forked from OSchip/llvm-project
[DAGCombine][ARM][X86] (sub Carry, X) -> (addcarry (sub 0, X), 0, Carry) fold
Summary: `DAGCombiner::visitADDLikeCommutative()` already has a sibling fold: `(add X, Carry) -> (addcarry X, 0, Carry)` This fold, as suggested by @efriedma, helps recover from //some// of the regressions of D62266 Reviewers: efriedma, deadalnix Subscribers: javed.absar, kristof.beyls, llvm-commits, efriedma Tags: #llvm Differential Revision: https://reviews.llvm.org/D62392 llvm-svn: 372259
This commit is contained in:
parent
a042aa1d82
commit
c00f318224
|
@ -3384,6 +3384,18 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TLI.isOperationLegalOrCustom(ISD::ADDCARRY, VT)) {
|
||||||
|
// (sub Carry, X) -> (addcarry (sub 0, X), 0, Carry)
|
||||||
|
if (SDValue Carry = getAsCarry(TLI, N0)) {
|
||||||
|
SDValue X = N1;
|
||||||
|
SDValue Zero = DAG.getConstant(0, DL, VT);
|
||||||
|
SDValue NegX = DAG.getNode(ISD::SUB, DL, VT, Zero, X);
|
||||||
|
return DAG.getNode(ISD::ADDCARRY, DL,
|
||||||
|
DAG.getVTList(VT, Carry.getValueType()), NegX, Zero,
|
||||||
|
Carry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 {
|
define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 {
|
||||||
; ARM-LABEL: fn1:
|
; ARM-LABEL: fn1:
|
||||||
; ARM: @ %bb.0: @ %entry
|
; ARM: @ %bb.0: @ %entry
|
||||||
|
; ARM-NEXT: rsb r2, r2, #0
|
||||||
; ARM-NEXT: adds r0, r1, r0
|
; ARM-NEXT: adds r0, r1, r0
|
||||||
; ARM-NEXT: mov r3, #0
|
|
||||||
; ARM-NEXT: adc r0, r3, #0
|
|
||||||
; ARM-NEXT: movw r1, #65535
|
; ARM-NEXT: movw r1, #65535
|
||||||
; ARM-NEXT: sub r0, r0, r2
|
; ARM-NEXT: sxth r2, r2
|
||||||
|
; ARM-NEXT: adc r0, r2, #0
|
||||||
; ARM-NEXT: uxth r0, r0
|
; ARM-NEXT: uxth r0, r0
|
||||||
; ARM-NEXT: cmp r0, r1
|
; ARM-NEXT: cmp r0, r1
|
||||||
; ARM-NEXT: bxeq lr
|
; ARM-NEXT: bxeq lr
|
||||||
|
@ -24,11 +24,12 @@ define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 {
|
||||||
;
|
;
|
||||||
; THUMBV6M-LABEL: fn1:
|
; THUMBV6M-LABEL: fn1:
|
||||||
; THUMBV6M: @ %bb.0: @ %entry
|
; THUMBV6M: @ %bb.0: @ %entry
|
||||||
|
; THUMBV6M-NEXT: rsbs r2, r2, #0
|
||||||
|
; THUMBV6M-NEXT: sxth r2, r2
|
||||||
; THUMBV6M-NEXT: movs r3, #0
|
; THUMBV6M-NEXT: movs r3, #0
|
||||||
; THUMBV6M-NEXT: adds r0, r1, r0
|
; THUMBV6M-NEXT: adds r0, r1, r0
|
||||||
; THUMBV6M-NEXT: adcs r3, r3
|
; THUMBV6M-NEXT: adcs r3, r2
|
||||||
; THUMBV6M-NEXT: subs r0, r3, r2
|
; THUMBV6M-NEXT: uxth r0, r3
|
||||||
; THUMBV6M-NEXT: uxth r0, r0
|
|
||||||
; THUMBV6M-NEXT: ldr r1, .LCPI0_0
|
; THUMBV6M-NEXT: ldr r1, .LCPI0_0
|
||||||
; THUMBV6M-NEXT: cmp r0, r1
|
; THUMBV6M-NEXT: cmp r0, r1
|
||||||
; THUMBV6M-NEXT: beq .LBB0_2
|
; THUMBV6M-NEXT: beq .LBB0_2
|
||||||
|
@ -44,11 +45,12 @@ define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 {
|
||||||
;
|
;
|
||||||
; THUMBV8M-BASE-LABEL: fn1:
|
; THUMBV8M-BASE-LABEL: fn1:
|
||||||
; THUMBV8M-BASE: @ %bb.0: @ %entry
|
; THUMBV8M-BASE: @ %bb.0: @ %entry
|
||||||
|
; THUMBV8M-BASE-NEXT: rsbs r2, r2, #0
|
||||||
|
; THUMBV8M-BASE-NEXT: sxth r2, r2
|
||||||
; THUMBV8M-BASE-NEXT: movs r3, #0
|
; THUMBV8M-BASE-NEXT: movs r3, #0
|
||||||
; THUMBV8M-BASE-NEXT: adds r0, r1, r0
|
; THUMBV8M-BASE-NEXT: adds r0, r1, r0
|
||||||
; THUMBV8M-BASE-NEXT: adcs r3, r3
|
; THUMBV8M-BASE-NEXT: adcs r3, r2
|
||||||
; THUMBV8M-BASE-NEXT: subs r0, r3, r2
|
; THUMBV8M-BASE-NEXT: uxth r0, r3
|
||||||
; THUMBV8M-BASE-NEXT: uxth r0, r0
|
|
||||||
; THUMBV8M-BASE-NEXT: movw r1, #65535
|
; THUMBV8M-BASE-NEXT: movw r1, #65535
|
||||||
; THUMBV8M-BASE-NEXT: cmp r0, r1
|
; THUMBV8M-BASE-NEXT: cmp r0, r1
|
||||||
; THUMBV8M-BASE-NEXT: beq .LBB0_2
|
; THUMBV8M-BASE-NEXT: beq .LBB0_2
|
||||||
|
@ -60,11 +62,11 @@ define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 {
|
||||||
;
|
;
|
||||||
; THUMB-LABEL: fn1:
|
; THUMB-LABEL: fn1:
|
||||||
; THUMB: @ %bb.0: @ %entry
|
; THUMB: @ %bb.0: @ %entry
|
||||||
|
; THUMB-NEXT: rsbs r2, r2, #0
|
||||||
; THUMB-NEXT: adds r0, r0, r1
|
; THUMB-NEXT: adds r0, r0, r1
|
||||||
; THUMB-NEXT: mov.w r3, #0
|
|
||||||
; THUMB-NEXT: adc r0, r3, #0
|
|
||||||
; THUMB-NEXT: movw r1, #65535
|
; THUMB-NEXT: movw r1, #65535
|
||||||
; THUMB-NEXT: subs r0, r0, r2
|
; THUMB-NEXT: sxth r2, r2
|
||||||
|
; THUMB-NEXT: adc r0, r2, #0
|
||||||
; THUMB-NEXT: uxth r0, r0
|
; THUMB-NEXT: uxth r0, r0
|
||||||
; THUMB-NEXT: cmp r0, r1
|
; THUMB-NEXT: cmp r0, r1
|
||||||
; THUMB-NEXT: it eq
|
; THUMB-NEXT: it eq
|
||||||
|
|
|
@ -169,11 +169,11 @@ declare {i64, i1} @llvm.usub.with.overflow(i64, i64)
|
||||||
define i64 @sub_from_carry(i64 %x, i64 %y, i64* %valout, i64 %z) {
|
define i64 @sub_from_carry(i64 %x, i64 %y, i64* %valout, i64 %z) {
|
||||||
; CHECK-LABEL: sub_from_carry:
|
; CHECK-LABEL: sub_from_carry:
|
||||||
; CHECK: # %bb.0:
|
; CHECK: # %bb.0:
|
||||||
; CHECK-NEXT: xorl %eax, %eax
|
; CHECK-NEXT: movq %rcx, %rax
|
||||||
|
; CHECK-NEXT: negq %rax
|
||||||
; CHECK-NEXT: addq %rsi, %rdi
|
; CHECK-NEXT: addq %rsi, %rdi
|
||||||
; CHECK-NEXT: setb %al
|
|
||||||
; CHECK-NEXT: movq %rdi, (%rdx)
|
; CHECK-NEXT: movq %rdi, (%rdx)
|
||||||
; CHECK-NEXT: subq %rcx, %rax
|
; CHECK-NEXT: adcq $0, %rax
|
||||||
; CHECK-NEXT: retq
|
; CHECK-NEXT: retq
|
||||||
%agg = call {i64, i1} @llvm.uadd.with.overflow(i64 %x, i64 %y)
|
%agg = call {i64, i1} @llvm.uadd.with.overflow(i64 %x, i64 %y)
|
||||||
%val = extractvalue {i64, i1} %agg, 0
|
%val = extractvalue {i64, i1} %agg, 0
|
||||||
|
|
Loading…
Reference in New Issue