summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-06-23 18:42:15 +0000
committerSanjay Patel <spatel@rotateright.com>2017-06-23 18:42:15 +0000
commit3de6bad65f5264fb161bc0d1c54109a003d04326 (patch)
tree51fa8cc57786a7895995a56ee92362d53e9b9854
parent19cee0d56c568a3f49b721dc3cd3d1674dc5698b (diff)
downloadbcm5719-llvm-3de6bad65f5264fb161bc0d1c54109a003d04326.tar.gz
bcm5719-llvm-3de6bad65f5264fb161bc0d1c54109a003d04326.zip
[x86] fix value types for SBB transform (PR33560)
I'm not sure yet why this wouldn't fail in the simple case, but clearly I used the wrong value type with: https://reviews.llvm.org/rL306040 ...and the bug manifests with: https://bugs.llvm.org/show_bug.cgi?id=33560 llvm-svn: 306139
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp21
-rw-r--r--llvm/test/CodeGen/X86/sbb.ll25
2 files changed, 38 insertions, 8 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index cf88673351e..0be5460fa34 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -34898,7 +34898,7 @@ static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) {
return SDValue();
SDValue Z = Cmp.getOperand(0);
- SDVTList VTs = DAG.getVTList(N->getValueType(0), MVT::i32);
+ EVT ZVT = Z.getValueType();
// If X is -1 or 0, then we have an opportunity to avoid constants required in
// the general case below.
@@ -34909,19 +34909,21 @@ static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) {
// -1 + (Z == 0) --> sbb %eax, %eax, (neg Z)
if ((IsSub && CC == X86::COND_NE && ConstantX->isNullValue()) ||
(!IsSub && CC == X86::COND_E && ConstantX->isAllOnesValue())) {
- SDValue Zero = DAG.getConstant(0, DL, VT);
- SDValue Neg = DAG.getNode(X86ISD::SUB, DL, VTs, Zero, Z);
+ SDValue Zero = DAG.getConstant(0, DL, ZVT);
+ SDVTList X86SubVTs = DAG.getVTList(ZVT, MVT::i32);
+ SDValue Neg = DAG.getNode(X86ISD::SUB, DL, X86SubVTs, Zero, Z);
return DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
DAG.getConstant(X86::COND_B, DL, MVT::i8),
SDValue(Neg.getNode(), 1));
}
+
// cmp with 1 sets the carry flag when Z == 0, so create 0 or -1 using 'sbb'
// with fake operands:
// 0 - (Z == 0) --> sbb %eax, %eax, (cmp Z, 1)
// -1 + (Z != 0) --> sbb %eax, %eax, (cmp Z, 1)
if ((IsSub && CC == X86::COND_E && ConstantX->isNullValue()) ||
(!IsSub && CC == X86::COND_NE && ConstantX->isAllOnesValue())) {
- SDValue One = DAG.getConstant(1, DL, Z.getValueType());
+ SDValue One = DAG.getConstant(1, DL, ZVT);
SDValue Cmp1 = DAG.getNode(X86ISD::CMP, DL, MVT::i32, Z, One);
return DAG.getNode(X86ISD::SETCC_CARRY, DL, VT,
DAG.getConstant(X86::COND_B, DL, MVT::i8), Cmp1);
@@ -34929,19 +34931,22 @@ static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) {
}
// (cmp Z, 1) sets the carry flag if Z is 0.
- SDValue NewCmp = DAG.getNode(X86ISD::CMP, DL, MVT::i32, Z,
- DAG.getConstant(1, DL, Z.getValueType()));
+ SDValue One = DAG.getConstant(1, DL, ZVT);
+ SDValue Cmp1 = DAG.getNode(X86ISD::CMP, DL, MVT::i32, Z, One);
+
+ // Add the flags type for ADC/SBB nodes.
+ SDVTList VTs = DAG.getVTList(VT, MVT::i32);
// X - (Z != 0) --> sub X, (zext(setne Z, 0)) --> adc X, -1, (cmp Z, 1)
// X + (Z != 0) --> add X, (zext(setne Z, 0)) --> sbb X, -1, (cmp Z, 1)
if (CC == X86::COND_NE)
return DAG.getNode(IsSub ? X86ISD::ADC : X86ISD::SBB, DL, VTs, X,
- DAG.getConstant(-1ULL, DL, VT), NewCmp);
+ DAG.getConstant(-1ULL, DL, VT), Cmp1);
// X - (Z == 0) --> sub X, (zext(sete Z, 0)) --> sbb X, 0, (cmp Z, 1)
// X + (Z == 0) --> add X, (zext(sete Z, 0)) --> adc X, 0, (cmp Z, 1)
return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL, VTs, X,
- DAG.getConstant(0, DL, VT), NewCmp);
+ DAG.getConstant(0, DL, VT), Cmp1);
}
static SDValue combineLoopMAddPattern(SDNode *N, SelectionDAG &DAG,
diff --git a/llvm/test/CodeGen/X86/sbb.ll b/llvm/test/CodeGen/X86/sbb.ll
index 409af00d3b2..bc00fc7c66a 100644
--- a/llvm/test/CodeGen/X86/sbb.ll
+++ b/llvm/test/CodeGen/X86/sbb.ll
@@ -111,3 +111,28 @@ define i8 @i8_select_neg1_or_0_commuted_as_math(i8 %x) {
ret i8 %add
}
+; Make sure we're creating nodes with the right value types. This would crash.
+; https://bugs.llvm.org/show_bug.cgi?id=33560
+
+define void @PR33560(i8 %x, i64 %y) {
+; CHECK-LABEL: PR33560:
+; CHECK: # BB#0: # %entry
+; CHECK-NEXT: negb %dil
+; CHECK-NEXT: sbbq %rax, %rax
+; CHECK-NEXT: cmpq %rsi, %rax
+; CHECK-NEXT: retq
+entry:
+ %cmp1 = icmp eq i8 %x, 0
+ %ext = zext i1 %cmp1 to i64
+ %add = add i64 %ext, -1
+ %cmp2 = icmp eq i64 %add, %y
+ br i1 %cmp2, label %end, label %else
+
+else:
+ %tmp7 = zext i1 %cmp1 to i8
+ br label %end
+
+end:
+ ret void
+}
+
OpenPOWER on IntegriCloud