summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-03-04 00:18:31 +0000
committerSanjay Patel <spatel@rotateright.com>2017-03-04 00:18:31 +0000
commita84fd041c6378178ce837012c53fb182ec7a5c4b (patch)
treee54d62049b19ec69020dbac1ff7708ddb723c0db
parent583e2c175a241dc39dfc28acda8a38514286950e (diff)
downloadbcm5719-llvm-a84fd041c6378178ce837012c53fb182ec7a5c4b.tar.gz
bcm5719-llvm-a84fd041c6378178ce837012c53fb182ec7a5c4b.zip
[x86] check for commuted add pattern to find ADC/SBB
llvm-svn: 296933
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp15
-rw-r--r--llvm/test/CodeGen/X86/conditional-indecrement.ll7
2 files changed, 14 insertions, 8 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 7db85172ec1..317edc419e7 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/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/llvm/test/CodeGen/X86/conditional-indecrement.ll b/llvm/test/CodeGen/X86/conditional-indecrement.ll
index 1dc083290f2..f9e18f62697 100644
--- a/llvm/test/CodeGen/X86/conditional-indecrement.ll
+++ b/llvm/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
OpenPOWER on IntegriCloud