From cbca9ce91c6440f8815742b8a73a27aa81e806e6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 31 Mar 2023 13:46:16 +0200 Subject: [PATCH] [InstCombine] Remove min/max special case when folding into select Now that we canonicalize to min/max intrinsics, we no longer need to guard against this here. In fact, it seems like the issue from PR46271 was the final push for introducing the intrinsics in the first place... --- .../InstCombine/InstructionCombining.cpp | 39 ---------------------- llvm/test/Transforms/InstCombine/minmax-fold.ll | 7 ++-- 2 files changed, 3 insertions(+), 43 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index a730752..de653a5 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1082,45 +1082,6 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI, return nullptr; } - // Test if a CmpInst instruction is used exclusively by a select as - // part of a minimum or maximum operation. If so, refrain from doing - // any other folding. This helps out other analyses which understand - // non-obfuscated minimum and maximum idioms, such as ScalarEvolution - // and CodeGen. And in this case, at least one of the comparison - // operands has at least one user besides the compare (the select), - // which would often largely negate the benefit of folding anyway. - if (auto *CI = dyn_cast(SI->getCondition())) { - if (CI->hasOneUse()) { - Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1); - - // FIXME: This is a hack to avoid infinite looping with min/max patterns. - // We have to ensure that vector constants that only differ with - // undef elements are treated as equivalent. - auto areLooselyEqual = [](Value *A, Value *B) { - if (A == B) - return true; - - // Test for vector constants. - Constant *ConstA, *ConstB; - if (!match(A, m_Constant(ConstA)) || !match(B, m_Constant(ConstB))) - return false; - - // TODO: Deal with FP constants? - if (!A->getType()->isIntOrIntVectorTy() || A->getType() != B->getType()) - return false; - - // Compare for equality including undefs as equal. - auto *Cmp = ConstantExpr::getCompare(ICmpInst::ICMP_EQ, ConstA, ConstB); - const APInt *C; - return match(Cmp, m_APIntAllowUndef(C)) && C->isOne(); - }; - - if ((areLooselyEqual(TV, Op0) && areLooselyEqual(FV, Op1)) || - (areLooselyEqual(FV, Op0) && areLooselyEqual(TV, Op1))) - return nullptr; - } - } - // Make sure that one of the select arms constant folds successfully. Value *NewTV = constantFoldOperationIntoSelectOperand(Op, SI, TV); Value *NewFV = constantFoldOperationIntoSelectOperand(Op, SI, FV); diff --git a/llvm/test/Transforms/InstCombine/minmax-fold.ll b/llvm/test/Transforms/InstCombine/minmax-fold.ll index a067c1e..b67c0f2 100644 --- a/llvm/test/Transforms/InstCombine/minmax-fold.ll +++ b/llvm/test/Transforms/InstCombine/minmax-fold.ll @@ -1361,10 +1361,9 @@ define i8 @PR14613_smax(i8 %x) { define i8 @PR46271(<2 x i8> %x) { ; CHECK-LABEL: @PR46271( -; CHECK-NEXT: [[A:%.*]] = icmp sgt <2 x i8> [[X:%.*]], -; CHECK-NEXT: [[B:%.*]] = select <2 x i1> [[A]], <2 x i8> [[X]], <2 x i8> -; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x i8> [[B]], i64 1 -; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP1]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[X:%.*]], <2 x i8> ) +; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x i8> [[TMP1]], i64 1 +; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP2]], -1 ; CHECK-NEXT: ret i8 [[R]] ; %a = icmp sgt <2 x i8> %x, -- 2.7.4