llvm.org GIT mirror llvm / bd1ee11
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366214 91177308-0d34-0410-b5e6-96231b3b80d8 Amaury Sechet 3 months ago
3 changed file(s) with 41 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
27052705 return DAG.getNode(ISD::XOR, DL, VT, V, Cst);
27062706 }
27072707
2708 static SDValue extractBooleanFlip(SDValue V, const TargetLowering &TLI) {
2708 /**
2709 * Flips a boolean if it is cheaper to compute. If the Force parameters is set,
2710 * then the flip also occurs if computing the inverse is the same cost.
2711 * This function returns an empty SDValue in case it cannot flip the boolean
2712 * without increasing the cost of the computation. If you want to flip a boolean
2713 * no matter what, use flipBoolean.
2714 */
2715 static SDValue extractBooleanFlip(SDValue V, SelectionDAG &DAG,
2716 const TargetLowering &TLI,
2717 bool Force) {
2718 if (Force && isa(V))
2719 return flipBoolean(V, SDLoc(V), DAG, TLI);
2720
27092721 if (V.getOpcode() != ISD::XOR)
27102722 return SDValue();
27112723
27302742
27312743 if (IsFlip)
27322744 return V.getOperand(0);
2745 if (Force)
2746 return flipBoolean(V, SDLoc(V), DAG, TLI);
27332747 return SDValue();
27342748 }
27352749
28422856 return DAG.getNode(ISD::UADDO, DL, N->getVTList(), N0, N1);
28432857 }
28442858
2845 EVT CarryVT = CarryIn.getValueType();
2846
28472859 // fold (addcarry 0, 0, X) -> (and (ext/trunc X), 1) and no carry.
28482860 if (isNullConstant(N0) && isNullConstant(N1)) {
28492861 EVT VT = N0.getValueType();
2862 EVT CarryVT = CarryIn.getValueType();
28502863 SDValue CarryExt = DAG.getBoolExtOrTrunc(CarryIn, DL, VT, CarryVT);
28512864 AddToWorklist(CarryExt.getNode());
28522865 return CombineTo(N, DAG.getNode(ISD::AND, DL, VT, CarryExt,
28532866 DAG.getConstant(1, DL, VT)),
28542867 DAG.getConstant(0, DL, CarryVT));
2855 }
2856
2857 // fold (addcarry (xor a, -1), 0, !b) -> (subcarry 0, a, b) and flip carry.
2858 if (isBitwiseNot(N0) && isNullConstant(N1)) {
2859 if (SDValue B = extractBooleanFlip(CarryIn, TLI)) {
2860 SDValue Sub = DAG.getNode(ISD::SUBCARRY, DL, N->getVTList(),
2861 DAG.getConstant(0, DL, N0.getValueType()),
2862 N0.getOperand(0), B);
2863 return CombineTo(N, Sub,
2864 flipBoolean(Sub.getValue(1), DL, DAG, TLI));
2865 }
28662868 }
28672869
28682870 if (SDValue Combined = visitADDCARRYLike(N0, N1, CarryIn, N))
29632965
29642966 SDValue DAGCombiner::visitADDCARRYLike(SDValue N0, SDValue N1, SDValue CarryIn,
29652967 SDNode *N) {
2968 // fold (addcarry (xor a, -1), b, c) -> (subcarry b, a, !c) and flip carry.
2969 if (isBitwiseNot(N0))
2970 if (SDValue NotC = extractBooleanFlip(CarryIn, DAG, TLI, true)) {
2971 SDLoc DL(N);
2972 SDValue Sub = DAG.getNode(ISD::SUBCARRY, DL, N->getVTList(), N1,
2973 N0.getOperand(0), NotC);
2974 return CombineTo(N, Sub,
2975 flipBoolean(Sub.getValue(1), DL, DAG, TLI));
2976 }
2977
29662978 // Iff the flag result is dead:
29672979 // (addcarry (add|uaddo X, Y), 0, Carry) -> (addcarry X, Y, Carry)
29682980 // Don't do this if the Carry comes from the uaddo. It won't remove the uaddo
83018313 }
83028314
83038315 // select (not Cond), N1, N2 -> select Cond, N2, N1
8304 if (SDValue F = extractBooleanFlip(N0, TLI)) {
8316 if (SDValue F = extractBooleanFlip(N0, DAG, TLI, false)) {
83058317 SDValue SelectOp = DAG.getSelect(DL, VT, F, N2, N1);
83068318 SelectOp->setFlags(Flags);
83078319 return SelectOp;
87968808 return V;
87978809
87988810 // vselect (not Cond), N1, N2 -> vselect Cond, N2, N1
8799 if (SDValue F = extractBooleanFlip(N0, TLI))
8811 if (SDValue F = extractBooleanFlip(N0, DAG, TLI, false))
88008812 return DAG.getSelect(DL, VT, F, N2, N1);
88018813
88028814 // Canonicalize integer abs.
390390 ; CHECK-LABEL: addcarry_to_subcarry:
391391 ; CHECK: # %bb.0:
392392 ; CHECK-NEXT: movq %rdi, %rax
393 ; CHECK-NEXT: cmpq %rsi, %rdi
393394 ; CHECK-NEXT: notq %rsi
394 ; CHECK-NEXT: movb $1, %cl
395 ; CHECK-NEXT: setae %cl
395396 ; CHECK-NEXT: addb $-1, %cl
396 ; CHECK-NEXT: movq %rdi, %rcx
397 ; CHECK-NEXT: adcq %rsi, %rcx
398397 ; CHECK-NEXT: adcq $0, %rax
399398 ; CHECK-NEXT: setb %cl
400399 ; CHECK-NEXT: movzbl %cl, %edx
8989 define %S @sub(%S* nocapture readonly %this, %S %arg.b) local_unnamed_addr {
9090 ; CHECK-LABEL: sub:
9191 ; CHECK: # %bb.0: # %entry
92 ; CHECK-NEXT: pushq %rbx
93 ; CHECK-NEXT: .cfi_def_cfa_offset 16
94 ; CHECK-NEXT: .cfi_offset %rbx, -16
9592 ; CHECK-NEXT: movq %rdi, %rax
9693 ; CHECK-NEXT: movq (%rsi), %r10
9794 ; CHECK-NEXT: movq 8(%rsi), %rdi
98 ; CHECK-NEXT: movq %r10, %r11
99 ; CHECK-NEXT: subq %rdx, %r11
100 ; CHECK-NEXT: notq %rdx
101 ; CHECK-NEXT: movb $1, %bl
102 ; CHECK-NEXT: addb $-1, %bl
103 ; CHECK-NEXT: adcq %r10, %rdx
95 ; CHECK-NEXT: subq %rdx, %r10
96 ; CHECK-NEXT: setae %dl
97 ; CHECK-NEXT: addb $-1, %dl
10498 ; CHECK-NEXT: adcq $0, %rdi
10599 ; CHECK-NEXT: setb %dl
106 ; CHECK-NEXT: movzbl %dl, %edx
100 ; CHECK-NEXT: movzbl %dl, %r11d
107101 ; CHECK-NEXT: notq %rcx
108102 ; CHECK-NEXT: addq %rdi, %rcx
109 ; CHECK-NEXT: adcq 16(%rsi), %rdx
110 ; CHECK-NEXT: setb %bl
111 ; CHECK-NEXT: movzbl %bl, %edi
103 ; CHECK-NEXT: adcq 16(%rsi), %r11
104 ; CHECK-NEXT: setb %dl
105 ; CHECK-NEXT: movzbl %dl, %edx
112106 ; CHECK-NEXT: notq %r8
113 ; CHECK-NEXT: addq %rdx, %r8
114 ; CHECK-NEXT: adcq 24(%rsi), %rdi
107 ; CHECK-NEXT: addq %r11, %r8
108 ; CHECK-NEXT: adcq 24(%rsi), %rdx
115109 ; CHECK-NEXT: notq %r9
116 ; CHECK-NEXT: addq %rdi, %r9
117 ; CHECK-NEXT: movq %r11, (%rax)
110 ; CHECK-NEXT: addq %rdx, %r9
111 ; CHECK-NEXT: movq %r10, (%rax)
118112 ; CHECK-NEXT: movq %rcx, 8(%rax)
119113 ; CHECK-NEXT: movq %r8, 16(%rax)
120114 ; CHECK-NEXT: movq %r9, 24(%rax)
121 ; CHECK-NEXT: popq %rbx
122 ; CHECK-NEXT: .cfi_def_cfa_offset 8
123115 ; CHECK-NEXT: retq
124116 entry:
125117 %0 = extractvalue %S %arg.b, 0