[llvm] [LICM] Allow hoisting of InsertElementInst's past non-hoistable InsertElementInsts (PR #200532)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 8 06:10:11 PDT 2026
================
@@ -1058,6 +1074,82 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI,
return Changed;
}
+static InsertElementInst *canBypassInsert(InsertElementInst *CurrIns,
+ Loop *CurLoop,
+ SmallSet<uint64_t, 4> &SeenIndices) {
+ // Must have constant insertion lane
+ auto *InsertedIdxCI = dyn_cast<ConstantInt>(CurrIns->getOperand(2));
+ if (!InsertedIdxCI)
+ return nullptr;
+ auto *VecTy = cast<VectorType>(CurrIns->getType());
+
+ // Avoid hoisting past out of bounds inserts
+ if (InsertedIdxCI->isNegative() ||
+ InsertedIdxCI->getValue().uge(
+ VecTy->getElementCount().getKnownMinValue()))
+ return nullptr;
+
+ // Make sure not hoisting past insertions into the same lane
+ if (!SeenIndices.insert(InsertedIdxCI->getValue().getLimitedValue()).second)
+ return nullptr;
+
+ Value *InnerVal = CurrIns->getOperand(0);
+ // If the value we are inserting into is not invariant/poison, recurse
+ // if it is another insert
+ if (!CurLoop->isLoopInvariant(InnerVal) && !isa<PoisonValue>(InnerVal)) {
+ // Only hoist past other insertions
+ // All instructions in the chain must be in the same basic block
+ auto *InnerIns = dyn_cast<InsertElementInst>(InnerVal);
+ if (!InnerIns || InnerIns->getParent() != CurrIns->getParent())
+ return nullptr;
+
+ // Instruction being hoisted past must only have one use
+ if (!InnerIns->hasOneUse())
+ return nullptr;
+
+ return canBypassInsert(InnerIns, CurLoop, SeenIndices);
----------------
nikic wrote:
It seems like it should be straightforward to make this iterative rather than recursive?
https://github.com/llvm/llvm-project/pull/200532
More information about the llvm-commits
mailing list