summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2014-01-19 15:24:22 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2014-01-19 15:24:22 +0000
commit0487faa97b7afd3e186bd6a56c864b7e66e354a0 (patch)
tree88e0b3bb3fe45f31e0b4923d2f09165865dc2f20
parent3f6a9d705ae081d6e86b558a4014fc57de7a1b22 (diff)
downloadllvm-0487faa97b7afd3e186bd6a56c864b7e66e354a0.tar.gz
llvm-0487faa97b7afd3e186bd6a56c864b7e66e354a0.tar.bz2
llvm-0487faa97b7afd3e186bd6a56c864b7e66e354a0.tar.xz
InstCombine: Teach most integer add/sub/mul/div combines how to deal with vectors.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199602 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstCombineAddSub.cpp115
-rw-r--r--lib/Transforms/InstCombine/InstCombineMulDivRem.cpp43
-rw-r--r--test/Transforms/InstCombine/add2.ll35
-rw-r--r--test/Transforms/InstCombine/div.ll24
-rw-r--r--test/Transforms/InstCombine/mul.ll16
-rw-r--r--test/Transforms/InstCombine/rem.ll9
-rw-r--r--test/Transforms/InstCombine/sub.ll54
-rw-r--r--test/Transforms/InstCombine/vec_phi_extract.ll2
-rw-r--r--test/Transforms/LoopVectorize/global_alias.ll8
9 files changed, 224 insertions, 82 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index d49153e482..7f22bcce09 100644
--- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -851,8 +851,8 @@ static Constant *AddOne(Constant *C) {
}
/// SubOne - Subtract one from a ConstantInt.
-static Constant *SubOne(ConstantInt *C) {
- return ConstantInt::get(C->getContext(), C->getValue()-1);
+static Constant *SubOne(Constant *C) {
+ return ConstantExpr::getAdd(C, ConstantInt::getAllOnesValue(C->getType()));
}
@@ -861,23 +861,20 @@ static Constant *SubOne(ConstantInt *C) {
// non-constant operand of the multiply, and set CST to point to the multiplier.
// Otherwise, return null.
//
-static inline Value *dyn_castFoldableMul(Value *V, ConstantInt *&CST) {
- if (!V->hasOneUse() || !V->getType()->isIntegerTy())
+static inline Value *dyn_castFoldableMul(Value *V, Constant *&CST) {
+ if (!V->hasOneUse() || !V->getType()->isIntOrIntVectorTy())
return 0;
Instruction *I = dyn_cast<Instruction>(V);
if (I == 0) return 0;
if (I->getOpcode() == Instruction::Mul)
- if ((CST = dyn_cast<ConstantInt>(I->getOperand(1))))
+ if ((CST = dyn_cast<Constant>(I->getOperand(1))))
return I->getOperand(0);
if (I->getOpcode() == Instruction::Shl)
- if ((CST = dyn_cast<ConstantInt>(I->getOperand(1)))) {
+ if ((CST = dyn_cast<Constant>(I->getOperand(1)))) {
// The multiplier is really 1 << CST.
- uint32_t BitWidth = cast<IntegerType>(V->getType())->getBitWidth();
- uint32_t CSTVal = CST->getLimitedValue(BitWidth);
- CST = ConstantInt::get(V->getType()->getContext(),
- APInt::getOneBitSet(BitWidth, CSTVal));
+ CST = ConstantExpr::getShl(ConstantInt::get(V->getType(), 1), CST);
return I->getOperand(0);
}
return 0;
@@ -987,7 +984,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
if (Instruction *NV = FoldOpIntoPhi(I))
return NV;
- if (I.getType()->isIntegerTy(1))
+ if (I.getType()->getScalarType()->isIntegerTy(1))
return BinaryOperator::CreateXor(LHS, RHS);
// X + X --> X << 1
@@ -1017,21 +1014,23 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
return BinaryOperator::CreateSub(LHS, V);
- ConstantInt *C2;
- if (Value *X = dyn_castFoldableMul(LHS, C2)) {
- if (X == RHS) // X*C + X --> X * (C+1)
- return BinaryOperator::CreateMul(RHS, AddOne(C2));
+ {
+ Constant *C2;
+ if (Value *X = dyn_castFoldableMul(LHS, C2)) {
+ if (X == RHS) // X*C + X --> X * (C+1)
+ return BinaryOperator::CreateMul(RHS, AddOne(C2));
+
+ // X*C1 + X*C2 --> X * (C1+C2)
+ Constant *C1;
+ if (X == dyn_castFoldableMul(RHS, C1))
+ return BinaryOperator::CreateMul(X, ConstantExpr::getAdd(C1, C2));
+ }
- // X*C1 + X*C2 --> X * (C1+C2)
- ConstantInt *C1;
- if (X == dyn_castFoldableMul(RHS, C1))
- return BinaryOperator::CreateMul(X, ConstantExpr::getAdd(C1, C2));
+ // X + X*C --> X * (C+1)
+ if (dyn_castFoldableMul(RHS, C2) == LHS)
+ return BinaryOperator::CreateMul(LHS, AddOne(C2));
}
- // X + X*C --> X * (C+1)
- if (dyn_castFoldableMul(RHS, C2) == LHS)
- return BinaryOperator::CreateMul(LHS, AddOne(C2));
-
// A+B --> A|B iff A and B have no bits set in common.
if (IntegerType *IT = dyn_cast<IntegerType>(I.getType())) {
APInt LHSKnownOne(IT->getBitWidth(), 0);
@@ -1071,12 +1070,16 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
}
}
- if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
- Value *X = 0;
- if (match(LHS, m_Not(m_Value(X)))) // ~X + C --> (C-1) - X
+ if (Constant *CRHS = dyn_cast<Constant>(RHS)) {
+ Value *X;
+ if (match(LHS, m_Not(m_Value(X)))) // ~X + C --> (C-1) - X
return BinaryOperator::CreateSub(SubOne(CRHS), X);
+ }
+ if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
// (X & FF00) + xx00 -> (X+xx00) & FF00
+ Value *X;
+ ConstantInt *C2;
if (LHS->hasOneUse() &&
match(LHS, m_And(m_Value(X), m_ConstantInt(C2))) &&
CRHS->getValue() == (CRHS->getValue() & C2->getValue())) {
@@ -1381,51 +1384,53 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
if (match(Op0, m_AllOnes()))
return BinaryOperator::CreateNot(Op1);
- if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) {
+ if (Constant *C = dyn_cast<Constant>(Op0)) {
// C - ~X == X + (1+C)
Value *X = 0;
if (match(Op1, m_Not(m_Value(X))))
return BinaryOperator::CreateAdd(X, AddOne(C));
- // -(X >>u 31) -> (X >>s 31)
- // -(X >>s 31) -> (X >>u 31)
- if (C->isZero()) {
- Value *X; ConstantInt *CI;
- if (match(Op1, m_LShr(m_Value(X), m_ConstantInt(CI))) &&
- // Verify we are shifting out everything but the sign bit.
- CI->getValue() == I.getType()->getPrimitiveSizeInBits()-1)
- return BinaryOperator::CreateAShr(X, CI);
-
- if (match(Op1, m_AShr(m_Value(X), m_ConstantInt(CI))) &&
- // Verify we are shifting out everything but the sign bit.
- CI->getValue() == I.getType()->getPrimitiveSizeInBits()-1)
- return BinaryOperator::CreateLShr(X, CI);
- }
-
// Try to fold constant sub into select arguments.
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
if (Instruction *R = FoldOpIntoSelect(I, SI))
return R;
// C-(X+C2) --> (C-C2)-X
- ConstantInt *C2;
- if (match(Op1, m_Add(m_Value(X), m_ConstantInt(C2))))
+ Constant *C2;
+ if (match(Op1, m_Add(m_Value(X), m_Constant(C2))))
return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X);
if (SimplifyDemandedInstructionBits(I))
return &I;
// Fold (sub 0, (zext bool to B)) --> (sext bool to B)
- if (C->isZero() && match(Op1, m_ZExt(m_Value(X))))
- if (X->getType()->isIntegerTy(1))
+ if (C->isNullValue() && match(Op1, m_ZExt(m_Value(X))))
+ if (X->getType()->getScalarType()->isIntegerTy(1))
return CastInst::CreateSExtOrBitCast(X, Op1->getType());
// Fold (sub 0, (sext bool to B)) --> (zext bool to B)
- if (C->isZero() && match(Op1, m_SExt(m_Value(X))))
- if (X->getType()->isIntegerTy(1))
+ if (C->isNullValue() && match(Op1, m_SExt(m_Value(X))))
+ if (X->getType()->getScalarType()->isIntegerTy(1))
return CastInst::CreateZExtOrBitCast(X, Op1->getType());
}
+ if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) {
+ // -(X >>u 31) -> (X >>s 31)
+ // -(X >>s 31) -> (X >>u 31)
+ if (C->isZero()) {
+ Value *X; ConstantInt *CI;
+ if (match(Op1, m_LShr(m_Value(X), m_ConstantInt(CI))) &&
+ // Verify we are shifting out everything but the sign bit.
+ CI->getValue() == I.getType()->getPrimitiveSizeInBits()-1)
+ return BinaryOperator::CreateAShr(X, CI);
+
+ if (match(Op1, m_AShr(m_Value(X), m_ConstantInt(CI))) &&
+ // Verify we are shifting out everything but the sign bit.
+ CI->getValue() == I.getType()->getPrimitiveSizeInBits()-1)
+ return BinaryOperator::CreateLShr(X, CI);
+ }
+ }
+
{ Value *Y;
// X-(X+Y) == -Y X-(Y+X) == -Y
@@ -1441,7 +1446,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
if (Op1->hasOneUse()) {
Value *X = 0, *Y = 0, *Z = 0;
Constant *C = 0;
- ConstantInt *CI = 0;
+ Constant *CI = 0;
// (X - (Y - Z)) --> (X + (Z - Y)).
if (match(Op1, m_Sub(m_Value(Y), m_Value(Z))))
@@ -1466,13 +1471,13 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
return BinaryOperator::CreateShl(XNeg, Y);
// X - X*C --> X * (1-C)
- if (match(Op1, m_Mul(m_Specific(Op0), m_ConstantInt(CI)))) {
+ if (match(Op1, m_Mul(m_Specific(Op0), m_Constant(CI)))) {
Constant *CP1 = ConstantExpr::getSub(ConstantInt::get(I.getType(),1), CI);
return BinaryOperator::CreateMul(Op0, CP1);
}
// X - X<<C --> X * (1-(1<<C))
- if (match(Op1, m_Shl(m_Specific(Op0), m_ConstantInt(CI)))) {
+ if (match(Op1, m_Shl(m_Specific(Op0), m_Constant(CI)))) {
Constant *One = ConstantInt::get(I.getType(), 1);
C = ConstantExpr::getSub(One, ConstantExpr::getShl(One, CI));
return BinaryOperator::CreateMul(Op0, C);
@@ -1487,19 +1492,19 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
// X - A*CI -> X + A*-CI
// X - CI*A -> X + A*-CI
- if (match(Op1, m_Mul(m_Value(A), m_ConstantInt(CI))) ||
- match(Op1, m_Mul(m_ConstantInt(CI), m_Value(A)))) {
+ if (match(Op1, m_Mul(m_Value(A), m_Constant(CI))) ||
+ match(Op1, m_Mul(m_Constant(CI), m_Value(A)))) {
Value *NewMul = Builder->CreateMul(A, ConstantExpr::getNeg(CI));
return BinaryOperator::CreateAdd(Op0, NewMul);
}
}
- ConstantInt *C1;
+ Constant *C1;
if (Value *X = dyn_castFoldableMul(Op0, C1)) {
if (X == Op1) // X*C - X --> X * (C-1)
return BinaryOperator::CreateMul(Op1, SubOne(C1));
- ConstantInt *C2; // X*C1 - X*C2 -> X * (C1-C2)
+ Constant *C2; // X*C1 - X*C2 -> X * (C1-C2)
if (X == dyn_castFoldableMul(Op1, C2))
return BinaryOperator::CreateMul(X, ConstantExpr::getSub(C1, C2));
}
diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index e6c04f51da..738756a5a2 100644
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -158,15 +158,6 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
}
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
- // Canonicalize (X+C1)*CI -> X*CI+C1*CI.
- { Value *X; ConstantInt *C1;
- if (Op0->hasOneUse() &&
- match(Op0, m_Add(m_Value(X), m_ConstantInt(C1)))) {
- Value *Add = Builder->CreateMul(X, CI);
- return BinaryOperator::CreateAdd(Add, Builder->CreateMul(C1, CI));
- }
- }
-
// (Y - X) * (-(2**n)) -> (X - Y) * (2**n), for positive nonzero n
// (Y + const) * (-(2**n)) -> (-constY) * (2**n), for positive nonzero n
// The "* (2**n)" thus becomes a potential shifting opportunity.
@@ -201,6 +192,16 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
if (isa<PHINode>(Op0))
if (Instruction *NV = FoldOpIntoPhi(I))
return NV;
+
+ // Canonicalize (X+C1)*CI -> X*CI+C1*CI.
+ {
+ Value *X;
+ Constant *C1;
+ if (match(Op0, m_OneUse(m_Add(m_Value(X), m_Constant(C1))))) {
+ Value *Add = Builder->CreateMul(X, Op1);
+ return BinaryOperator::CreateAdd(Add, Builder->CreateMul(C1, Op1));
+ }
+ }
}
if (Value *Op0v = dyn_castNegVal(Op0)) // -X * -Y = X*Y
@@ -247,7 +248,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
}
/// i1 mul -> i1 and.
- if (I.getType()->isIntegerTy(1))
+ if (I.getType()->getScalarType()->isIntegerTy(1))
return BinaryOperator::CreateAnd(Op0, Op1);
// X*(1 << Y) --> X << Y
@@ -882,13 +883,11 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
return Common;
// (x lshr C1) udiv C2 --> x udiv (C2 << C1)
- if (ConstantInt *C2 = dyn_cast<ConstantInt>(Op1)) {
+ if (Constant *C2 = dyn_cast<Constant>(Op1)) {
Value *X;
- ConstantInt *C1;
- if (match(Op0, m_LShr(m_Value(X), m_ConstantInt(C1)))) {
- APInt NC = C2->getValue().shl(C1->getLimitedValue(C1->getBitWidth()-1));
- return BinaryOperator::CreateUDiv(X, Builder->getInt(NC));
- }
+ Constant *C1;
+ if (match(Op0, m_LShr(m_Value(X), m_Constant(C1))))
+ return BinaryOperator::CreateUDiv(X, ConstantExpr::getShl(C2, C1));
}
// (zext A) udiv (zext B) --> zext (A udiv B)
@@ -942,11 +941,11 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
if (Instruction *Common = commonIDivTransforms(I))
return Common;
- if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
- // sdiv X, -1 == -X
- if (RHS->isAllOnesValue())
- return BinaryOperator::CreateNeg(Op0);
+ // sdiv X, -1 == -X
+ if (match(Op1, m_AllOnes()))
+ return BinaryOperator::CreateNeg(Op0);
+ if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
// sdiv X, C --> ashr exact X, log2(C)
if (I.isExact() && RHS->getValue().isNonNegative() &&
RHS->getValue().isPowerOf2()) {
@@ -954,7 +953,9 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
RHS->getValue().exactLogBase2());
return BinaryOperator::CreateExactAShr(Op0, ShAmt, I.getName());
}
+ }
+ if (Constant *RHS = dyn_cast<Constant>(Op1)) {
// -X/C --> X/-C provided the negation doesn't overflow.
if (SubOperator *Sub = dyn_cast<SubOperator>(Op0))
if (match(Sub->getOperand(0), m_Zero()) && Sub->hasNoSignedWrap())
@@ -1149,7 +1150,7 @@ Instruction *InstCombiner::commonIRemTransforms(BinaryOperator &I) {
if (isa<SelectInst>(Op1) && SimplifyDivRemOfSelect(I))
return &I;
- if (isa<ConstantInt>(Op1)) {
+ if (isa<Constant>(Op1)) {
if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) {
if (SelectInst *SI = dyn_cast<SelectInst>(Op0I)) {
if (Instruction *R = FoldOpIntoSelect(I, SI))
diff --git a/test/Transforms/InstCombine/add2.ll b/test/Transforms/InstCombine/add2.ll
index 0964bc00d1..67d560e500 100644
--- a/test/Transforms/InstCombine/add2.ll
+++ b/test/Transforms/InstCombine/add2.ll
@@ -41,3 +41,38 @@ define i32 @test4(i32 %A) {
; CHECK-NEXT: ret i32 %B
}
+define <2 x i1> @test5(<2 x i1> %A, <2 x i1> %B) {
+ %add = add <2 x i1> %A, %B
+ ret <2 x i1> %add
+; CHECK-LABEL: @test5(
+; CHECK-NEXT: %add = xor <2 x i1> %A, %B
+; CHECK-NEXT: ret <2 x i1> %add
+}
+
+define <2 x i64> @test6(<2 x i64> %A) {
+ %shl = shl <2 x i64> %A, <i64 2, i64 3>
+ %add = add <2 x i64> %shl, %A
+ ret <2 x i64> %add
+; CHECK-LABEL: @test6(
+; CHECK-NEXT: %add = mul <2 x i64> %A, <i64 5, i64 9>
+; CHECK-NEXT: ret <2 x i64> %add
+}
+
+define <2 x i64> @test7(<2 x i64> %A) {
+ %shl = shl <2 x i64> %A, <i64 2, i64 3>
+ %mul = mul <2 x i64> %A, <i64 3, i64 4>
+ %add = add <2 x i64> %shl, %mul
+ ret <2 x i64> %add
+; CHECK-LABEL: @test7(
+; CHECK-NEXT: %add = mul <2 x i64> %A, <i64 7, i64 12>
+; CHECK-NEXT: ret <2 x i64> %add
+}
+
+define <2 x i64> @test8(<2 x i64> %A) {
+ %xor = xor <2 x i64> %A, <i64 -1, i64 -1>
+ %add = add <2 x i64> %xor, <i64 2, i64 3>
+ ret <2 x i64> %add
+; CHECK-LABEL: @test8(
+; CHECK-NEXT: %add = sub <2 x i64> <i64 1, i64 2>, %A
+; CHECK-NEXT: ret <2 x i64> %add
+}
diff --git a/test/Transforms/InstCombine/div.ll b/test/Transforms/InstCombine/div.ll
index f67fd1c51b..1bf486fa33 100644
--- a/test/Transforms/InstCombine/div.ll
+++ b/test/Transforms/InstCombine/div.ll
@@ -131,4 +131,28 @@ define i32 @test15(i32 %a, i32 %b) nounwind {
; CHECK-NEXT: ret i32
}
+define <2 x i64> @test16(<2 x i64> %x) nounwind {
+ %shr = lshr <2 x i64> %x, <i64 3, i64 5>
+ %div = udiv <2 x i64> %shr, <i64 4, i64 6>
+ ret <2 x i64> %div
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: udiv <2 x i64> %x, <i64 32, i64 192>
+; CHECK-NEXT: ret <2 x i64>
+}
+
+define <2 x i64> @test17(<2 x i64> %x) nounwind {
+ %neg = sub nsw <2 x i64> zeroinitializer, %x
+ %div = sdiv <2 x i64> %neg, <i64 3, i64 4>
+ ret <2 x i64> %div
+; CHECK-LABEL: @test17(
+; CHECK-NEXT: sdiv <2 x i64> %x, <i64 -3, i64 -4>
+; CHECK-NEXT: ret <2 x i64>
+}
+define <2 x i64> @test18(<2 x i64> %x) nounwind {
+ %div = sdiv <2 x i64> %x, <i64 -1, i64 -1>
+ ret <2 x i64> %div
+; CHECK-LABEL: @test18(
+; CHECK-NEXT: sub <2 x i64> zeroinitializer, %x
+; CHECK-NEXT: ret <2 x i64>
+}
diff --git a/test/Transforms/InstCombine/mul.ll b/test/Transforms/InstCombine/mul.ll
index 94fc1183c5..d19bedc7a1 100644
--- a/test/Transforms/InstCombine/mul.ll
+++ b/test/Transforms/InstCombine/mul.ll
@@ -181,3 +181,19 @@ define i32 @test19(i32 %A, i32 %B) {
ret i32 %H
; CHECK: ret i32 0
}
+
+define <2 x i64> @test20(<2 x i64> %A) {
+; CHECK-LABEL: @test20(
+ %B = add <2 x i64> %A, <i64 12, i64 14>
+ %C = mul <2 x i64> %B, <i64 3, i64 2>
+ ret <2 x i64> %C
+; CHECK: mul <2 x i64> %A, <i64 3, i64 2>
+; CHECK: add <2 x i64> %{{.}}, <i64 36, i64 28>
+}
+
+define <2 x i1> @test21(<2 x i1> %A, <2 x i1> %B) {
+; CHECK-LABEL: @test21(
+ %C = mul <2 x i1> %A, %B
+ ret <2 x i1> %C
+; CHECK: %C = and <2 x i1> %A, %B
+}
diff --git a/test/Transforms/InstCombine/rem.ll b/test/Transforms/InstCombine/rem.ll
index 22fd90bf7a..9f07702681 100644
--- a/test/Transforms/InstCombine/rem.ll
+++ b/test/Transforms/InstCombine/rem.ll
@@ -204,3 +204,12 @@ define i32 @test19(i32 %x, i32 %y) {
%E = urem i32 %y, %D
ret i32 %E
}
+
+define <2 x i64> @test20(<2 x i64> %X, <2 x i1> %C) {
+; CHECK-LABEL: @test20(
+; CHECK-NEXT: select <2 x i1> %C, <2 x i64> <i64 1, i64 2>, <2 x i64> zeroinitializer
+; CHECK-NEXT: ret <2 x i64>
+ %V = select <2 x i1> %C, <2 x i64> <i64 1, i64 2>, <2 x i64> <i64 8, i64 9>
+ %R = urem <2 x i64> %V, <i64 2, i64 3>
+ ret <2 x i64> %R
+}
diff --git a/test/Transforms/InstCombine/sub.ll b/test/Transforms/InstCombine/sub.ll
index 36c523bd7b..41d803c8bd 100644
--- a/test/Transforms/InstCombine/sub.ll
+++ b/test/Transforms/InstCombine/sub.ll
@@ -391,4 +391,56 @@ define i16 @test30_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
ret i16 %sub
}
-
+define <2 x i64> @test31(<2 x i64> %A) {
+ %xor = xor <2 x i64> %A, <i64 -1, i64 -1>
+ %sub = sub <2 x i64> <i64 2, i64 3>, %xor
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test31(
+; CHECK-NEXT: %sub = add <2 x i64> %A, <i64 3, i64 4>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i64> @test32(<2 x i64> %A) {
+ %add = add <2 x i64> %A, <i64 -1, i64 -1>
+ %sub = sub <2 x i64> <i64 2, i64 3>, %add
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test32(
+; CHECK-NEXT: %sub = sub <2 x i64> <i64 3, i64 4>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i64> @test33(<2 x i1> %A) {
+ %ext = zext <2 x i1> %A to <2 x i64>
+ %sub = sub <2 x i64> zeroinitializer, %ext
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test33(
+; CHECK-NEXT: %sub = sext <2 x i1> %A to <2 x i64>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i64> @test34(<2 x i1> %A) {
+ %ext = sext <2 x i1> %A to <2 x i64>
+ %sub = sub <2 x i64> zeroinitializer, %ext
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test34(
+; CHECK-NEXT: %sub = zext <2 x i1> %A to <2 x i64>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i64> @test35(<2 x i64> %A) {
+ %mul = mul <2 x i64> %A, <i64 3, i64 4>
+ %sub = sub <2 x i64> %A, %mul
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test35(
+; CHECK-NEXT: %sub = mul <2 x i64> %A, <i64 -2, i64 -3>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
+
+define <2 x i64> @test36(<2 x i64> %A) {
+ %shl = shl <2 x i64> %A, <i64 3, i64 4>
+ %sub = sub <2 x i64> %shl, %A
+ ret <2 x i64> %sub
+; CHECK-LABEL: @test36(
+; CHECK-NEXT: %sub = mul <2 x i64> %A, <i64 7, i64 15>
+; CHECK-NEXT: ret <2 x i64> %sub
+}
diff --git a/test/Transforms/InstCombine/vec_phi_extract.ll b/test/Transforms/InstCombine/vec_phi_extract.ll
index b0f365ba79..1d778a000f 100644
--- a/test/Transforms/InstCombine/vec_phi_extract.ll
+++ b/test/Transforms/InstCombine/vec_phi_extract.ll
@@ -39,7 +39,7 @@ for.cond:
; CHECK: extractelement
for.body:
%dec43 = add <3 x i32> %input_1.addr.1, <i32 -1, i32 -1, i32 -1>
- %sub44 = sub <3 x i32> zeroinitializer, %dec43
+ %sub44 = sub <3 x i32> <i32 -1, i32 -1, i32 -1>, %dec43
%div45 = sdiv <3 x i32> %input_2.addr.0, %sub44
br label %for.cond
diff --git a/test/Transforms/LoopVectorize/global_alias.ll b/test/Transforms/LoopVectorize/global_alias.ll
index 0118fb4741..d64d67f6a5 100644
--- a/test/Transforms/LoopVectorize/global_alias.ll
+++ b/test/Transforms/LoopVectorize/global_alias.ll
@@ -387,7 +387,7 @@ for.end: ; preds = %for.cond
; return Foo.A[a];
; }
; CHECK-LABEL: define i32 @noAlias08(
-; CHECK: sub nsw <4 x i32>
+; CHECK: sub <4 x i32>
; CHECK: ret
define i32 @noAlias08(i32 %a) #0 {
@@ -439,7 +439,7 @@ for.end: ; preds = %for.cond
; return Foo.A[a];
; }
; CHECK-LABEL: define i32 @noAlias09(
-; CHECK: sub nsw <4 x i32>
+; CHECK: sub <4 x i32>
; CHECK: ret
define i32 @noAlias09(i32 %a) #0 {
@@ -491,7 +491,7 @@ for.end: ; preds = %for.cond
; return *(PA+a);
; }
; CHECK-LABEL: define i32 @noAlias10(
-; CHECK-NOT: sub nsw <4 x i32>
+; CHECK-NOT: sub {{.*}} <4 x i32>
; CHECK: ret
;
; TODO: This test vectorizes (with run-time check) on real targets with -O3)
@@ -721,7 +721,7 @@ for.end: ; preds = %for.cond
; return Foo.A[a];
; }
; CHECK-LABEL: define i32 @noAlias14(
-; CHECK: sub nsw <4 x i32>
+; CHECK: sub <4 x i32>
; CHECK: ret
define i32 @noAlias14(i32 %a) #0 {