[llvm] r366214 - [DAGCombiner] fold (addcarry (xor a, -1), b, c) -> (subcarry b, a, !c) and flip carry.
Amaury Sechet via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 16 08:17:01 PDT 2019
Author: deadalnix
Date: Tue Jul 16 08:17:00 2019
New Revision: 366214
URL: http://llvm.org/viewvc/llvm-project?rev=366214&view=rev
Log:
[DAGCombiner] fold (addcarry (xor a, -1), b, c) -> (subcarry b, a, !c) and flip carry.
Summary:
As per title. DAGCombiner only mathes the special case where b = 0, this patches extends the pattern to match any value of b.
Depends on D57302
Reviewers: hfinkel, RKSimon, craig.topper
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59208
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/trunk/test/CodeGen/X86/addcarry.ll
llvm/trunk/test/CodeGen/X86/subcarry.ll
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=366214&r1=366213&r2=366214&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Tue Jul 16 08:17:00 2019
@@ -2706,7 +2706,19 @@ static SDValue flipBoolean(SDValue V, co
return DAG.getNode(ISD::XOR, DL, VT, V, Cst);
}
-static SDValue extractBooleanFlip(SDValue V, const TargetLowering &TLI) {
+/**
+ * Flips a boolean if it is cheaper to compute. If the Force parameters is set,
+ * then the flip also occurs if computing the inverse is the same cost.
+ * This function returns an empty SDValue in case it cannot flip the boolean
+ * without increasing the cost of the computation. If you want to flip a boolean
+ * no matter what, use flipBoolean.
+ */
+static SDValue extractBooleanFlip(SDValue V, SelectionDAG &DAG,
+ const TargetLowering &TLI,
+ bool Force) {
+ if (Force && isa<ConstantSDNode>(V))
+ return flipBoolean(V, SDLoc(V), DAG, TLI);
+
if (V.getOpcode() != ISD::XOR)
return SDValue();
@@ -2731,6 +2743,8 @@ static SDValue extractBooleanFlip(SDValu
if (IsFlip)
return V.getOperand(0);
+ if (Force)
+ return flipBoolean(V, SDLoc(V), DAG, TLI);
return SDValue();
}
@@ -2843,11 +2857,10 @@ SDValue DAGCombiner::visitADDCARRY(SDNod
return DAG.getNode(ISD::UADDO, DL, N->getVTList(), N0, N1);
}
- EVT CarryVT = CarryIn.getValueType();
-
// fold (addcarry 0, 0, X) -> (and (ext/trunc X), 1) and no carry.
if (isNullConstant(N0) && isNullConstant(N1)) {
EVT VT = N0.getValueType();
+ EVT CarryVT = CarryIn.getValueType();
SDValue CarryExt = DAG.getBoolExtOrTrunc(CarryIn, DL, VT, CarryVT);
AddToWorklist(CarryExt.getNode());
return CombineTo(N, DAG.getNode(ISD::AND, DL, VT, CarryExt,
@@ -2855,17 +2868,6 @@ SDValue DAGCombiner::visitADDCARRY(SDNod
DAG.getConstant(0, DL, CarryVT));
}
- // fold (addcarry (xor a, -1), 0, !b) -> (subcarry 0, a, b) and flip carry.
- if (isBitwiseNot(N0) && isNullConstant(N1)) {
- if (SDValue B = extractBooleanFlip(CarryIn, TLI)) {
- SDValue Sub = DAG.getNode(ISD::SUBCARRY, DL, N->getVTList(),
- DAG.getConstant(0, DL, N0.getValueType()),
- N0.getOperand(0), B);
- return CombineTo(N, Sub,
- flipBoolean(Sub.getValue(1), DL, DAG, TLI));
- }
- }
-
if (SDValue Combined = visitADDCARRYLike(N0, N1, CarryIn, N))
return Combined;
@@ -2964,6 +2966,16 @@ static SDValue combineADDCARRYDiamond(DA
SDValue DAGCombiner::visitADDCARRYLike(SDValue N0, SDValue N1, SDValue CarryIn,
SDNode *N) {
+ // fold (addcarry (xor a, -1), b, c) -> (subcarry b, a, !c) and flip carry.
+ if (isBitwiseNot(N0))
+ if (SDValue NotC = extractBooleanFlip(CarryIn, DAG, TLI, true)) {
+ SDLoc DL(N);
+ SDValue Sub = DAG.getNode(ISD::SUBCARRY, DL, N->getVTList(), N1,
+ N0.getOperand(0), NotC);
+ return CombineTo(N, Sub,
+ flipBoolean(Sub.getValue(1), DL, DAG, TLI));
+ }
+
// Iff the flag result is dead:
// (addcarry (add|uaddo X, Y), 0, Carry) -> (addcarry X, Y, Carry)
// Don't do this if the Carry comes from the uaddo. It won't remove the uaddo
@@ -8302,7 +8314,7 @@ SDValue DAGCombiner::visitSELECT(SDNode
}
// select (not Cond), N1, N2 -> select Cond, N2, N1
- if (SDValue F = extractBooleanFlip(N0, TLI)) {
+ if (SDValue F = extractBooleanFlip(N0, DAG, TLI, false)) {
SDValue SelectOp = DAG.getSelect(DL, VT, F, N2, N1);
SelectOp->setFlags(Flags);
return SelectOp;
@@ -8797,7 +8809,7 @@ SDValue DAGCombiner::visitVSELECT(SDNode
return V;
// vselect (not Cond), N1, N2 -> vselect Cond, N2, N1
- if (SDValue F = extractBooleanFlip(N0, TLI))
+ if (SDValue F = extractBooleanFlip(N0, DAG, TLI, false))
return DAG.getSelect(DL, VT, F, N2, N1);
// Canonicalize integer abs.
Modified: llvm/trunk/test/CodeGen/X86/addcarry.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/addcarry.ll?rev=366214&r1=366213&r2=366214&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/addcarry.ll (original)
+++ llvm/trunk/test/CodeGen/X86/addcarry.ll Tue Jul 16 08:17:00 2019
@@ -391,11 +391,10 @@ define i128 @addcarry_to_subcarry(i64 %a
; CHECK-LABEL: addcarry_to_subcarry:
; CHECK: # %bb.0:
; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: cmpq %rsi, %rdi
; CHECK-NEXT: notq %rsi
-; CHECK-NEXT: movb $1, %cl
+; CHECK-NEXT: setae %cl
; CHECK-NEXT: addb $-1, %cl
-; CHECK-NEXT: movq %rdi, %rcx
-; CHECK-NEXT: adcq %rsi, %rcx
; CHECK-NEXT: adcq $0, %rax
; CHECK-NEXT: setb %cl
; CHECK-NEXT: movzbl %cl, %edx
Modified: llvm/trunk/test/CodeGen/X86/subcarry.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/subcarry.ll?rev=366214&r1=366213&r2=366214&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/subcarry.ll (original)
+++ llvm/trunk/test/CodeGen/X86/subcarry.ll Tue Jul 16 08:17:00 2019
@@ -90,37 +90,29 @@ entry:
define %S @sub(%S* nocapture readonly %this, %S %arg.b) local_unnamed_addr {
; CHECK-LABEL: sub:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: pushq %rbx
-; CHECK-NEXT: .cfi_def_cfa_offset 16
-; CHECK-NEXT: .cfi_offset %rbx, -16
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: movq (%rsi), %r10
; CHECK-NEXT: movq 8(%rsi), %rdi
-; CHECK-NEXT: movq %r10, %r11
-; CHECK-NEXT: subq %rdx, %r11
-; CHECK-NEXT: notq %rdx
-; CHECK-NEXT: movb $1, %bl
-; CHECK-NEXT: addb $-1, %bl
-; CHECK-NEXT: adcq %r10, %rdx
+; CHECK-NEXT: subq %rdx, %r10
+; CHECK-NEXT: setae %dl
+; CHECK-NEXT: addb $-1, %dl
; CHECK-NEXT: adcq $0, %rdi
; CHECK-NEXT: setb %dl
-; CHECK-NEXT: movzbl %dl, %edx
+; CHECK-NEXT: movzbl %dl, %r11d
; CHECK-NEXT: notq %rcx
; CHECK-NEXT: addq %rdi, %rcx
-; CHECK-NEXT: adcq 16(%rsi), %rdx
-; CHECK-NEXT: setb %bl
-; CHECK-NEXT: movzbl %bl, %edi
+; CHECK-NEXT: adcq 16(%rsi), %r11
+; CHECK-NEXT: setb %dl
+; CHECK-NEXT: movzbl %dl, %edx
; CHECK-NEXT: notq %r8
-; CHECK-NEXT: addq %rdx, %r8
-; CHECK-NEXT: adcq 24(%rsi), %rdi
+; CHECK-NEXT: addq %r11, %r8
+; CHECK-NEXT: adcq 24(%rsi), %rdx
; CHECK-NEXT: notq %r9
-; CHECK-NEXT: addq %rdi, %r9
-; CHECK-NEXT: movq %r11, (%rax)
+; CHECK-NEXT: addq %rdx, %r9
+; CHECK-NEXT: movq %r10, (%rax)
; CHECK-NEXT: movq %rcx, 8(%rax)
; CHECK-NEXT: movq %r8, 16(%rax)
; CHECK-NEXT: movq %r9, 24(%rax)
-; CHECK-NEXT: popq %rbx
-; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
entry:
%0 = extractvalue %S %arg.b, 0
More information about the llvm-commits
mailing list