aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp29
-rw-r--r--llvm/test/Transforms/InstCombine/or.ll14
2 files changed, 19 insertions, 24 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 230046a2..8b7f7f3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1310,23 +1310,21 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
// This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
Value *LHS0 = LHS->getOperand(0), *RHS0 = RHS->getOperand(0);
+ // (icmp eq A, 0) & (icmp eq B, 0) --> (icmp eq (A|B), 0)
+ // TODO: Remove this when foldLogOpOfMaskedICmps can handle undefs.
+ if (PredL == ICmpInst::ICMP_EQ && match(LHS->getOperand(1), m_ZeroInt()) &&
+ PredR == ICmpInst::ICMP_EQ && match(RHS->getOperand(1), m_ZeroInt()) &&
+ LHS0->getType() == RHS0->getType()) {
+ Value *NewOr = Builder.CreateOr(LHS0, RHS0);
+ return Builder.CreateICmp(PredL, NewOr,
+ Constant::getNullValue(NewOr->getType()));
+ }
+
const APInt *LHSC, *RHSC;
if (!match(LHS->getOperand(1), m_APInt(LHSC)) ||
!match(RHS->getOperand(1), m_APInt(RHSC)))
return nullptr;
- if (LHSC == RHSC && PredL == PredR) {
- // (icmp ult A, C) & (icmp ult B, C) --> (icmp ult (A|B), C)
- // where C is a power of 2 or
- // (icmp eq A, 0) & (icmp eq B, 0) --> (icmp eq (A|B), 0)
- if ((PredL == ICmpInst::ICMP_ULT && LHSC->isPowerOf2()) ||
- (PredL == ICmpInst::ICMP_EQ && LHSC->isZero())) {
- Value *NewOr = Builder.CreateOr(LHS0, RHS0);
- return Builder.CreateICmp(PredL, NewOr,
- ConstantInt::get(NewOr->getType(), *LHSC));
- }
- }
-
// (trunc x) == C1 & (and x, CA) == C2 -> (and x, CA|CMAX) == C1|C2
// where CMAX is the all ones value for the truncated type,
// iff the lower bits of C2 and CA are zero.
@@ -2468,10 +2466,9 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
return X;
// (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0)
- // TODO: Remove this when foldLogOpOfMaskedICmps can handle vectors.
- if (PredL == ICmpInst::ICMP_NE && match(LHS1, m_Zero()) &&
- PredR == ICmpInst::ICMP_NE && match(RHS1, m_Zero()) &&
- LHS0->getType()->isIntOrIntVectorTy() &&
+ // TODO: Remove this when foldLogOpOfMaskedICmps can handle undefs.
+ if (PredL == ICmpInst::ICMP_NE && match(LHS1, m_ZeroInt()) &&
+ PredR == ICmpInst::ICMP_NE && match(RHS1, m_ZeroInt()) &&
LHS0->getType() == RHS0->getType()) {
Value *NewOr = Builder.CreateOr(LHS0, RHS0);
return Builder.CreateICmp(PredL, NewOr,
diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll
index 4e66efc..01ffdac 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -248,10 +248,9 @@ define <2 x i1> @and_icmp_eq_0_vector(<2 x i32> %A, <2 x i32> %B) {
define <2 x i1> @and_icmp_eq_0_vector_undef1(<2 x i32> %A, <2 x i32> %B) {
; CHECK-LABEL: @and_icmp_eq_0_vector_undef1(
-; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 0, i32 undef>
-; CHECK-NEXT: [[C2:%.*]] = icmp eq <2 x i32> [[B:%.*]], <i32 0, i32 undef>
-; CHECK-NEXT: [[D:%.*]] = and <2 x i1> [[C1]], [[C2]]
-; CHECK-NEXT: ret <2 x i1> [[D]]
+; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
+; CHECK-NEXT: ret <2 x i1> [[TMP2]]
;
%C1 = icmp eq <2 x i32> %A, <i32 0, i32 undef>
%C2 = icmp eq <2 x i32> %B, <i32 0, i32 undef>
@@ -261,10 +260,9 @@ define <2 x i1> @and_icmp_eq_0_vector_undef1(<2 x i32> %A, <2 x i32> %B) {
define <2 x i1> @and_icmp_eq_0_vector_undef2(<2 x i32> %A, <2 x i32> %B) {
; CHECK-LABEL: @and_icmp_eq_0_vector_undef2(
-; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 0, i32 undef>
-; CHECK-NEXT: [[C2:%.*]] = icmp eq <2 x i32> [[B:%.*]], <i32 undef, i32 0>
-; CHECK-NEXT: [[D:%.*]] = and <2 x i1> [[C1]], [[C2]]
-; CHECK-NEXT: ret <2 x i1> [[D]]
+; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
+; CHECK-NEXT: ret <2 x i1> [[TMP2]]
;
%C1 = icmp eq <2 x i32> %A, <i32 0, i32 undef>
%C2 = icmp eq <2 x i32> %B, <i32 undef, i32 0>