[llvm-branch-commits] [llvm] AMDGPU/GlobalISel: Improve readanylane combines in regbanklegalize (PR #142789)

Pierre van Houtryve via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jun 5 01:14:55 PDT 2025


================
@@ -137,7 +138,123 @@ class AMDGPURegBankLegalizeCombiner {
     return {MatchMI, MatchMI->getOperand(1).getReg()};
   }
 
+  std::tuple<GUnmerge *, int> tryMatchRALFromUnmerge(Register Src) {
+    auto *ReadAnyLane = MRI.getVRegDef(Src);
+    if (ReadAnyLane->getOpcode() == AMDGPU::G_AMDGPU_READANYLANE) {
+      Register RALSrc = ReadAnyLane->getOperand(1).getReg();
+      auto *UnMerge = getOpcodeDef<GUnmerge>(RALSrc, MRI);
+      if (UnMerge)
+        return {UnMerge, UnMerge->findRegisterDefOperandIdx(RALSrc, nullptr)};
+    }
+    return {nullptr, -1};
+  }
+
+  Register getReadAnyLaneSrc(Register Src) {
+    // Src = G_AMDGPU_READANYLANE RALSrc
+    auto [RAL, RALSrc] = tryMatch(Src, AMDGPU::G_AMDGPU_READANYLANE);
+    if (RAL)
+      return RALSrc;
+
+    // LoVgpr, HiVgpr = G_UNMERGE_VALUES UnmergeSrc
+    // LoSgpr = G_AMDGPU_READANYLANE LoVgpr
+    // HiSgpr = G_AMDGPU_READANYLANE HiVgpr
+    // Src G_MERGE_VALUES LoSgpr, HiSgpr
+    auto *Merge = getOpcodeDef<GMergeLikeInstr>(Src, MRI);
+    if (Merge) {
+      unsigned NumElts = Merge->getNumSources();
+      auto [Unmerge, Idx] = tryMatchRALFromUnmerge(Merge->getSourceReg(0));
+      if (!Unmerge || Unmerge->getNumDefs() != NumElts || Idx != 0)
+        return {};
+
+      // check if all elements are from same unmerge and there is no shuffling
+      for (unsigned i = 1; i < NumElts; ++i) {
+        auto [UnmergeI, IdxI] = tryMatchRALFromUnmerge(Merge->getSourceReg(i));
+        if (UnmergeI != Unmerge || (unsigned)IdxI != i)
+          return {};
+      }
+      return Unmerge->getSourceReg();
+    }
+
+    // ..., VgprI, ... = G_UNMERGE_VALUES VgprLarge
+    // SgprI = G_AMDGPU_READANYLANE VgprI
+    // SgprLarge G_MERGE_VALUES ..., SgprI, ...
+    // ..., Src, ... = G_UNMERGE_VALUES SgprLarge
+    auto *UnMerge = getOpcodeDef<GUnmerge>(Src, MRI);
+    if (UnMerge) {
+      int Idx = UnMerge->findRegisterDefOperandIdx(Src, nullptr);
+      auto *Merge = getOpcodeDef<GMergeLikeInstr>(UnMerge->getSourceReg(), MRI);
+      if (Merge) {
+        auto [RAL, RALSrc] =
+            tryMatch(Merge->getSourceReg(Idx), AMDGPU::G_AMDGPU_READANYLANE);
+        if (RAL)
+          return RALSrc;
+      }
+    }
+
+    return {};
+  }
+
+  bool tryEliminateReadAnyLane(MachineInstr &Copy) {
+    Register Dst = Copy.getOperand(0).getReg();
+    Register Src = Copy.getOperand(1).getReg();
+    if (!Src.isVirtual())
+      return false;
+
+    Register RALDst = Src;
+    MachineInstr &SrcMI = *MRI.getVRegDef(Src);
+    if (SrcMI.getOpcode() == AMDGPU::G_BITCAST) {
+      RALDst = SrcMI.getOperand(1).getReg();
+    }
----------------
Pierre-vh wrote:

```suggestion
    if (SrcMI.getOpcode() == AMDGPU::G_BITCAST) 
      RALDst = SrcMI.getOperand(1).getReg();
```

nit: can we have other opcodes than bitcast and that'd matter, like inreg extensions, assert exts ?
It feels like we should have a helper for this somewhere

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


More information about the llvm-branch-commits mailing list