[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: Temporal divergence lowering (non i1) (PR #124298)

Nicolai Hähnle via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jan 30 04:05:34 PST 2025


================
@@ -188,6 +190,37 @@ void DivergenceLoweringHelper::constrainAsLaneMask(Incoming &In) {
   In.Reg = Copy.getReg(0);
 }
 
+void replaceUsesOfRegInInstWith(Register Reg, MachineInstr *Inst,
+                                Register NewReg) {
+  for (MachineOperand &Op : Inst->operands()) {
+    if (Op.isReg() && Op.getReg() == Reg)
+      Op.setReg(NewReg);
+  }
+}
+
+bool DivergenceLoweringHelper::lowerTempDivergence() {
+  AMDGPU::IntrinsicLaneMaskAnalyzer ILMA(*MF);
+
+  for (auto [Inst, UseInst, _] : MUI->getUsesOutsideCycleWithDivergentExit()) {
+    Register Reg = Inst->getOperand(0).getReg();
+    if (MRI->getType(Reg) == LLT::scalar(1) || MUI->isDivergent(Reg) ||
+        ILMA.isS32S64LaneMask(Reg))
+      continue;
+
+    MachineInstr *MI = const_cast<MachineInstr *>(Inst);
----------------
nhaehnle wrote:

These come out of the analysis. The analysis itself uses const pointers/references in its implementation, which I believe is a good idea for const correctness. I wouldn't change that.

So a `const_cast` is needed at some point. The only question is where.

I think here is as good a place as any, though perhaps grouping them together with a small explanation is in order. Something like:
```c++
    // As an analysis, UniformityAnalysis treats instructions as const. We have the parent function
    // as non-const, so casting const away here is inelegant but justified.
    MachineInstr *MI = const_cast<MachineInstr *>(Inst);
    MachineInstr *UseMI = const_cast<MachineInstr *>(UseInst);
```

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


More information about the llvm-branch-commits mailing list