1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

[InstCombine] use m_APInt to allow icmp (add X, Y), C folds for splat constant vectors

This is a sibling of:
https://reviews.llvm.org/rL278859

llvm-svn: 278935
This commit is contained in:
Sanjay Patel 2016-08-17 15:24:30 +00:00
parent 584f261fc5
commit f6dffe904b
3 changed files with 36 additions and 48 deletions

View File

@ -2198,53 +2198,48 @@ Instruction *InstCombiner::foldICmpSubConstant(ICmpInst &Cmp, Instruction *Sub,
/// Fold icmp (add X, Y), C.
Instruction *InstCombiner::foldICmpAddConstant(ICmpInst &Cmp, Instruction *Add,
const APInt *C) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(Cmp.getOperand(1));
if (!RHS)
Value *Y = Add->getOperand(1);
const APInt *C2;
if (Cmp.isEquality() || !match(Y, m_APInt(C2)))
return nullptr;
if (Cmp.isEquality())
return nullptr;
// Fold: icmp pred (add X, C2), C
// Fold icmp pred (add X, C2), C.
Value *X = Add->getOperand(0);
ConstantInt *AddC = dyn_cast<ConstantInt>(Add->getOperand(1));
if (!AddC)
return nullptr;
const APInt &C2 = AddC->getValue();
ConstantRange CR = Cmp.makeConstantRange(Cmp.getPredicate(), *C).subtract(C2);
Type *Ty = Add->getType();
auto CR = Cmp.makeConstantRange(Cmp.getPredicate(), *C).subtract(*C2);
const APInt &Upper = CR.getUpper();
const APInt &Lower = CR.getLower();
if (Cmp.isSigned()) {
if (Lower.isSignBit())
return new ICmpInst(ICmpInst::ICMP_SLT, X, Builder->getInt(Upper));
return new ICmpInst(ICmpInst::ICMP_SLT, X, ConstantInt::get(Ty, Upper));
if (Upper.isSignBit())
return new ICmpInst(ICmpInst::ICMP_SGE, X, Builder->getInt(Lower));
return new ICmpInst(ICmpInst::ICMP_SGE, X, ConstantInt::get(Ty, Lower));
} else {
if (Lower.isMinValue())
return new ICmpInst(ICmpInst::ICMP_ULT, X, Builder->getInt(Upper));
return new ICmpInst(ICmpInst::ICMP_ULT, X, ConstantInt::get(Ty, Upper));
if (Upper.isMinValue())
return new ICmpInst(ICmpInst::ICMP_UGE, X, Builder->getInt(Lower));
return new ICmpInst(ICmpInst::ICMP_UGE, X, ConstantInt::get(Ty, Lower));
}
if (Add->hasOneUse()) {
// X+C <u C2 -> (X & -C2) == C
// iff C & (C2-1) == 0
// C2 is a power of 2
if (Cmp.getPredicate() == ICmpInst::ICMP_ULT && C->isPowerOf2() &&
(C2 & (*C - 1)) == 0)
return new ICmpInst(ICmpInst::ICMP_EQ, Builder->CreateAnd(X, -(*C)),
ConstantExpr::getNeg(AddC));
if (!Add->hasOneUse())
return nullptr;
// X+C <u C2 -> (X & -C2) == C
// iff C & (C2-1) == 0
// C2 is a power of 2
if (Cmp.getPredicate() == ICmpInst::ICMP_ULT && C->isPowerOf2() &&
(*C2 & (*C - 1)) == 0)
return new ICmpInst(ICmpInst::ICMP_EQ, Builder->CreateAnd(X, -(*C)),
ConstantExpr::getNeg(cast<Constant>(Y)));
// X+C >u C2 -> (X & ~C2) != C
// iff C & C2 == 0
// C2+1 is a power of 2
if (Cmp.getPredicate() == ICmpInst::ICMP_UGT && (*C + 1).isPowerOf2() &&
(*C2 & *C) == 0)
return new ICmpInst(ICmpInst::ICMP_NE, Builder->CreateAnd(X, ~(*C)),
ConstantExpr::getNeg(cast<Constant>(Y)));
// X+C >u C2 -> (X & ~C2) != C
// iff C & C2 == 0
// C2+1 is a power of 2
if (Cmp.getPredicate() == ICmpInst::ICMP_UGT && (*C + 1).isPowerOf2() &&
(C2 & *C) == 0)
return new ICmpInst(ICmpInst::ICMP_NE, Builder->CreateAnd(X, ~(*C)),
ConstantExpr::getNeg(AddC));
}
return nullptr;
}

View File

@ -2,7 +2,6 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
; PR1949
; FIXME: Vectors should fold the same way for all tests.
define i1 @test1(i32 %a) {
; CHECK-LABEL: @test1(
@ -16,8 +15,7 @@ define i1 @test1(i32 %a) {
define <2 x i1> @test1vec(<2 x i32> %a) {
; CHECK-LABEL: @test1vec(
; CHECK-NEXT: [[B:%.*]] = add <2 x i32> %a, <i32 4, i32 4>
; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> [[B]], <i32 4, i32 4>
; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i32> %a, <i32 -5, i32 -5>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%b = add <2 x i32> %a, <i32 4, i32 4>
@ -37,8 +35,7 @@ define i1 @test2(i32 %a) {
define <2 x i1> @test2vec(<2 x i32> %a) {
; CHECK-LABEL: @test2vec(
; CHECK-NEXT: [[B:%.*]] = add <2 x i32> %a, <i32 -4, i32 -4>
; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i32> [[B]], <i32 -5, i32 -5>
; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> %a, <i32 4, i32 4>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%b = sub <2 x i32> %a, <i32 4, i32 4>
@ -58,8 +55,7 @@ define i1 @test3(i32 %a) {
define <2 x i1> @test3vec(<2 x i32> %a) {
; CHECK-LABEL: @test3vec(
; CHECK-NEXT: [[B:%.*]] = add <2 x i32> %a, <i32 4, i32 4>
; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[B]], <i32 -2147483644, i32 -2147483644>
; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i32> %a, <i32 2147483643, i32 2147483643>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%b = add <2 x i32> %a, <i32 4, i32 4>
@ -79,8 +75,7 @@ define i1 @test4(i32 %a) {
define <2 x i1> @test4vec(<2 x i32> %a) {
; CHECK-LABEL: @test4vec(
; CHECK-NEXT: [[B:%.*]] = add <2 x i32> %a, <i32 -2147483644, i32 -2147483644>
; CHECK-NEXT: [[C:%.*]] = icmp sgt <2 x i32> [[B]], <i32 3, i32 3>
; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> %a, <i32 -4, i32 -4>
; CHECK-NEXT: ret <2 x i1> [[C]]
;
%b = add <2 x i32> %a, <i32 2147483652, i32 2147483652>

View File

@ -1727,11 +1727,10 @@ define i1 @icmp_add_ult_2(i32 %X) {
ret i1 %cmp
}
; FIXME: Vectors should fold too.
define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> %X, <i32 -14, i32 -14>
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[ADD]], <i32 2, i32 2>
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> %X, <i32 -2, i32 -2>
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%add = add <2 x i32> %X, <i32 -14, i32 -14>
@ -1772,11 +1771,10 @@ define i1 @icmp_add_X_-14_uge_2(i32 %X) {
ret i1 %cmp
}
; FIXME: Vectors should fold too.
define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
; CHECK-NEXT: [[ADD:%.*]] = add <2 x i32> %X, <i32 -14, i32 -14>
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[ADD]], <i32 1, i32 1>
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> %X, <i32 -2, i32 -2>
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%add = add <2 x i32> %X, <i32 -14, i32 -14>