From: Sanjay Patel Date: Sat, 4 Mar 2017 00:18:31 +0000 (+0000) Subject: [x86] check for commuted add pattern to find ADC/SBB X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=deed01eb8d3cc9d31e4fd9f6a10fc43f482a1823;p=llvm [x86] check for commuted add pattern to find ADC/SBB git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296933 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 7db85172ec1..317edc419e7 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -34106,7 +34106,15 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG, static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) { // Look through ZExts. bool IsSub = N->getOpcode() == ISD::SUB; - SDValue Ext = N->getOperand(IsSub ? 1 : 0); + SDValue Y = N->getOperand(0); + SDValue Ext = N->getOperand(1); + + // If this is an add, canonicalize a zext to the RHS. + // TODO: Incomplete? What if both sides are zexts? + if (!IsSub && Ext.getOpcode() != ISD::ZERO_EXTEND && + Y.getOpcode() == ISD::ZERO_EXTEND) + std::swap(Ext, Y); + if (Ext.getOpcode() != ISD::ZERO_EXTEND || !Ext.hasOneUse()) return SDValue(); @@ -34130,17 +34138,16 @@ static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) { SDValue NewCmp = DAG.getNode(X86ISD::CMP, DL, MVT::i32, X, DAG.getConstant(1, DL, X.getValueType())); - SDValue Y = N->getOperand(IsSub ? 0 : 1); EVT VT = Y.getValueType(); // Y - (X != 0) --> sub Y, (zext(setne X, 0)) --> adc Y, -1, (cmp X, 1) - // (X != 0) + Y --> add (zext(setne X, 0)), Y --> sbb Y, -1, (cmp X, 1) + // Y + (X != 0) --> add Y, (zext(setne X, 0)) --> sbb Y, -1, (cmp X, 1) if (CC == X86::COND_NE) return DAG.getNode(IsSub ? X86ISD::ADC : X86ISD::SBB, DL, VT, Y, DAG.getConstant(-1ULL, DL, VT), NewCmp); // Y - (X == 0) --> sub Y, (zext(sete X, 0)) --> sbb Y, 0, (cmp X, 1) - // (X == 0) + Y --> add (zext(sete X, 0)), Y --> adc Y, 0, (cmp X, 1) + // Y + (X == 0) --> add Y, (zext(sete X, 0)) --> adc Y, 0, (cmp X, 1) return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL, VT, Y, DAG.getConstant(0, DL, VT), NewCmp); } diff --git a/test/CodeGen/X86/conditional-indecrement.ll b/test/CodeGen/X86/conditional-indecrement.ll index 1dc083290f2..f9e18f62697 100644 --- a/test/CodeGen/X86/conditional-indecrement.ll +++ b/test/CodeGen/X86/conditional-indecrement.ll @@ -17,10 +17,9 @@ define i32 @test1(i32 %a, i32 %b) nounwind readnone { define i32 @test1_commute(i32 %a, i32 %b) nounwind readnone { ; CHECK-LABEL: test1_commute: ; CHECK: # BB#0: -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: setne %al -; CHECK-NEXT: addl %esi, %eax +; CHECK-NEXT: cmpl $1, %edi +; CHECK-NEXT: sbbl $-1, %esi +; CHECK-NEXT: movl %esi, %eax ; CHECK-NEXT: retq %cmp = icmp ne i32 %a, 0 %inc = zext i1 %cmp to i32