[llvm] 4b8b168 - [AMDGPU] Add getRegisterByName support for src_flat_scratch_base (#220560)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 9 02:27:07 PDT 2026


Author: Andreas Leitner
Date: 2026-09-09T11:27:02+02:00
New Revision: 4b8b168e8b6897fe3816949a316002ee8aff2e98

URL: https://github.com/llvm/llvm-project/commit/4b8b168e8b6897fe3816949a316002ee8aff2e98
DIFF: https://github.com/llvm/llvm-project/commit/4b8b168e8b6897fe3816949a316002ee8aff2e98.diff

LOG: [AMDGPU] Add getRegisterByName support for src_flat_scratch_base (#220560)

Expose `src_flat_scratch_base`, `src_flat_scratch_base_lo`, and
`src_flat_scratch_base_hi` through `llvm.read_register` /
`llvm.write_register`.

The implementation is basically the same as the existing named-register
support for `flat_scratch`

It errors out on targets without `FeatureGloballyAddressableScratch`
(pre-gfx1250).

Added: 
    llvm/test/CodeGen/AMDGPU/read-register-src-flat-scratch-base.ll
    llvm/test/CodeGen/AMDGPU/read-write-register-src-flat-scratch-base-invalid-subtarget.ll
    llvm/test/CodeGen/AMDGPU/type-mismatch-src-flat-scratch-base.ll
    llvm/test/CodeGen/AMDGPU/write-register-src-flat-scratch-base.ll

Modified: 
    llvm/lib/Target/AMDGPU/SIISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 4a3c9258f1770..deba185580571 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -5074,15 +5074,19 @@ Register SITargetLowering::getRegisterByName(const char *RegName, LLT VT,
                                              const MachineFunction &MF) const {
   const Function &Fn = MF.getFunction();
 
-  Register Reg = StringSwitch<Register>(RegName)
-                     .Case("m0", AMDGPU::M0)
-                     .Case("exec", AMDGPU::EXEC)
-                     .Case("exec_lo", AMDGPU::EXEC_LO)
-                     .Case("exec_hi", AMDGPU::EXEC_HI)
-                     .Case("flat_scratch", AMDGPU::FLAT_SCR)
-                     .Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
-                     .Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
-                     .Default(Register());
+  Register Reg =
+      StringSwitch<Register>(RegName)
+          .Case("m0", AMDGPU::M0)
+          .Case("exec", AMDGPU::EXEC)
+          .Case("exec_lo", AMDGPU::EXEC_LO)
+          .Case("exec_hi", AMDGPU::EXEC_HI)
+          .Case("flat_scratch", AMDGPU::FLAT_SCR)
+          .Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
+          .Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
+          .Case("src_flat_scratch_base", AMDGPU::SRC_FLAT_SCRATCH_BASE)
+          .Case("src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
+          .Case("src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
+          .Default(Register());
   if (!Reg)
     return Reg;
 
@@ -5092,17 +5096,27 @@ Register SITargetLowering::getRegisterByName(const char *RegName, LLT VT,
                                     "\" for subtarget."));
   }
 
+  if (!Subtarget->hasGloballyAddressableScratch() &&
+      Subtarget->getRegisterInfo()->regsOverlap(
+          Reg, AMDGPU::SRC_FLAT_SCRATCH_BASE)) {
+    Fn.getContext().emitError(Twine("invalid register \"" + StringRef(RegName) +
+                                    "\" for subtarget."));
+  }
+
   switch (Reg) {
   case AMDGPU::M0:
   case AMDGPU::EXEC_LO:
   case AMDGPU::EXEC_HI:
   case AMDGPU::FLAT_SCR_LO:
   case AMDGPU::FLAT_SCR_HI:
+  case AMDGPU::SRC_FLAT_SCRATCH_BASE_LO:
+  case AMDGPU::SRC_FLAT_SCRATCH_BASE_HI:
     if (VT.getSizeInBits() == 32)
       return Reg;
     break;
   case AMDGPU::EXEC:
   case AMDGPU::FLAT_SCR:
+  case AMDGPU::SRC_FLAT_SCRATCH_BASE:
     if (VT.getSizeInBits() == 64)
       return Reg;
     break;

diff  --git a/llvm/test/CodeGen/AMDGPU/read-register-src-flat-scratch-base.ll b/llvm/test/CodeGen/AMDGPU/read-register-src-flat-scratch-base.ll
new file mode 100644
index 0000000000000..6073c27cf09ce
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/read-register-src-flat-scratch-base.ll
@@ -0,0 +1,35 @@
+; RUN: llc -global-isel=0 -mtriple=amdgpu12.50-amd-amdhsa < %s | FileCheck %s
+; RUN: llc -global-isel=1 -mtriple=amdgpu12.50-amd-amdhsa < %s | FileCheck %s
+
+declare i32 @llvm.read_register.i32(metadata) #0
+declare i64 @llvm.read_register.i64(metadata) #0
+
+; CHECK-LABEL: {{^}}test_read_src_flat_scratch_base:
+; CHECK: v_mov_b64_e32 v{{\[[0-9]+:[0-9]+\]}}, src_flat_scratch_base_lo
+define amdgpu_kernel void @test_read_src_flat_scratch_base(ptr addrspace(1) %out) #0 {
+  %v = call i64 @llvm.read_register.i64(metadata !0)
+  store i64 %v, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK-LABEL: {{^}}test_read_src_flat_scratch_base_lo:
+; CHECK: v_{{(dual_)?}}mov_b32{{(_e32)?}} v{{[0-9]+}}, src_flat_scratch_base_lo
+define amdgpu_kernel void @test_read_src_flat_scratch_base_lo(ptr addrspace(1) %out) #0 {
+  %v = call i32 @llvm.read_register.i32(metadata !1)
+  store i32 %v, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK-LABEL: {{^}}test_read_src_flat_scratch_base_hi:
+; CHECK: v_{{(dual_)?}}mov_b32{{(_e32)?}} v{{[0-9]+}}, src_flat_scratch_base_hi
+define amdgpu_kernel void @test_read_src_flat_scratch_base_hi(ptr addrspace(1) %out) #0 {
+  %v = call i32 @llvm.read_register.i32(metadata !2)
+  store i32 %v, ptr addrspace(1) %out
+  ret void
+}
+
+attributes #0 = { nounwind }
+
+!0 = !{!"src_flat_scratch_base"}
+!1 = !{!"src_flat_scratch_base_lo"}
+!2 = !{!"src_flat_scratch_base_hi"}

diff  --git a/llvm/test/CodeGen/AMDGPU/read-write-register-src-flat-scratch-base-invalid-subtarget.ll b/llvm/test/CodeGen/AMDGPU/read-write-register-src-flat-scratch-base-invalid-subtarget.ll
new file mode 100644
index 0000000000000..b702a74e1031e
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/read-write-register-src-flat-scratch-base-invalid-subtarget.ll
@@ -0,0 +1,52 @@
+; RUN: not llc -mtriple=amdgpu12.00-amd-amdhsa -filetype=null %s 2>&1 | FileCheck %s
+
+; src_flat_scratch_base{,_lo,_hi} require globally-addressable-scratch (gfx1250+),
+; so named-register access to them should be rejected on earlier subtargets.
+
+declare i32 @llvm.read_register.i32(metadata) #0
+declare i64 @llvm.read_register.i64(metadata) #0
+declare void @llvm.write_register.i32(metadata, i32) #0
+declare void @llvm.write_register.i64(metadata, i64) #0
+
+; CHECK: error: invalid register "src_flat_scratch_base" for subtarget.
+define amdgpu_kernel void @test_read_src_flat_scratch_base(ptr addrspace(1) %out) nounwind {
+  %v = call i64 @llvm.read_register.i64(metadata !0)
+  store i64 %v, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: invalid register "src_flat_scratch_base_lo" for subtarget.
+define amdgpu_kernel void @test_read_src_flat_scratch_base_lo(ptr addrspace(1) %out) nounwind {
+  %v = call i32 @llvm.read_register.i32(metadata !1)
+  store i32 %v, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: invalid register "src_flat_scratch_base_hi" for subtarget.
+define amdgpu_kernel void @test_read_src_flat_scratch_base_hi(ptr addrspace(1) %out) nounwind {
+  %v = call i32 @llvm.read_register.i32(metadata !2)
+  store i32 %v, ptr addrspace(1) %out
+  ret void
+}
+
+; CHECK: error: invalid register "src_flat_scratch_base" for subtarget.
+define amdgpu_kernel void @test_write_src_flat_scratch_base(i64 %val) nounwind {
+  call void @llvm.write_register.i64(metadata !0, i64 %val)
+  ret void
+}
+
+; CHECK: error: invalid register "src_flat_scratch_base_lo" for subtarget.
+define amdgpu_kernel void @test_write_src_flat_scratch_base_lo(i32 %val) nounwind {
+  call void @llvm.write_register.i32(metadata !1, i32 %val)
+  ret void
+}
+
+; CHECK: error: invalid register "src_flat_scratch_base_hi" for subtarget.
+define amdgpu_kernel void @test_write_src_flat_scratch_base_hi(i32 %val) nounwind {
+  call void @llvm.write_register.i32(metadata !2, i32 %val)
+  ret void
+}
+
+!0 = !{!"src_flat_scratch_base"}
+!1 = !{!"src_flat_scratch_base_lo"}
+!2 = !{!"src_flat_scratch_base_hi"}

diff  --git a/llvm/test/CodeGen/AMDGPU/type-mismatch-src-flat-scratch-base.ll b/llvm/test/CodeGen/AMDGPU/type-mismatch-src-flat-scratch-base.ll
new file mode 100644
index 0000000000000..362ca5ce3e4be
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/type-mismatch-src-flat-scratch-base.ll
@@ -0,0 +1,92 @@
+; RUN: split-file %s %t
+
+; RUN: not --crash llc -global-isel=0 -mtriple=amdgpu12.50-amd-amdhsa < %t/lo.ll 2>&1 | FileCheck --check-prefix=LO %s
+; RUN: not --crash llc -global-isel=1 -mtriple=amdgpu12.50-amd-amdhsa < %t/lo.ll 2>&1 | FileCheck --check-prefix=LO %s
+; RUN: not --crash llc -global-isel=0 -mtriple=amdgpu12.50-amd-amdhsa < %t/hi.ll 2>&1 | FileCheck --check-prefix=HI %s
+; RUN: not --crash llc -global-isel=1 -mtriple=amdgpu12.50-amd-amdhsa < %t/hi.ll 2>&1 | FileCheck --check-prefix=HI %s
+; RUN: not --crash llc -global-isel=0 -mtriple=amdgpu12.50-amd-amdhsa < %t/combined.ll 2>&1 | FileCheck --check-prefix=COMBINED %s
+; RUN: not --crash llc -global-isel=1 -mtriple=amdgpu12.50-amd-amdhsa < %t/combined.ll 2>&1 | FileCheck --check-prefix=COMBINED %s
+
+; RUN: not --crash llc -global-isel=0 -mtriple=amdgpu12.50-amd-amdhsa < %t/write-lo.ll 2>&1 | FileCheck --check-prefix=WRITE-LO %s
+; RUN: not --crash llc -global-isel=1 -mtriple=amdgpu12.50-amd-amdhsa < %t/write-lo.ll 2>&1 | FileCheck --check-prefix=WRITE-LO %s
+; RUN: not --crash llc -global-isel=0 -mtriple=amdgpu12.50-amd-amdhsa < %t/write-hi.ll 2>&1 | FileCheck --check-prefix=WRITE-HI %s
+; RUN: not --crash llc -global-isel=1 -mtriple=amdgpu12.50-amd-amdhsa < %t/write-hi.ll 2>&1 | FileCheck --check-prefix=WRITE-HI %s
+; RUN: not --crash llc -global-isel=0 -mtriple=amdgpu12.50-amd-amdhsa < %t/write-combined.ll 2>&1 | FileCheck --check-prefix=WRITE-COMBINED %s
+; RUN: not --crash llc -global-isel=1 -mtriple=amdgpu12.50-amd-amdhsa < %t/write-combined.ll 2>&1 | FileCheck --check-prefix=WRITE-COMBINED %s
+
+; Requesting src_flat_scratch_base and its variants as a wrong type is expected to error out.
+
+;--- lo.ll
+declare i64 @llvm.read_register.i64(metadata) #0
+
+; LO: LLVM ERROR: invalid type for register "src_flat_scratch_base_lo".
+define amdgpu_kernel void @test_read_src_flat_scratch_base_lo_wrong_type(ptr addrspace(1) %out) #0 {
+  %v = call i64 @llvm.read_register.i64(metadata !0)
+  store i64 %v, ptr addrspace(1) %out
+  ret void
+}
+
+attributes #0 = { nounwind }
+!0 = !{!"src_flat_scratch_base_lo"}
+
+;--- hi.ll
+declare i64 @llvm.read_register.i64(metadata) #0
+
+; HI: LLVM ERROR: invalid type for register "src_flat_scratch_base_hi".
+define amdgpu_kernel void @test_read_src_flat_scratch_base_hi_wrong_type(ptr addrspace(1) %out) #0 {
+  %v = call i64 @llvm.read_register.i64(metadata !0)
+  store i64 %v, ptr addrspace(1) %out
+  ret void
+}
+
+attributes #0 = { nounwind }
+!0 = !{!"src_flat_scratch_base_hi"}
+
+;--- combined.ll
+declare i32 @llvm.read_register.i32(metadata) #0
+
+; COMBINED: LLVM ERROR: invalid type for register "src_flat_scratch_base".
+define amdgpu_kernel void @test_read_src_flat_scratch_base_wrong_type(ptr addrspace(1) %out) #0 {
+  %v = call i32 @llvm.read_register.i32(metadata !0)
+  store i32 %v, ptr addrspace(1) %out
+  ret void
+}
+
+attributes #0 = { nounwind }
+!0 = !{!"src_flat_scratch_base"}
+
+;--- write-lo.ll
+declare void @llvm.write_register.i64(metadata, i64) #0
+
+; WRITE-LO: LLVM ERROR: invalid type for register "src_flat_scratch_base_lo".
+define amdgpu_kernel void @test_write_src_flat_scratch_base_lo_wrong_type(i64 %v) #0 {
+  call void @llvm.write_register.i64(metadata !0, i64 %v)
+  ret void
+}
+
+attributes #0 = { nounwind }
+!0 = !{!"src_flat_scratch_base_lo"}
+
+;--- write-hi.ll
+declare void @llvm.write_register.i64(metadata, i64) #0
+
+; WRITE-HI: LLVM ERROR: invalid type for register "src_flat_scratch_base_hi".
+define amdgpu_kernel void @test_write_src_flat_scratch_base_hi_wrong_type(i64 %v) #0 {
+  call void @llvm.write_register.i64(metadata !0, i64 %v)
+  ret void
+}
+
+attributes #0 = { nounwind }
+!0 = !{!"src_flat_scratch_base_hi"}
+
+;--- write-combined.ll
+declare void @llvm.write_register.i32(metadata, i32) #0
+
+; WRITE-COMBINED: LLVM ERROR: invalid type for register "src_flat_scratch_base".
+define amdgpu_kernel void @test_write_src_flat_scratch_base_wrong_type(i32 %v) #0 {
+  call void @llvm.write_register.i32(metadata !0, i32 %v)
+  ret void
+}
+
+attributes #0 = { nounwind }
+!0 = !{!"src_flat_scratch_base"}

diff  --git a/llvm/test/CodeGen/AMDGPU/write-register-src-flat-scratch-base.ll b/llvm/test/CodeGen/AMDGPU/write-register-src-flat-scratch-base.ll
new file mode 100644
index 0000000000000..ffa3554ff2212
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/write-register-src-flat-scratch-base.ll
@@ -0,0 +1,38 @@
+; RUN: llc -global-isel=0 -mtriple=amdgpu12.50-amd-amdhsa < %s | FileCheck %s
+; RUN: llc -global-isel=1 -mtriple=amdgpu12.50-amd-amdhsa < %s | FileCheck %s
+
+; src_flat_scratch_base{,_lo,_hi} are isConstant register aliases, so writes to
+; them are dead and get silently eliminated rather than lowered to a copy.
+
+declare void @llvm.write_register.i32(metadata, i32) #0
+declare void @llvm.write_register.i64(metadata, i64) #0
+
+; CHECK-LABEL: {{^}}test_write_src_flat_scratch_base:{{.*$}}
+; CHECK-NOT: src_flat_scratch_base
+; CHECK: s_endpgm
+define amdgpu_kernel void @test_write_src_flat_scratch_base(i64 %val) #0 {
+  call void @llvm.write_register.i64(metadata !0, i64 %val)
+  ret void
+}
+
+; CHECK-LABEL: {{^}}test_write_src_flat_scratch_base_lo:{{.*$}}
+; CHECK-NOT: src_flat_scratch_base
+; CHECK: s_endpgm
+define amdgpu_kernel void @test_write_src_flat_scratch_base_lo(i32 %val) #0 {
+  call void @llvm.write_register.i32(metadata !1, i32 %val)
+  ret void
+}
+
+; CHECK-LABEL: {{^}}test_write_src_flat_scratch_base_hi:{{.*$}}
+; CHECK-NOT: src_flat_scratch_base
+; CHECK: s_endpgm
+define amdgpu_kernel void @test_write_src_flat_scratch_base_hi(i32 %val) #0 {
+  call void @llvm.write_register.i32(metadata !2, i32 %val)
+  ret void
+}
+
+attributes #0 = { nounwind }
+
+!0 = !{!"src_flat_scratch_base"}
+!1 = !{!"src_flat_scratch_base_lo"}
+!2 = !{!"src_flat_scratch_base_hi"}


        


More information about the llvm-commits mailing list