[llvm] r333943 - [DAGcombine] Teach the combiner about -a = ~a + 1
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 4 14:26:02 PDT 2018
The switch in flipBoolean throws this warning
warning: default label in switch which covers all enumeration values
[-Wcovered-switch-default]
~Craig
On Mon, Jun 4, 2018 at 12:27 PM Amaury Sechet via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: deadalnix
> Date: Mon Jun 4 12:23:22 2018
> New Revision: 333943
>
> URL: http://llvm.org/viewvc/llvm-project?rev=333943&view=rev
> Log:
> [DAGcombine] Teach the combiner about -a = ~a + 1
>
> Summary: This include variant for add, uaddo and addcarry. usubo and
> subcarry require the carry to be flipped to preserve semantic, but we chose
> to do the transform anyway in that case as to push the transform down the
> carry chain.
>
> Reviewers: efriedma, spatel, RKSimon, zvi, bkramer
>
> Subscribers: llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D46505
>
> Modified:
> llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> llvm/trunk/test/CodeGen/X86/add.ll
> 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=333943&r1=333942&r2=333943&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Jun 4
> 12:23:22 2018
> @@ -2053,6 +2053,11 @@ SDValue DAGCombiner::visitADD(SDNode *N)
> DAG.haveNoCommonBitsSet(N0, N1))
> return DAG.getNode(ISD::OR, DL, VT, N0, N1);
>
> + // fold (add (xor a, -1), 1) -> (sub 0, a)
> + if (isBitwiseNot(N0) && isOneConstantOrOneSplatConstant(N1))
> + return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT),
> + N0.getOperand(0));
> +
> if (SDValue Combined = visitADDLike(N0, N1, N))
> return Combined;
>
> @@ -2188,6 +2193,40 @@ SDValue DAGCombiner::visitADDC(SDNode *N
> return SDValue();
> }
>
> +static SDValue flipBoolean(SDValue V, const SDLoc &DL, EVT VT,
> + SelectionDAG &DAG, const TargetLowering &TLI) {
> + SDValue Cst;
> + switch(TLI.getBooleanContents(VT)) {
> + case TargetLowering::ZeroOrOneBooleanContent:
> + case TargetLowering::UndefinedBooleanContent:
> + Cst = DAG.getConstant(1, DL, VT);
> + break;
> + case TargetLowering::ZeroOrNegativeOneBooleanContent:
> + Cst = DAG.getConstant(-1, DL, VT);
> + break;
> + default:
> + llvm_unreachable("Unsupported boolean content");
> + }
> +
> + return DAG.getNode(ISD::XOR, DL, VT, V, Cst);
> +}
> +
> +static bool isBooleanFlip(SDValue V, EVT VT, const TargetLowering &TLI) {
> + if (V.getOpcode() != ISD::XOR) return false;
> + ConstantSDNode *Const = dyn_cast<ConstantSDNode>(V.getOperand(1));
> + if (!Const) return false;
> +
> + switch(TLI.getBooleanContents(VT)) {
> + case TargetLowering::ZeroOrOneBooleanContent:
> + return Const->isOne();
> + case TargetLowering::ZeroOrNegativeOneBooleanContent:
> + return Const->isAllOnesValue();
> + case TargetLowering::UndefinedBooleanContent:
> + return (Const->getAPIntValue() & 0x01) == 1;
> + }
> + llvm_unreachable("Unsupported boolean content");
> +}
> +
> SDValue DAGCombiner::visitUADDO(SDNode *N) {
> SDValue N0 = N->getOperand(0);
> SDValue N1 = N->getOperand(1);
> @@ -2218,6 +2257,15 @@ SDValue DAGCombiner::visitUADDO(SDNode *
> return CombineTo(N, DAG.getNode(ISD::ADD, DL, VT, N0, N1),
> DAG.getConstant(0, DL, CarryVT));
>
> + // fold (uaddo (xor a, -1), 1) -> (usub 0, a) and flip carry.
> + if (isBitwiseNot(N0) && isOneConstantOrOneSplatConstant(N1)) {
> + SDValue Sub = DAG.getNode(ISD::USUBO, DL, N->getVTList(),
> + DAG.getConstant(0, DL, VT),
> + N0.getOperand(0));
> + return CombineTo(N, Sub,
> + flipBoolean(Sub.getValue(1), DL, CarryVT, DAG, TLI));
> + }
> +
> if (SDValue Combined = visitUADDOLike(N0, N1, N))
> return Combined;
>
> @@ -2287,10 +2335,11 @@ 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,
> @@ -2298,6 +2347,16 @@ 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) &&
> + isBooleanFlip(CarryIn, CarryVT, TLI)) {
> + SDValue Sub = DAG.getNode(ISD::SUBCARRY, DL, N->getVTList(),
> + DAG.getConstant(0, DL, N0.getValueType()),
> + N0.getOperand(0), CarryIn.getOperand(0));
> + return CombineTo(N, Sub,
> + flipBoolean(Sub.getValue(1), DL, CarryVT, DAG, TLI));
> + }
> +
> if (SDValue Combined = visitADDCARRYLike(N0, N1, CarryIn, N))
> return Combined;
>
>
> Modified: llvm/trunk/test/CodeGen/X86/add.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/add.ll?rev=333943&r1=333942&r2=333943&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/add.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/add.ll Mon Jun 4 12:23:22 2018
> @@ -386,23 +386,20 @@ entry:
> define i32 @inc_not(i32 %a) {
> ; X32-LABEL: inc_not:
> ; X32: # %bb.0:
> -; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
> -; X32-NEXT: notl %eax
> -; X32-NEXT: incl %eax
> +; X32-NEXT: xorl %eax, %eax
> +; X32-NEXT: subl {{[0-9]+}}(%esp), %eax
> ; X32-NEXT: retl
> ;
> ; X64-LINUX-LABEL: inc_not:
> ; X64-LINUX: # %bb.0:
> -; X64-LINUX-NEXT: # kill: def $edi killed $edi def $rdi
> -; X64-LINUX-NEXT: notl %edi
> -; X64-LINUX-NEXT: leal 1(%rdi), %eax
> +; X64-LINUX-NEXT: negl %edi
> +; X64-LINUX-NEXT: movl %edi, %eax
> ; X64-LINUX-NEXT: retq
> ;
> ; X64-WIN32-LABEL: inc_not:
> ; X64-WIN32: # %bb.0:
> -; X64-WIN32-NEXT: # kill: def $ecx killed $ecx def $rcx
> -; X64-WIN32-NEXT: notl %ecx
> -; X64-WIN32-NEXT: leal 1(%rcx), %eax
> +; X64-WIN32-NEXT: negl %ecx
> +; X64-WIN32-NEXT: movl %ecx, %eax
> ; X64-WIN32-NEXT: retq
> %nota = xor i32 %a, -1
> %r = add i32 %nota, 1
> @@ -414,27 +411,24 @@ define void @uaddo1_not(i32 %a, i32* %p0
> ; X32: # %bb.0:
> ; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
> ; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
> -; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
> -; X32-NEXT: notl %edx
> -; X32-NEXT: addl $1, %edx
> +; X32-NEXT: xorl %edx, %edx
> +; X32-NEXT: subl {{[0-9]+}}(%esp), %edx
> ; X32-NEXT: movl %edx, (%ecx)
> -; X32-NEXT: setb (%eax)
> +; X32-NEXT: setae (%eax)
> ; X32-NEXT: retl
> ;
> ; X64-LINUX-LABEL: uaddo1_not:
> ; X64-LINUX: # %bb.0:
> -; X64-LINUX-NEXT: notl %edi
> -; X64-LINUX-NEXT: addl $1, %edi
> +; X64-LINUX-NEXT: negl %edi
> ; X64-LINUX-NEXT: movl %edi, (%rsi)
> -; X64-LINUX-NEXT: setb (%rdx)
> +; X64-LINUX-NEXT: setae (%rdx)
> ; X64-LINUX-NEXT: retq
> ;
> ; X64-WIN32-LABEL: uaddo1_not:
> ; X64-WIN32: # %bb.0:
> -; X64-WIN32-NEXT: notl %ecx
> -; X64-WIN32-NEXT: addl $1, %ecx
> +; X64-WIN32-NEXT: negl %ecx
> ; X64-WIN32-NEXT: movl %ecx, (%rdx)
> -; X64-WIN32-NEXT: setb (%r8)
> +; X64-WIN32-NEXT: setae (%r8)
> ; X64-WIN32-NEXT: retq
> %nota = xor i32 %a, -1
> %uaddo = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %nota, i32 1)
>
> Modified: llvm/trunk/test/CodeGen/X86/addcarry.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/addcarry.ll?rev=333943&r1=333942&r2=333943&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/addcarry.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/addcarry.ll Mon Jun 4 12:23:22 2018
> @@ -321,12 +321,10 @@ entry:
> define i128 @addcarry1_not(i128 %n) {
> ; CHECK-LABEL: addcarry1_not:
> ; CHECK: # %bb.0:
> -; CHECK-NEXT: notq %rsi
> -; CHECK-NEXT: notq %rdi
> -; CHECK-NEXT: addq $1, %rdi
> -; CHECK-NEXT: adcq $0, %rsi
> +; CHECK-NEXT: xorl %edx, %edx
> +; CHECK-NEXT: negq %rdi
> +; CHECK-NEXT: sbbq %rsi, %rdx
> ; CHECK-NEXT: movq %rdi, %rax
> -; CHECK-NEXT: movq %rsi, %rdx
> ; CHECK-NEXT: retq
> %1 = xor i128 %n, -1
> %2 = add i128 %1, 1
>
> Modified: llvm/trunk/test/CodeGen/X86/subcarry.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/subcarry.ll?rev=333943&r1=333942&r2=333943&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/subcarry.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/subcarry.ll Mon Jun 4 12:23:22 2018
> @@ -37,22 +37,18 @@ entry:
> define %S @negate(%S* nocapture readonly %this) {
> ; CHECK-LABEL: negate:
> ; CHECK: # %bb.0: # %entry
> -; CHECK-NEXT: movq (%rsi), %rax
> -; CHECK-NEXT: movq 8(%rsi), %rcx
> -; CHECK-NEXT: notq %rax
> -; CHECK-NEXT: addq $1, %rax
> -; CHECK-NEXT: notq %rcx
> -; CHECK-NEXT: adcq $0, %rcx
> -; CHECK-NEXT: movq 16(%rsi), %rdx
> -; CHECK-NEXT: notq %rdx
> -; CHECK-NEXT: adcq $0, %rdx
> -; CHECK-NEXT: movq 24(%rsi), %rsi
> -; CHECK-NEXT: notq %rsi
> -; CHECK-NEXT: adcq $0, %rsi
> -; CHECK-NEXT: movq %rax, (%rdi)
> -; CHECK-NEXT: movq %rcx, 8(%rdi)
> -; CHECK-NEXT: movq %rdx, 16(%rdi)
> -; CHECK-NEXT: movq %rsi, 24(%rdi)
> +; CHECK-NEXT: xorl %r8d, %r8d
> +; CHECK-NEXT: xorl %ecx, %ecx
> +; CHECK-NEXT: subq (%rsi), %rcx
> +; CHECK-NEXT: movl $0, %edx
> +; CHECK-NEXT: sbbq 8(%rsi), %rdx
> +; CHECK-NEXT: movl $0, %eax
> +; CHECK-NEXT: sbbq 16(%rsi), %rax
> +; CHECK-NEXT: sbbq 24(%rsi), %r8
> +; CHECK-NEXT: movq %rcx, (%rdi)
> +; CHECK-NEXT: movq %rdx, 8(%rdi)
> +; CHECK-NEXT: movq %rax, 16(%rdi)
> +; CHECK-NEXT: movq %r8, 24(%rdi)
> ; CHECK-NEXT: movq %rdi, %rax
> ; CHECK-NEXT: retq
> entry:
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180604/ab097026/attachment.html>
More information about the llvm-commits
mailing list