From 40c53ea93374d90c303e4b9606cbcc745db9df95 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 15 Sep 2016 16:23:20 +0000 Subject: [PATCH] [InstCombine] allow (icmp sgt smin(PosA, B), 0) fold for vectors llvm-svn: 281624 --- .../InstCombine/InstCombineCompares.cpp | 32 +++++++++++-------- .../Transforms/InstCombine/min-positive.ll | 14 ++------ 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index fb5122a5edb9..e8c6a27090d8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1376,11 +1376,10 @@ static Instruction *ProcessUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B, // Fold icmp Pred X, C. Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &Cmp) { CmpInst::Predicate Pred = Cmp.getPredicate(); - Value *X = Cmp.getOperand(0), *C = Cmp.getOperand(1); + Value *X = Cmp.getOperand(0); - // FIXME: Use m_APInt to allow folds for splat constants. - ConstantInt *CI = dyn_cast(C); - if (!CI) + const APInt *C; + if (!match(Cmp.getOperand(1), m_APInt(C))) return nullptr; Value *A = nullptr, *B = nullptr; @@ -1400,21 +1399,26 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &Cmp) { ConstantInt *CI2; // I = icmp ugt (add (add A, B), CI2), CI if (Pred == ICmpInst::ICMP_UGT && match(X, m_Add(m_Add(m_Value(A), m_Value(B)), m_ConstantInt(CI2)))) - if (Instruction *Res = ProcessUGT_ADDCST_ADD(Cmp, A, B, CI2, CI, *this)) + if (Instruction *Res = ProcessUGT_ADDCST_ADD( + Cmp, A, B, CI2, cast(Cmp.getOperand(1)), *this)) return Res; } // (icmp sgt smin(PosA, B) 0) -> (icmp sgt B 0) - if (CI->isZero() && Pred == ICmpInst::ICMP_SGT) - if (auto *SI = dyn_cast(X)) { - SelectPatternResult SPR = matchSelectPattern(SI, A, B); - if (SPR.Flavor == SPF_SMIN) { - if (isKnownPositive(A, DL)) - return new ICmpInst(Pred, B, CI); - if (isKnownPositive(B, DL)) - return new ICmpInst(Pred, A, CI); - } + if (*C == 0 && Pred == ICmpInst::ICMP_SGT) { + SelectPatternResult SPR = matchSelectPattern(X, A, B); + if (SPR.Flavor == SPF_SMIN) { + if (isKnownPositive(A, DL)) + return new ICmpInst(Pred, B, Cmp.getOperand(1)); + if (isKnownPositive(B, DL)) + return new ICmpInst(Pred, A, Cmp.getOperand(1)); } + } + + // FIXME: Use m_APInt to allow folds for splat constants. + ConstantInt *CI = dyn_cast(Cmp.getOperand(1)); + if (!CI) + return nullptr; // The following transforms are only worth it if the only user of the subtract // is the icmp. diff --git a/llvm/test/Transforms/InstCombine/min-positive.ll b/llvm/test/Transforms/InstCombine/min-positive.ll index 58258e1a2935..c82e51a0e438 100644 --- a/llvm/test/Transforms/InstCombine/min-positive.ll +++ b/llvm/test/Transforms/InstCombine/min-positive.ll @@ -19,11 +19,7 @@ define i1 @smin(i32 %other) { define <2 x i1> @smin_vec(<2 x i32> %x, <2 x i32> %other) { ; CHECK-LABEL: @smin_vec( -; CHECK-NEXT: [[NOTNEG:%.*]] = and <2 x i32> %x, -; CHECK-NEXT: [[POSITIVE:%.*]] = or <2 x i32> [[NOTNEG]], -; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[POSITIVE]], %other -; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[POSITIVE]], <2 x i32> %other -; CHECK-NEXT: [[TEST:%.*]] = icmp sgt <2 x i32> [[SEL]], zeroinitializer +; CHECK-NEXT: [[TEST:%.*]] = icmp sgt <2 x i32> %other, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[TEST]] ; %notneg = and <2 x i32> %x, @@ -48,16 +44,12 @@ define i1 @smin_commute(i32 %other) { define <2 x i1> @smin_commute_vec(<2 x i32> %x, <2 x i32> %other) { ; CHECK-LABEL: @smin_commute_vec( -; CHECK-NEXT: [[NOTNEG:%.*]] = and <2 x i32> %x, -; CHECK-NEXT: [[POSITIVE:%.*]] = or <2 x i32> [[NOTNEG]], -; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[POSITIVE]], %other -; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i32> %other, <2 x i32> [[POSITIVE]] -; CHECK-NEXT: [[TEST:%.*]] = icmp sgt <2 x i32> [[SEL]], zeroinitializer +; CHECK-NEXT: [[TEST:%.*]] = icmp sgt <2 x i32> %other, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[TEST]] ; %notneg = and <2 x i32> %x, %positive = or <2 x i32> %notneg, - %cmp = icmp slt <2 x i32> %positive, %other + %cmp = icmp slt <2 x i32> %other, %positive %sel = select <2 x i1> %cmp, <2 x i32> %other, <2 x i32> %positive %test = icmp sgt <2 x i32> %sel, zeroinitializer ret <2 x i1> %test