[llvm] [AMDGPU] Merge 32-bit VGPR copies into 64-bit copies (PR #193270)
Steffen Larsen via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 30 07:17:32 PDT 2026
================
@@ -0,0 +1,186 @@
+//===-- SIMergeVGPRCopies.cpp - Merge adjacent VGPR copies ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Merge adjacent 32-bit copy-to-VGPR pairs into a single 64-bit copy
+/// (V_PK_MOV_B32 or V_MOV_B64).
+///
+/// Both sources and destinations must be consecutive and even-aligned, but the
+/// source and destination pairs can be in either order. The sources can be
+/// SGPRs if the target supports V_MOV_B64, but not if the merged copy needs to
+/// use V_PK_MOV_B32 (e.g. if the source pairs are inversed relative to the
+/// destinations).
+///
+/// This runs after register allocation, when all registers are physical and
+/// before ExpandPostRAPseudos lowers each copy individually.
+///
+//===----------------------------------------------------------------------===//
+
+#include "SIMergeVGPRCopies.h"
+#include "AMDGPU.h"
+#include "GCNSubtarget.h"
+#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "si-merge-vgpr-copies"
+
+namespace {
+
+class SIMergeVGPRCopiesLegacy : public MachineFunctionPass {
+public:
+ static char ID;
+
+ SIMergeVGPRCopiesLegacy() : MachineFunctionPass(ID) {}
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ StringRef getPassName() const override { return "SI Merge VGPR copies"; }
+};
+
+class SIMergeVGPRCopies {
+public:
+ bool run(MachineFunction &MF);
+};
+
+} // End anonymous namespace.
+
+INITIALIZE_PASS(SIMergeVGPRCopiesLegacy, DEBUG_TYPE, "SI Merge VGPR copies",
+ false, false)
+
+char SIMergeVGPRCopiesLegacy::ID = 0;
+
+char &llvm::SIMergeVGPRCopiesID = SIMergeVGPRCopiesLegacy::ID;
+
+PreservedAnalyses SIMergeVGPRCopiesPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &) {
+ SIMergeVGPRCopies().run(MF);
+ return PreservedAnalyses::all();
+}
+
+bool SIMergeVGPRCopiesLegacy::runOnMachineFunction(MachineFunction &MF) {
+ return SIMergeVGPRCopies().run(MF);
+}
+
+static bool getBaseIfConsecutive(const Register &Reg1, const Register &Reg2,
+ const SIRegisterInfo *TRI, Register &Base) {
+ long Dist =
+ static_cast<long>(TRI->getHWRegIndex(Reg2)) - TRI->getHWRegIndex(Reg1);
+ if (std::abs(Dist) != 1)
+ return false;
+ Base = (Dist == 1) ? Reg1 : Reg2;
+ return true;
+}
+
+bool SIMergeVGPRCopies::run(MachineFunction &MF) {
+ const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
+ // Only merge when the target has a 64-bit move instruction. Skip targets
+ // with VOPD: GCNCreateVOPD runs later and can pair 32-bit moves with
+ // unrelated instructions, which is potentially better than v_mov_b64.
----------------
steffenlarsen wrote:
It did require a slight change to the instruction it looks for (as COPY has been replaced by the time GCNCreateVOPD is hit) but it now runs after.
https://github.com/llvm/llvm-project/pull/193270
More information about the llvm-commits
mailing list