[llvm] Reland "[LICM] Sink unused l-invariant loads in preheader #157559" (PR #170204)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 16 01:37:56 PDT 2026
================
@@ -1560,6 +1572,181 @@ static void moveInstructionBefore(Instruction &I, BasicBlock::iterator Dest,
SE->forgetBlockAndLoopDispositions(&I);
}
+// If there's a single exit block, sink any loop-invariant values that were
+// defined in the preheader but not used inside the loop into the exit block
+// to reduce register pressure in the loop.
+static bool sinkUnusedInvariantsFromPreheaderToExit(
+ Loop *L, AAResults *AA, ICFLoopSafetyInfo *SafetyInfo,
+ MemorySSAUpdater &MSSAU, ScalarEvolution *SE, DominatorTree *DT,
+ SinkAndHoistLICMFlags &SinkFlags) {
+ BasicBlock *ExitBlock = L->getExitBlock();
+ if (!ExitBlock)
+ return false;
+
+ BasicBlock *Preheader = L->getLoopPreheader();
+ if (!Preheader)
+ return false;
+
+ // Collect instructions that are safe to sink and have no in-loop users.
+ SmallPtrSet<Instruction *, 16> LegalToSink;
+ for (Instruction &I : llvm::reverse(*Preheader)) {
+ if (I.isTerminator())
+ continue;
+
+ // New instructions were inserted at the end of the preheader.
+ if (isa<PHINode>(I))
+ break;
+
+ // Don't move instructions which might have side effects, since the side
+ // effects need to complete before instructions inside the loop. Note that
+ // it's okay if the instruction might have undefined behavior: LoopSimplify
+ // guarantees that the preheader dominates the exit block.
----------------
nikic wrote:
This is not really related to LoopSimplify, but part of the definition of a loop preheader (as opposed to a loop predecessor).
https://github.com/llvm/llvm-project/pull/170204
More information about the llvm-commits
mailing list