From de885f1b2abe7fd26c22bbb551d1dc86a87e6dff Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Mon, 19 Oct 2020 15:41:07 +0100 Subject: [PATCH] [InstCombine] Add (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0) vector support Scalar cases were already being handled by foldLogOpOfMaskedICmps (so this was dead code), but refactoring to support non-uniform vectors will take some time, so tweak this fold in the meantime. --- .../Transforms/InstCombine/InstCombineAndOrXor.cpp | 19 +++++++++++-------- llvm/test/Transforms/InstCombine/icmp.ll | 14 ++++++-------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 9b3e373..c636cfa 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2403,20 +2403,23 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS, foldUnsignedUnderflowCheck(RHS, LHS, /*IsAnd=*/false, Q, Builder)) 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() && + LHS0->getType() == RHS0->getType()) { + Value *NewOr = Builder.CreateOr(LHS0, RHS0); + return Builder.CreateICmp(PredL, NewOr, + Constant::getNullValue(NewOr->getType())); + } + // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2). auto *LHSC = dyn_cast(LHS1); auto *RHSC = dyn_cast(RHS1); if (!LHSC || !RHSC) return nullptr; - if (LHSC == RHSC && PredL == PredR) { - // (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0) - if (PredL == ICmpInst::ICMP_NE && LHSC->isZero()) { - Value *NewOr = Builder.CreateOr(LHS0, RHS0); - return Builder.CreateICmp(PredL, NewOr, LHSC); - } - } - // (icmp ult (X + CA), C1) | (icmp eq X, C2) -> (icmp ule (X + CA), C1) // iff C2 + CA == C1. if (PredL == ICmpInst::ICMP_ULT && PredR == ICmpInst::ICMP_EQ) { diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index c6bfc29..80dd9d2 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -2200,10 +2200,9 @@ define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) { define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) { ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i64> [[A:%.*]], zeroinitializer -; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[B:%.*]], zeroinitializer -; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]] -; CHECK-NEXT: ret <2 x i1> [[TMP3]] +; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer +; CHECK-NEXT: ret <2 x i1> [[TMP2]] ; %1 = icmp ne <2 x i64> %a, zeroinitializer %2 = icmp ne <2 x i64> %b, zeroinitializer @@ -2213,10 +2212,9 @@ define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_undef(<2 x i64> %a, <2 x i64> %b) { ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_undef( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i64> [[A:%.*]], -; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[B:%.*]], -; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]] -; CHECK-NEXT: ret <2 x i1> [[TMP3]] +; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer +; CHECK-NEXT: ret <2 x i1> [[TMP2]] ; %1 = icmp ne <2 x i64> %a, %2 = icmp ne <2 x i64> %b, -- 2.7.4