summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp6
-rw-r--r--llvm/test/Transforms/InstCombine/icmp.ll19
2 files changed, 22 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 0c434a54cbe..ea175cd10ff 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1646,7 +1646,7 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp,
if (!match(And->getOperand(1), m_APInt(C2)))
return nullptr;
- if (!And->hasOneUse() || !And->getOperand(0)->hasOneUse())
+ if (!And->hasOneUse())
return nullptr;
// If the LHS is an 'and' of a truncate and we can widen the and/compare to
@@ -1658,7 +1658,7 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp,
// set or if it is an equality comparison. Extending a relational comparison
// when we're checking the sign bit would not work.
Value *W;
- if (match(And->getOperand(0), m_Trunc(m_Value(W))) &&
+ if (match(And->getOperand(0), m_OneUse(m_Trunc(m_Value(W)))) &&
(Cmp.isEquality() || (!C1->isNegative() && !C2->isNegative()))) {
// TODO: Is this a good transform for vectors? Wider types may reduce
// throughput. Should this transform be limited (even for scalars) by using
@@ -1680,7 +1680,7 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp,
// (icmp pred (and A, (or (shl 1, B), 1), 0))
//
// iff pred isn't signed
- if (!Cmp.isSigned() && C1->isNullValue() &&
+ if (!Cmp.isSigned() && C1->isNullValue() && And->getOperand(0)->hasOneUse() &&
match(And->getOperand(1), m_One())) {
Constant *One = cast<Constant>(And->getOperand(1));
Value *Or = And->getOperand(0);
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 68d98de0b4e..18d449228bd 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -1615,6 +1615,25 @@ define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
ret <2 x i1> %tobool
}
+; Variation of the above with an extra use of the shift
+define i1 @icmp_and_shr_multiuse(i32 %X) {
+; CHECK-LABEL: @icmp_and_shr_multiuse(
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 240
+; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 496
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], 224
+; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[AND2]], 432
+; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
+; CHECK-NEXT: ret i1 [[AND3]]
+;
+ %shr = lshr i32 %X, 4
+ %and = and i32 %shr, 15
+ %and2 = and i32 %shr, 31 ; second use of the shift
+ %tobool = icmp ne i32 %and, 14
+ %tobool2 = icmp ne i32 %and2, 27
+ %and3 = and i1 %tobool, %tobool2
+ ret i1 %and3
+}
+
; PR16244
define i1 @test71(i8* %x) {
; CHECK-LABEL: @test71(
OpenPOWER on IntegriCloud