[llvm] [Uniformity] Implement per-output machine uniformity analysis (PR #179275)

Sameer Sahasrabuddhe via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 3 01:02:20 PST 2026


================
@@ -46,24 +46,86 @@ bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::markDefsDivergent(
   return insertedDivergent;
 }
 
+template <>
+bool llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::isAlwaysUniform(
+    const MachineInstr &Instr) const {
+  // For MIR, an instruction is "always uniform" only if it has at least one
+  // virtual register def AND all those defs are in UniformOverrides.
+  // Instructions with no virtual register defs (e.g., terminators like
+  // G_BRCOND, G_BR) return false to ensure they can be properly processed
+  // for divergence during propagation.
+  bool HasVirtualDef = false;
+  for (const MachineOperand &Op : Instr.all_defs()) {
+    if (!Op.getReg().isVirtual())
+      continue;
+    HasVirtualDef = true;
+    if (!UniformOverrides.contains(Op.getReg()))
+      return false;
+  }
+  // Only return true if we found at least one virtual def and all were uniform
+  return HasVirtualDef;
+}
+
 template <>
 void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::initialize() {
-  const auto &InstrInfo = *F.getSubtarget().getInstrInfo();
-
-  for (const MachineBasicBlock &block : F) {
-    for (const MachineInstr &instr : block) {
-      auto uniformity = InstrInfo.getInstructionUniformity(instr);
-
-      switch (uniformity) {
-      case InstructionUniformity::AlwaysUniform:
-        addUniformOverride(instr);
-        break;
-      case InstructionUniformity::NeverUniform:
-        markDivergent(instr);
-        break;
-      case InstructionUniformity::Default:
-        break;
+  const TargetInstrInfo &InstrInfo = *F.getSubtarget().getInstrInfo();
+  const MachineRegisterInfo &MRI = F.getRegInfo();
+  const RegisterBankInfo &RBI = *F.getSubtarget().getRegBankInfo();
+  const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
+
+  for (const MachineBasicBlock &Block : F) {
+    for (const MachineInstr &Instr : Block) {
+      // Terminators are handled separately because:
+      // 1. Many terminators (G_BRCOND, G_BR) have no def operands, so the
+      //    per-def loop below would skip them entirely.
+      // 2. Divergent terminators mark the BLOCK as divergent
+      // (DivergentTermBlocks),
----------------
ssahasra wrote:

Fix indentation. Probably meant to be on the line above?

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


More information about the llvm-commits mailing list