[llvm] [SPIRV][Matrix] Change Matrix Shader legalization to largest common divisor (PR #207768)

Diego Novillo via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 07:13:32 PDT 2026


================
@@ -715,6 +757,143 @@ static bool legalizeStore(LegalizerHelper &Helper, MachineInstr &MI,
   return true;
 }
 
+// Lowers wide G_SHUFFLE_VECTORs into legal-width chunked OpVectorShuffles
+// instead of scalarizing. Unmerge/concat artifacts fold away naturally.
+// Requires shader targets and matching chunk widths (see shuffleChunkable).
+static bool legalizeShuffleVector(LegalizerHelper &Helper, MachineInstr &MI,
+                                  SPIRVGlobalRegistry *GR) {
+  MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
+  MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
+  Register DstReg = MI.getOperand(0).getReg();
+
+  // Chunk-vectorize wide shuffles unless feeding a G_STORE or scalar
+  // G_UNMERGE_VALUES. Exception: Keep vectorizing if the unmerge directly
+  // feeds a G_BUILD_VECTOR.
+  if (!MRI.use_nodbg_empty(DstReg)) {
+    auto IsScatterUse = [&](MachineInstr &Use) {
+      if (Use.getOpcode() == TargetOpcode::G_STORE)
+        return true;
+      if (Use.getOpcode() == TargetOpcode::G_UNMERGE_VALUES &&
+          MRI.getType(Use.getOperand(0).getReg()).isScalar()) {
+        for (const MachineOperand &Def : Use.defs())
+          for (MachineInstr &U : MRI.use_nodbg_instructions(Def.getReg()))
+            if (U.getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
+                U.getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC)
+              return false;
+        return true;
+      }
+      return false;
+    };
+    bool AllScatter = true;
+    for (MachineInstr &Use : MRI.use_nodbg_instructions(DstReg)) {
+      if (!IsScatterUse(Use)) {
+        AllScatter = false;
+        break;
+      }
+    }
+    if (AllScatter)
----------------
dnovillo wrote:

I think the spec says to fall back to scalar if feeding _only_ scatter stores. In here we seem to return false at the first G_BUILD_VECTOR consumer we find. Shouldn't this return true only when every def of the G_UNMERGE_VALUES fees a G_STORE?

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


More information about the llvm-commits mailing list