[llvm] [AMDGPU][GlobalISel] Eliminate READANYLANE round trips in mixed build_vector/merge (PR #210449)

Petar Avramovic via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 28 06:26:08 PDT 2026


================
@@ -575,6 +588,76 @@ bool AMDGPURegBankCombinerImpl::matchMinMaxToMinMax3(
   return true;
 }
 
+// Sgpr0 = G_AMDGPU_READANYLANE Vgpr0
+// Src = G_MERGE_LIKE Sgpr0, Sgpr1, ...
+// Dst = COPY Src
+// ->
+// Vgpr1 = COPY Sgpr1
+// Dst = G_MERGE_LIKE Vgpr0, Vgpr1, ...
+//
+// Merge sources that are not readanylanes have to be uniform, copying them to a
+// vgpr is a broadcast. Requires at least one readanylane source, otherwise this
+// would only move the copy from the merge result to its sources.
+bool AMDGPURegBankCombinerImpl::matchMergeReadAnyLaneToVgpr(
+    MachineInstr &Copy, SmallVector<Register> &Srcs) const {
+  Register Dst = Copy.getOperand(0).getReg();
+  Register Src = Copy.getOperand(1).getReg();
+
+  if (!isVgprRegBank(Dst))
+    return false;
+
+  // Skip physical source registers and source registers with register class.
+  if (!Src.isVirtual() || MRI.getRegClassOrNull(Src))
+    return false;
+
+  auto *Merge = getOpcodeDef<GMergeLikeInstr>(Src, MRI);
+  if (!Merge)
+    return false;
+
+  bool SawReadAnyLane = false;
+  for (unsigned I = 0; I < Merge->getNumSources(); ++I) {
+    Register MergeSrc = Merge->getSourceReg(I);
+    if (!MergeSrc.isVirtual())
+      return false;
+
+    MachineInstr *MergeSrcMI = MRI.getVRegDef(MergeSrc);
+    if (MergeSrcMI->getOpcode() == AMDGPU::G_AMDGPU_READANYLANE) {
+      Srcs.push_back(MergeSrcMI->getOperand(1).getReg());
+      SawReadAnyLane = true;
+      continue;
+    }
+
+    if (isSgprRegBank(MergeSrc)) {
+      Srcs.push_back(MergeSrc);
+      continue;
+    }
+
+    return false;
+  }
+
+  return SawReadAnyLane;
+}
+
+void AMDGPURegBankCombinerImpl::applyMergeReadAnyLaneToVgpr(
+    MachineInstr &Copy, SmallVector<Register> &Srcs) const {
+  const RegisterBank &VgprRB = RBI.getRegBank(AMDGPU::VGPRRegBankID);
+  for (Register &Src : Srcs) {
+    if (!isVgprRegBank(Src))
+      Src = B.buildCopy({&VgprRB, MRI.getType(Src)}, Src).getReg(0);
+  }
+
+  Register Dst = Copy.getOperand(0).getReg();
+  if (Dst.isVirtual()) {
+    B.buildMergeLikeInstr(Dst, Srcs);
+  } else {
+    LLT Ty = MRI.getType(Copy.getOperand(1).getReg());
----------------
petar-avramovic wrote:

this is very unlikely to happen ? what would it even be, copy sgpr vreg to physical vgpr? that should be invalid copy

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


More information about the llvm-commits mailing list