[llvm-branch-commits] [llvm] [CodeGen] Fix incorrect rematerialization order in rematerializer (PR #189485)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Apr 6 06:02:11 PDT 2026


================
@@ -94,40 +94,27 @@ Rematerializer::rematerializeToPos(RegisterIdx RootIdx, unsigned UseRegion,
   assert(!DRI.DependencyMap.contains(RootIdx));
   LLVM_DEBUG(dbgs() << "Rematerializing " << printID(RootIdx) << '\n');
 
-  // Traverse the root's dependency DAG depth-first to find the set of
-  // registers we must rematerialize along with it and a legal order to
-  // rematerialize them in.
-  SmallVector<RegisterIdx, 4> DepDAG{RootIdx};
-  SmallSetVector<RegisterIdx, 8> RematOrder;
-  RematOrder.insert(RootIdx);
-  do {
-    RegisterIdx RegIdx = DepDAG.pop_back_val();
-    for (const Reg::Dependency &Dep : getReg(RegIdx).Dependencies) {
-      // The dependency may already have a rematerialization ready to use.
-      if (DRI.DependencyMap.contains(Dep.RegIdx))
-        continue;
-      // We may have already seen the dependency in the dependency DAG.
-      if (RematOrder.contains(Dep.RegIdx))
-        continue;
-      DepDAG.push_back(Dep.RegIdx);
-      RematOrder.insert(Dep.RegIdx);
+  std::function<RegisterIdx(RegisterIdx)> Remat = [&](RegisterIdx RegIdx) {
+    SmallVector<Reg::Dependency, 2> NewDeps;
+    // Copy all dependencies because recursive rematerialization of dependencies
+    // may invalidate references to the backing vector of registers.
+    SmallVector<Reg::Dependency, 2> OldDeps(getReg(RegIdx).Dependencies);
+    for (const Reg::Dependency &Dep : OldDeps) {
+      // Recursively rematerialize required dependencies at the same position as
+      // the root. Registers form a DAG so the recursion is guaranteed to
+      // terminate.
+      auto RematIdx = DRI.DependencyMap.find(Dep.RegIdx);
+      if (RematIdx == DRI.DependencyMap.end())
+        NewDeps.emplace_back(Dep.MOIdx, Remat(Dep.RegIdx));
+      else
+        NewDeps.emplace_back(Dep.MOIdx, DRI.DependencyMap.at(Dep.RegIdx));
     }
-  } while (!DepDAG.empty());
-
-  // Rematerialize all necessary registers in the root's dependency DAG. At each
-  // rematerialization, dependencies should already be available.
-  RegisterIdx LastNewIdx;
-  for (RegisterIdx RegIdx : reverse(RematOrder)) {
-    assert(!DRI.DependencyMap.contains(RegIdx) && "useless remat");
-    SmallVector<Reg::Dependency, 2> Dependencies;
-    for (const Reg::Dependency &Dep : getReg(RegIdx).Dependencies)
-      Dependencies.emplace_back(Dep.MOIdx, DRI.DependencyMap.at(Dep.RegIdx));
-    LastNewIdx =
-        rematerializeReg(RegIdx, UseRegion, InsertPos, std::move(Dependencies));
-    DRI.DependencyMap.insert({RegIdx, LastNewIdx});
-  }
-
-  return LastNewIdx;
+    RegisterIdx NewIdx =
+        rematerializeReg(RegIdx, UseRegion, InsertPos, std::move(NewDeps));
+    DRI.DependencyMap.insert({RegIdx, NewIdx});
+    return NewIdx;
+  };
+  return Remat(RootIdx);
----------------
arsenm wrote:

Don't use a lambda you just immediately call? Recursive lambda is weird, move to a proper function? 

https://github.com/llvm/llvm-project/pull/189485


More information about the llvm-branch-commits mailing list