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:
parent
584f261fc5
commit
f6dffe904b
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user