[llvm] b457ac4 - [InstCombine] Extract icmp of select transform (NFC)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri May 6 05:46:51 PDT 2022
Author: Nikita Popov
Date: 2022-05-06T14:46:44+02:00
New Revision: b457ac42406fbb5d826a321942e99ba4ef860115
URL: https://github.com/llvm/llvm-project/commit/b457ac42406fbb5d826a321942e99ba4ef860115
DIFF: https://github.com/llvm/llvm-project/commit/b457ac42406fbb5d826a321942e99ba4ef860115.diff
LOG: [InstCombine] Extract icmp of select transform (NFC)
To make it either to extend to the case where the other operand
is not a constant.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/lib/Transforms/InstCombine/InstCombineInternal.h
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 39a32e526d714..dc4849b045921 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3422,64 +3422,6 @@ Instruction *InstCombinerImpl::foldICmpInstWithConstantNotInt(ICmpInst &I) {
if (Instruction *NV = foldOpIntoPhi(I, cast<PHINode>(LHSI)))
return NV;
break;
- case Instruction::Select: {
- // If either operand of the select is a constant, we can fold the
- // comparison into the select arms, which will cause one to be
- // constant folded and the select turned into a bitwise or.
- Value *Op1 = nullptr, *Op2 = nullptr;
- ConstantInt *CI = nullptr;
-
- auto SimplifyOp = [&](Value *V) {
- Value *Op = nullptr;
- if (Constant *C = dyn_cast<Constant>(V)) {
- Op = ConstantExpr::getICmp(I.getPredicate(), C, RHSC);
- } else if (RHSC->isNullValue()) {
- // If null is being compared, check if it can be further simplified.
- Op = SimplifyICmpInst(I.getPredicate(), V, RHSC, SQ);
- }
- return Op;
- };
- Op1 = SimplifyOp(LHSI->getOperand(1));
- if (Op1)
- CI = dyn_cast<ConstantInt>(Op1);
-
- Op2 = SimplifyOp(LHSI->getOperand(2));
- if (Op2)
- CI = dyn_cast<ConstantInt>(Op2);
-
- // We only want to perform this transformation if it will not lead to
- // additional code. This is true if either both sides of the select
- // fold to a constant (in which case the icmp is replaced with a select
- // which will usually simplify) or this is the only user of the
- // select (in which case we are trading a select+icmp for a simpler
- // select+icmp) or all uses of the select can be replaced based on
- // dominance information ("Global cases").
- bool Transform = false;
- if (Op1 && Op2)
- Transform = true;
- else if (Op1 || Op2) {
- // Local case
- if (LHSI->hasOneUse())
- Transform = true;
- // Global cases
- else if (CI && !CI->isZero())
- // When Op1 is constant try replacing select with second operand.
- // Otherwise Op2 is constant and try replacing select with first
- // operand.
- Transform =
- replacedSelectWithOperand(cast<SelectInst>(LHSI), &I, Op1 ? 2 : 1);
- }
- if (Transform) {
- if (!Op1)
- Op1 = Builder.CreateICmp(I.getPredicate(), LHSI->getOperand(1), RHSC,
- I.getName());
- if (!Op2)
- Op2 = Builder.CreateICmp(I.getPredicate(), LHSI->getOperand(2), RHSC,
- I.getName());
- return SelectInst::Create(LHSI->getOperand(0), Op1, Op2);
- }
- break;
- }
case Instruction::IntToPtr:
// icmp pred inttoptr(X), null -> icmp pred X, 0
if (RHSC->isNullValue() &&
@@ -3503,6 +3445,68 @@ Instruction *InstCombinerImpl::foldICmpInstWithConstantNotInt(ICmpInst &I) {
return nullptr;
}
+Instruction *InstCombinerImpl::foldSelectICmp(ICmpInst::Predicate Pred,
+ SelectInst *SI, Value *RHS,
+ const ICmpInst &I) {
+ // If either operand of the select is a constant, we can fold the
+ // comparison into the select arms, which will cause one to be
+ // constant folded and the select turned into a bitwise or.
+ auto *RHSC = dyn_cast<Constant>(RHS);
+ if (!RHSC)
+ return nullptr;
+
+ auto SimplifyOp = [&](Value *V) {
+ Value *Op = nullptr;
+ if (Constant *C = dyn_cast<Constant>(V)) {
+ Op = ConstantExpr::getICmp(Pred, C, RHSC);
+ } else if (RHSC->isNullValue()) {
+ // If null is being compared, check if it can be further simplified.
+ Op = SimplifyICmpInst(Pred, V, RHSC, SQ);
+ }
+ return Op;
+ };
+
+ ConstantInt *CI = nullptr;
+ Value *Op1 = SimplifyOp(SI->getOperand(1));
+ if (Op1)
+ CI = dyn_cast<ConstantInt>(Op1);
+
+ Value *Op2 = SimplifyOp(SI->getOperand(2));
+ if (Op2)
+ CI = dyn_cast<ConstantInt>(Op2);
+
+ // We only want to perform this transformation if it will not lead to
+ // additional code. This is true if either both sides of the select
+ // fold to a constant (in which case the icmp is replaced with a select
+ // which will usually simplify) or this is the only user of the
+ // select (in which case we are trading a select+icmp for a simpler
+ // select+icmp) or all uses of the select can be replaced based on
+ // dominance information ("Global cases").
+ bool Transform = false;
+ if (Op1 && Op2)
+ Transform = true;
+ else if (Op1 || Op2) {
+ // Local case
+ if (SI->hasOneUse())
+ Transform = true;
+ // Global cases
+ else if (CI && !CI->isZero())
+ // When Op1 is constant try replacing select with second operand.
+ // Otherwise Op2 is constant and try replacing select with first
+ // operand.
+ Transform = replacedSelectWithOperand(SI, &I, Op1 ? 2 : 1);
+ }
+ if (Transform) {
+ if (!Op1)
+ Op1 = Builder.CreateICmp(Pred, SI->getOperand(1), RHSC, I.getName());
+ if (!Op2)
+ Op2 = Builder.CreateICmp(Pred, SI->getOperand(2), RHSC, I.getName());
+ return SelectInst::Create(SI->getOperand(0), Op1, Op2);
+ }
+
+ return nullptr;
+}
+
/// Some comparisons can be simplified.
/// In this case, we are looking for comparisons that look like
/// a check for a lossy truncation.
@@ -6109,6 +6113,10 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
if (Instruction *NI = foldGEPICmp(GEP, Op0, I.getSwappedPredicate(), I))
return NI;
+ if (auto *SI = dyn_cast<SelectInst>(Op0))
+ if (Instruction *NI = foldSelectICmp(I.getPredicate(), SI, Op1, I))
+ return NI;
+
// Try to optimize equality comparisons against alloca-based pointers.
if (Op0->getType()->isPointerTy() && I.isEquality()) {
assert(Op1->getType()->isPointerTy() && "Comparing pointer with non-pointer?");
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 7637cb4a40ee6..ae47c0727ee75 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -655,6 +655,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
Instruction *foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
ICmpInst::Predicate Cond, Instruction &I);
+ Instruction *foldSelectICmp(ICmpInst::Predicate Pred, SelectInst *SI,
+ Value *RHS, const ICmpInst &I);
Instruction *foldAllocaCmp(ICmpInst &ICI, const AllocaInst *Alloca);
Instruction *foldCmpLoadFromIndexedGlobal(LoadInst *LI,
GetElementPtrInst *GEP,
More information about the llvm-commits
mailing list