[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