[llvm] r278935 - [InstCombine] use m_APInt to allow icmp (add X, Y), C folds for splat constant vectors
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 17 08:24:31 PDT 2016
Author: spatel
Date: Wed Aug 17 10:24:30 2016
New Revision: 278935
URL: http://llvm.org/viewvc/llvm-project?rev=278935&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.ll
llvm/trunk/test/Transforms/InstCombine/icmp.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=278935&r1=278934&r2=278935&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Wed Aug 17 10:24:30 2016
@@ -2198,53 +2198,48 @@ Instruction *InstCombiner::foldICmpSubCo
/// 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));
-
- // 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));
- }
+ 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)));
+
return nullptr;
}
Modified: llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.ll?rev=278935&r1=278934&r2=278935&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/2008-01-29-AddICmp.ll Wed Aug 17 10:24:30 2016
@@ -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>
Modified: llvm/trunk/test/Transforms/InstCombine/icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp.ll?rev=278935&r1=278934&r2=278935&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/icmp.ll Wed Aug 17 10:24:30 2016
@@ -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>
More information about the llvm-commits
mailing list