diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp index 5762f1906a16d..b85cb26fdc956 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp @@ -340,15 +340,25 @@ class AMDGPULowerModuleLDS { // Get uses from the current function, excluding uses by called functions // Two output variables to avoid walking the globals list twice + std::optional HasAbsoluteGVs; for (auto &GV : M.globals()) { if (!AMDGPU::isLDSVariableToLower(GV)) { continue; } - if (GV.isAbsoluteSymbolRef()) { - report_fatal_error( - "LDS variables with absolute addresses are unimplemented."); - } + // Check if the module is consistent: either all GVs are absolute (happens + // when we run the pass more than once), or none are. + const bool IsAbsolute = GV.isAbsoluteSymbolRef(); + if (HasAbsoluteGVs.has_value()) { + if (*HasAbsoluteGVs != IsAbsolute) { + report_fatal_error( + "Module cannot mix absolute and non-absolute LDS GVs"); + } + } else + HasAbsoluteGVs = IsAbsolute; + + if (IsAbsolute) + continue; for (User *V : GV.users()) { if (auto *I = dyn_cast(V)) { diff --git a/llvm/test/CodeGen/AMDGPU/lds-reject-absolute-addresses.ll b/llvm/test/CodeGen/AMDGPU/lds-reject-mixed-absolute-addresses.ll similarity index 81% rename from llvm/test/CodeGen/AMDGPU/lds-reject-absolute-addresses.ll rename to llvm/test/CodeGen/AMDGPU/lds-reject-mixed-absolute-addresses.ll index 659cdb55ded2f..b512a43aa1022 100644 --- a/llvm/test/CodeGen/AMDGPU/lds-reject-absolute-addresses.ll +++ b/llvm/test/CodeGen/AMDGPU/lds-reject-mixed-absolute-addresses.ll @@ -2,8 +2,9 @@ ; RUN: not --crash opt -S -mtriple=amdgcn-- -passes=amdgpu-lower-module-lds < %s 2>&1 | FileCheck %s @var1 = addrspace(3) global i32 undef, !absolute_symbol !0 +@var2 = addrspace(3) global i32 undef -; CHECK: LLVM ERROR: LDS variables with absolute addresses are unimplemented. +; CHECK: Module cannot mix absolute and non-absolute LDS GVs define amdgpu_kernel void @kern() { %val0 = load i32, ptr addrspace(3) @var1 %val1 = add i32 %val0, 4 @@ -12,4 +13,3 @@ define amdgpu_kernel void @kern() { } !0 = !{i32 0, i32 1} - diff --git a/llvm/test/CodeGen/AMDGPU/lds-run-twice-absolute-md.ll b/llvm/test/CodeGen/AMDGPU/lds-run-twice-absolute-md.ll new file mode 100644 index 0000000000000..52b44eea35c82 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/lds-run-twice-absolute-md.ll @@ -0,0 +1,16 @@ +; RUN: opt -S -mtriple=amdgcn-- -amdgpu-lower-module-lds %s -o %t.ll +; RUN: opt -S -mtriple=amdgcn-- -amdgpu-lower-module-lds %t.ll -o %t.second.ll +; RUN: diff -ub %t.ll %t.second.ll -I ".*ModuleID.*" + +; Check AMDGPULowerModuleLDS can run more than once on the same module, and that +; the second run is a no-op. + +@lds = internal unnamed_addr addrspace(3) global i32 undef, align 4, !absolute_symbol !0 + +define amdgpu_kernel void @test() { +entry: + store i32 1, ptr addrspace(3) @lds + ret void +} + +!0 = !{i32 0, i32 1} diff --git a/llvm/test/CodeGen/AMDGPU/lds-run-twice.ll b/llvm/test/CodeGen/AMDGPU/lds-run-twice.ll new file mode 100644 index 0000000000000..b830ccb944a28 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/lds-run-twice.ll @@ -0,0 +1,14 @@ +; RUN: opt -S -mtriple=amdgcn-- -amdgpu-lower-module-lds %s -o %t.ll +; RUN: opt -S -mtriple=amdgcn-- -amdgpu-lower-module-lds %t.ll -o %t.second.ll +; RUN: diff -ub %t.ll %t.second.ll -I ".*ModuleID.*" + +; Check AMDGPULowerModuleLDS can run more than once on the same module, and that +; the second run is a no-op. + +@lds = internal unnamed_addr addrspace(3) global i32 undef, align 4 + +define amdgpu_kernel void @test() { +entry: + store i32 1, ptr addrspace(3) @lds + ret void +}