diff options
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 29 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/or.ll | 14 |
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> |
