[llvm] [AMDGPU][CodeGen] Allow remat with multiple users in multiple regions (PR #215598)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 13 06:02:30 PDT 2026


================
@@ -3048,6 +3025,66 @@ bool PreRARematStage::setObjective() {
   return TargetRegions.any();
 }
 
+bool PreRARematStage::candidateHasValidUsers(
+    RegisterIdx CandIdx, const SmallSet<Register, 4> &MarkedRegs) const {
+  const SIRegisterInfo &TRI = *ST.getRegisterInfo();
+  const RegisterBankInfo &RBI = *ST.getRegBankInfo();
+
+  const Rematerializer::Reg &CandReg = Remater.getReg(CandIdx);
+  SlotIndex RefIdx =
+      DAG.LIS->getInstructionIndex(*CandReg.getLastDef()).getRegSlot(true);
+  const MachineBasicBlock *DefMBB =
+      DAG.Regions[CandReg.DefRegion].first->getParent();
+
+  for (const auto &[UseRegion, Users] : CandReg.Uses) {
+    // A convergent user (e.g., V_READLANE*) of a vector register may observe
+    // lanes of the definition that are active in the definition's region but
+    // inactive at the user's region. Rematerialization could therefore change
+    // what the user reads, which is invalid. EXEC doesn't change within a block
+    // so a rematerialization across regions belonging to the same block is
+    // safe.
+    Register DefReg = CandReg.getDefReg();
+    const bool ConvergentUserForbidden =
+        !TRI.isUniformReg(DAG.MRI, RBI, DefReg) &&
+        DefMBB != DAG.Regions[UseRegion].first->getParent();
+
+    // Users cannot be rematerializable or, conditionally, convergent.
+    if (llvm::any_of(Users, [&](const MachineInstr *UserMI) {
+          assert(UserMI->getNumOperands() > 0 &&
+                 "user must have at least one operand");
+          const MachineOperand &UseMO = UserMI->getOperand(0);
----------------
arsenm wrote:

I don't understand the hardcoded operand 0, won't that usually be its def?

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


More information about the llvm-commits mailing list