mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
InstCombine: Teach most integer add/sub/mul/div combines how to deal with vectors.
llvm-svn: 199602
This commit is contained in:
parent
b864b5d907
commit
0de38fdc6a
@ -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)
|
||||
ConstantInt *C1;
|
||||
if (X == dyn_castFoldableMul(RHS, C1))
|
||||
return BinaryOperator::CreateMul(X, ConstantExpr::getAdd(C1, 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 + 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,12 +1384,37 @@ 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));
|
||||
|
||||
// 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
|
||||
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->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->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()) {
|
||||
@ -1401,29 +1429,6 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
||||
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))))
|
||||
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))
|
||||
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))
|
||||
return CastInst::CreateZExtOrBitCast(X, Op1->getType());
|
||||
}
|
||||
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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>
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user