https://github.com/doru1004 updated https://github.com/llvm/llvm-project/pull/208557
>From b99852cc62e65a9f50b7745f71f4680fca7b5828 Mon Sep 17 00:00:00 2001 From: Gheorghe-Teodor Bercea <[email protected]> Date: Thu, 9 Jul 2026 15:46:01 -0500 Subject: [PATCH 1/3] Introduce address space 13 for VGPR as memory --- clang/test/CodeGen/target-data.c | 4 +- clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl | 2 +- llvm/docs/AMDGPUUsage.rst | 19 ++++- llvm/include/llvm/Support/AMDGPUAddrSpace.h | 5 ++ llvm/lib/IR/AutoUpgrade.cpp | 4 + llvm/lib/IR/VerifierAMDGPU.cpp | 12 ++- llvm/lib/Target/AMDGPU/AMDGPUInstructions.td | 1 + llvm/lib/TargetParser/TargetDataLayout.cpp | 3 +- llvm/test/Verifier/AMDGPU/alloca.ll | 75 ++++++++++++------- .../Bitcode/DataLayoutUpgradeTest.cpp | 38 +++++----- 10 files changed, 110 insertions(+), 53 deletions(-) diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c index a5e0b814c7042..f03aaba8b53dd 100644 --- a/clang/test/CodeGen/target-data.c +++ b/clang/test/CodeGen/target-data.c @@ -160,12 +160,12 @@ // RUN: %clang_cc1 -triple amdgcn-unknown -target-cpu hawaii -o - -emit-llvm %s \ // RUN: | FileCheck %s -check-prefix=R600SI -// R600SI: target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" +// R600SI: target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-p13:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" // Test default -target-cpu // RUN: %clang_cc1 -triple amdgcn-unknown -o - -emit-llvm %s \ // RUN: | FileCheck %s -check-prefix=R600SIDefault -// R600SIDefault: target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" +// R600SIDefault: target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-p13:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" // RUN: %clang_cc1 -triple arm64-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=AARCH64 diff --git a/clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl b/clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl index 72ce72644b8ea..f120db1aaf6cd 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl @@ -1,5 +1,5 @@ // RUN: %clang_cc1 %s -O0 -triple amdgcn -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 %s -O0 -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s -// CHECK: target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" +// CHECK: target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-p13:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9" void foo(void) {} diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst index cbe9d15074457..a055f72fdfded 100644 --- a/llvm/docs/AMDGPUUsage.rst +++ b/llvm/docs/AMDGPUUsage.rst @@ -1118,7 +1118,7 @@ supported for the ``amdgcn`` target. *reserved for future use* 10 *reserved for future use* 11 *reserved for downstream use (LLPC)* 12 - *reserved for future use* 13 + VGPR 13 N/A VGPR 32 0xFFFFFFFF *reserved for future use* 14 *reserved for future use* 16 Streamout Registers 128 N/A GS_REGS @@ -1333,6 +1333,23 @@ supported for the ``amdgcn`` target. a buffer strided pointer, this means that the base pointer is ``align(4)``, that the offset is a multiple of 4 bytes, and that the stride is a multiple of 4. +**VGPR** + The VGPR address space presents a memory view of the wave's vector registers. + The 32-bit address is a byte address into the thread's view of vector + registers. For example, loading 4 bytes from address ``12`` reads the contents + of ``v3``. Storing 8 bytes to address ``32`` overwrites the contents of + ``v[8:9]``. + + Use of this address space by frontends is strongly discouraged. It has unusual + and subtle lifetime rules due to the potential for interaction with normal + register allocation. It exists primarily for internal purposes of the backend, + such as promoting ``alloca`` instructions from the private address space into + VGPRs. + + In particular, memory in this address space that was allocated by an + ``alloca`` is not visible while in a called function. Attempting to dereference + a pointer to such memory in a called function is undefined behavior. + **Streamout Registers** Dedicated registers used by the GS NGG Streamout Instructions. The register file is modelled as a memory in a distinct address space because it is indexed diff --git a/llvm/include/llvm/Support/AMDGPUAddrSpace.h b/llvm/include/llvm/Support/AMDGPUAddrSpace.h index 01b1510524d0f..b1af8047ce580 100644 --- a/llvm/include/llvm/Support/AMDGPUAddrSpace.h +++ b/llvm/include/llvm/Support/AMDGPUAddrSpace.h @@ -47,6 +47,11 @@ enum : unsigned { BUFFER_STRIDED_POINTER = 9, ///< Address space for 192-bit fat buffer ///< pointers with an additional index. + VGPR = 13, ///< Address space for VGPRs. The 32-bit address is a byte offset + ///< into the wave's view of its vector registers. Note this shares + ///< its numeric value with CONSTANT_BUFFER_5, which is only used + ///< by the (graphics) R600 path. + RESERVED_ADDRESS_SPACE_16 = 16, ///< Reserved for downstream use. /// Internal address spaces. Can be freely renumbered. diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 880350a1b159b..932b7c79789b6 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -7075,6 +7075,10 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { Res.replace(Res.find(OldP8), OldP8.size(), "-p8:128:128:128:48-"); if (!DL.contains("-p9") && !DL.starts_with("p9")) Res.append("-p9:192:256:256:32"); + // Add sizing for the VGPR address space (32-bit byte offset into the + // wave's vector registers). + if (!DL.contains("-p13") && !DL.starts_with("p13")) + Res.append("-p13:32:32"); } // Upgrade the ELF mangling mode. diff --git a/llvm/lib/IR/VerifierAMDGPU.cpp b/llvm/lib/IR/VerifierAMDGPU.cpp index 04cb214ef2520..a9cbdc20ace35 100644 --- a/llvm/lib/IR/VerifierAMDGPU.cpp +++ b/llvm/lib/IR/VerifierAMDGPU.cpp @@ -122,8 +122,16 @@ void llvm::verifyAMDGPUAlloca(VerifierSupport &VS, const AllocaInst &AI) { if (!VS.TT.isAMDGPU()) return; - if (AI.getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS) - VS.CheckFailed("alloca on amdgpu must be in addrspace(5)", &AI); + if (AI.getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS && + AI.getAddressSpace() != AMDGPUAS::VGPR) + VS.CheckFailed("alloca on amdgpu must be in addrspace(5) or addrspace(13)", + &AI); + + // Only static allocas can live in VGPRs; a dynamically sized one has no + // register-file representation. (Other address spaces are already rejected + // above, so this only adds the more specific diagnostic for addrspace(13).) + if (!AI.isStaticAlloca() && AI.getAddressSpace() == AMDGPUAS::VGPR) + VS.CheckFailed("dynamic alloca on amdgpu must be in addrspace(5)", &AI); } bool llvm::isAMDGPUCallBrIntrinsic(Intrinsic::ID ID) { diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td index 2387afe1cd362..aa06e49c68e03 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td +++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td @@ -19,6 +19,7 @@ def AddrSpaces { int Constant = 4; int Private = 5; int Constant32Bit = 6; + int VGPR = 13; } diff --git a/llvm/lib/TargetParser/TargetDataLayout.cpp b/llvm/lib/TargetParser/TargetDataLayout.cpp index 18f0c13907e52..e11f65f6cd4bd 100644 --- a/llvm/lib/TargetParser/TargetDataLayout.cpp +++ b/llvm/lib/TargetParser/TargetDataLayout.cpp @@ -274,7 +274,8 @@ static std::string computeAMDDataLayout(const Triple &TT) { // space 8) which cannot be non-trivilally accessed by LLVM memory operations // like getelementptr. return "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32" - "-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-" + "-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-p13:32:32-" + "i64:64-" "v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-" "v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"; } diff --git a/llvm/test/Verifier/AMDGPU/alloca.ll b/llvm/test/Verifier/AMDGPU/alloca.ll index f31d6228d7936..24b422a37bd7d 100644 --- a/llvm/test/Verifier/AMDGPU/alloca.ll +++ b/llvm/test/Verifier/AMDGPU/alloca.ll @@ -2,23 +2,25 @@ target triple = "amdgcn-amd-amdhsa" -; CHECK: alloca on amdgpu must be in addrspace(5) +; A static alloca is allowed in addrspace(5) (private) and addrspace(13) (VGPR); +; any other address space is rejected. +; CHECK: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.0 = alloca i32, align 4 -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.1 = alloca i32, align 4, addrspace(1) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.2 = alloca i32, align 4, addrspace(2) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.3 = alloca i32, align 4, addrspace(3) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.4 = alloca i32, align 4, addrspace(4) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.6 = alloca i32, align 4, addrspace(6) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.7 = alloca i32, align 4, addrspace(7) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.8 = alloca i32, align 4, addrspace(8) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.9 = alloca i32, align 4, addrspace(9) define void @static_alloca() { entry: @@ -32,27 +34,32 @@ entry: %alloca.7 = alloca i32, align 4, addrspace(7) %alloca.8 = alloca i32, align 4, addrspace(8) %alloca.9 = alloca i32, align 4, addrspace(9) + %alloca.13 = alloca i32, align 4, addrspace(13) ret void } -; CHECK: alloca on amdgpu must be in addrspace(5) +; A dynamically sized alloca is only allowed in addrspace(5); addrspace(13) is +; rejected because it has no register-file representation. +; CHECK: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.0 = alloca i32, i32 %n, align 4 -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.1 = alloca i32, i32 %n, align 4, addrspace(1) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.2 = alloca i32, i32 %n, align 4, addrspace(2) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.3 = alloca i32, i32 %n, align 4, addrspace(3) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.4 = alloca i32, i32 %n, align 4, addrspace(4) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.6 = alloca i32, i32 %n, align 4, addrspace(6) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.7 = alloca i32, i32 %n, align 4, addrspace(7) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.8 = alloca i32, i32 %n, align 4, addrspace(8) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.9 = alloca i32, i32 %n, align 4, addrspace(9) +; CHECK-NEXT: dynamic alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: %alloca.13 = alloca i32, i32 %n, align 4, addrspace(13) define void @dynamic_alloca_i32(i32 %n) { entry: %alloca.0 = alloca i32, i32 %n, align 4 @@ -65,26 +72,27 @@ entry: %alloca.7 = alloca i32, i32 %n, align 4, addrspace(7) %alloca.8 = alloca i32, i32 %n, align 4, addrspace(8) %alloca.9 = alloca i32, i32 %n, align 4, addrspace(9) + %alloca.13 = alloca i32, i32 %n, align 4, addrspace(13) ret void } -; CHECK: alloca on amdgpu must be in addrspace(5) +; CHECK: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.0 = alloca i32, i64 %n, align 4 -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.1 = alloca i32, i64 %n, align 4, addrspace(1) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.2 = alloca i32, i64 %n, align 4, addrspace(2) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.3 = alloca i32, i64 %n, align 4, addrspace(3) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.4 = alloca i32, i64 %n, align 4, addrspace(4) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.6 = alloca i32, i64 %n, align 4, addrspace(6) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.7 = alloca i32, i64 %n, align 4, addrspace(7) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.8 = alloca i32, i64 %n, align 4, addrspace(8) -; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: alloca on amdgpu must be in addrspace(5) or addrspace(13) ; CHECK-NEXT: %alloca.9 = alloca i32, i64 %n, align 4, addrspace(9) define void @dynamic_alloca_i64(i64 %n) { entry: @@ -100,3 +108,16 @@ entry: %alloca.9 = alloca i32, i64 %n, align 4, addrspace(9) ret void } + +; A static alloca that is not in the entry block is treated as dynamic, so +; addrspace(13) is rejected there too. +; CHECK: dynamic alloca on amdgpu must be in addrspace(5) +; CHECK-NEXT: %alloca.13 = alloca i32, align 4, addrspace(13) +define void @nonentry_alloca() { +entry: + br label %nonentry + +nonentry: + %alloca.13 = alloca i32, align 4, addrspace(13) + ret void +} diff --git a/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp b/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp index a082adbf6565e..0ec3c753c10f1 100644 --- a/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp +++ b/llvm/unittests/Bitcode/DataLayoutUpgradeTest.cpp @@ -43,14 +43,14 @@ TEST(DataLayoutUpgradeTest, ValidDataLayoutUpgrade) { // and that ANDGCN adds p7 and p8 as well. EXPECT_EQ(UpgradeDataLayoutString("e-p:64:64", "amdgcn"), "m:e-e-p:64:64-G1-ni:7:8:9-p7:160:256:256:32-p8:128:128:128:48-p9:" - "192:256:256:32"); + "192:256:256:32-p13:32:32"); EXPECT_EQ(UpgradeDataLayoutString("e-p:64:64-G1", "amdgcn"), "m:e-e-p:64:64-G1-ni:7:8:9-p7:160:256:256:32-p8:128:128:128:48-p9:" - "192:256:256:32"); + "192:256:256:32-p13:32:32"); // Check that the old AMDGCN p8:128:128 definition is upgraded EXPECT_EQ(UpgradeDataLayoutString("e-p:64:64-p8:128:128-G1", "amdgcn"), "m:e-e-p:64:64-p8:128:128:128:48-G1-ni:7:8:9-p7:160:256:256:32-p9:" - "192:256:256:32"); + "192:256:256:32-p13:32:32"); // but that r600 does not. EXPECT_EQ(UpgradeDataLayoutString("e-p:32:32-G1", "r600"), "m:e-e-p:32:32-G1"); @@ -66,7 +66,7 @@ TEST(DataLayoutUpgradeTest, ValidDataLayoutUpgrade) { "m:e-e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:" "64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:" "1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9-p7:160:256:256:32-p8:128:128:" - "128:48-p9:192:256:256:32"); + "128:48-p9:192:256:256:32-p13:32:32"); // Check that SystemZ adds -S64 if needed. EXPECT_EQ(UpgradeDataLayoutString( @@ -158,24 +158,24 @@ TEST(DataLayoutUpgradeTest, NoDataLayoutUpgrade) { EXPECT_EQ(UpgradeDataLayoutString("G2", "r600"), "m:e-G2"); EXPECT_EQ(UpgradeDataLayoutString("e-p:64:64-G2", "amdgcn"), "m:e-e-p:64:64-G2-ni:7:8:9-p7:160:256:256:32-p8:128:128:128:48-p9:" - "192:256:256:32"); + "192:256:256:32-p13:32:32"); EXPECT_EQ(UpgradeDataLayoutString("G2-e-p:64:64", "amdgcn"), "m:e-G2-e-p:64:64-ni:7:8:9-p7:160:256:256:32-p8:128:128:128:48-p9:" - "192:256:256:32"); + "192:256:256:32-p13:32:32"); EXPECT_EQ(UpgradeDataLayoutString("e-p:64:64-G0", "amdgcn"), "m:e-e-p:64:64-G0-ni:7:8:9-p7:160:256:256:32-p8:128:128:128:48-p9:" - "192:256:256:32"); + "192:256:256:32-p13:32:32"); // Check that AMDGCN targets don't add already declared address space 7. - EXPECT_EQ( - UpgradeDataLayoutString("e-p:64:64-p7:64:64", "amdgcn"), - "m:e-e-p:64:64-p7:64:64-G1-ni:7:8:9-p8:128:128:128:48-p9:192:256:256:32"); - EXPECT_EQ( - UpgradeDataLayoutString("p7:64:64-G2-e-p:64:64", "amdgcn"), - "m:e-p7:64:64-G2-e-p:64:64-ni:7:8:9-p8:128:128:128:48-p9:192:256:256:32"); - EXPECT_EQ( - UpgradeDataLayoutString("e-p:64:64-p7:64:64-G1", "amdgcn"), - "m:e-e-p:64:64-p7:64:64-G1-ni:7:8:9-p8:128:128:128:48-p9:192:256:256:32"); + EXPECT_EQ(UpgradeDataLayoutString("e-p:64:64-p7:64:64", "amdgcn"), + "m:e-e-p:64:64-p7:64:64-G1-ni:7:8:9-p8:128:128:128:48-p9:192:256:" + "256:32-p13:32:32"); + EXPECT_EQ(UpgradeDataLayoutString("p7:64:64-G2-e-p:64:64", "amdgcn"), + "m:e-p7:64:64-G2-e-p:64:64-ni:7:8:9-p8:128:128:128:48-p9:192:256:" + "256:32-p13:32:32"); + EXPECT_EQ(UpgradeDataLayoutString("e-p:64:64-p7:64:64-G1", "amdgcn"), + "m:e-e-p:64:64-p7:64:64-G1-ni:7:8:9-p8:128:128:128:48-p9:192:256:" + "256:32-p13:32:32"); // Check that SPIR & SPIRV targets don't add -G1 if there is already a -G // flag. @@ -216,9 +216,9 @@ TEST(DataLayoutUpgradeTest, EmptyDataLayout) { // Check that AMDGPU targets add G1 if it's not present. EXPECT_EQ(UpgradeDataLayoutString("", "r600"), "m:e-G1"); - EXPECT_EQ( - UpgradeDataLayoutString("", "amdgcn"), - "m:e-G1-ni:7:8:9-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32"); + EXPECT_EQ(UpgradeDataLayoutString("", "amdgcn"), + "m:e-G1-ni:7:8:9-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:" + "256:32-p13:32:32"); // Check that SPIR & SPIRV targets add G1 if it's not present. EXPECT_EQ(UpgradeDataLayoutString("", "spir"), "G1"); >From 14a7d385a41a1265cd56714dca59beab0b114314 Mon Sep 17 00:00:00 2001 From: Gheorghe-Teodor Bercea <[email protected]> Date: Thu, 30 Jul 2026 19:06:48 +0300 Subject: [PATCH 2/3] Give the VGPR address space a null pointer value of -1 --- llvm/include/llvm/Support/AMDGPUAddrSpace.h | 1 + llvm/test/CodeGen/AMDGPU/nullptr.ll | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Support/AMDGPUAddrSpace.h b/llvm/include/llvm/Support/AMDGPUAddrSpace.h index b1af8047ce580..6dbedbc0c6c2e 100644 --- a/llvm/include/llvm/Support/AMDGPUAddrSpace.h +++ b/llvm/include/llvm/Support/AMDGPUAddrSpace.h @@ -186,6 +186,7 @@ constexpr int64_t getNullPointerValue(unsigned AS) { case PRIVATE_ADDRESS: case LOCAL_ADDRESS: case REGION_ADDRESS: + case VGPR: return -1; default: return 0; diff --git a/llvm/test/CodeGen/AMDGPU/nullptr.ll b/llvm/test/CodeGen/AMDGPU/nullptr.ll index 79c11fb2a7c37..2fdf76e8d9ef7 100644 --- a/llvm/test/CodeGen/AMDGPU/nullptr.ll +++ b/llvm/test/CodeGen/AMDGPU/nullptr.ll @@ -54,8 +54,11 @@ ; R600-NEXT: .long 0 @nullptr12 = global ptr addrspace(12) addrspacecast (ptr null to ptr addrspace(12)) +; Address space 13 is the VGPR address space, whose null pointer is -1 like the +; other address spaces where zero is a valid address. R600 reaches the same +; value through the shared numbering, where 13 is CONSTANT_BUFFER_5. ; CHECK-LABEL: nullptr13: -; R600-NEXT: .long 0 +; CHECK-NEXT: .long -1 @nullptr13 = global ptr addrspace(13) addrspacecast (ptr null to ptr addrspace(13)) ; CHECK-LABEL: nullptr14: >From 8aa39c90d7085edc9973e26a4aa221aa8af8524d Mon Sep 17 00:00:00 2001 From: Gheorghe-Teodor Bercea <[email protected]> Date: Tue, 4 Aug 2026 14:57:56 +0300 Subject: [PATCH 3/3] Classify the VGPR address space correctly and give it alias rules --- llvm/include/llvm/Support/AMDGPUAddrSpace.h | 2 +- llvm/lib/Target/AMDGPU/AMDGPU.h | 29 ++++++++------ .../CodeGen/AMDGPU/amdgpu-alias-analysis.ll | 39 +++++++++++++++++++ .../AMDGPU/annotate-kernel-features-hsa.ll | 8 ++-- ...utor-flatscratchinit-undefined-behavior.ll | 4 +- .../AMDGPU/attributor-flatscratchinit.ll | 20 +++++----- .../AMDGPU/attributor-noalias-addrspace.ll | 4 +- .../CodeGen/AMDGPU/simple-indirect-call.ll | 2 +- 8 files changed, 77 insertions(+), 31 deletions(-) diff --git a/llvm/include/llvm/Support/AMDGPUAddrSpace.h b/llvm/include/llvm/Support/AMDGPUAddrSpace.h index 6dbedbc0c6c2e..54a80ecccf6c9 100644 --- a/llvm/include/llvm/Support/AMDGPUAddrSpace.h +++ b/llvm/include/llvm/Support/AMDGPUAddrSpace.h @@ -27,7 +27,7 @@ namespace llvm { namespace AMDGPUAS { enum : unsigned { // The maximum value for flat, generic, local, private, constant and region. - MAX_AMDGPU_ADDRESS = 9, + MAX_AMDGPU_ADDRESS = 13, FLAT_ADDRESS = 0, ///< Address space for flat memory. GLOBAL_ADDRESS = 1, ///< Address space for global memory (RAT0, VTX0). diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h index c72fa69aa1419..48ba95b2a1a41 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPU.h +++ b/llvm/lib/Target/AMDGPU/AMDGPU.h @@ -620,17 +620,24 @@ static inline bool addrspacesMayAlias(unsigned AS1, unsigned AS2) { // clang-format off static const bool ASAliasRules[][AMDGPUAS::MAX_AMDGPU_ADDRESS + 1] = { - /* Flat Global Region Local Constant Private Const32 BufFatPtr BufRsrc BufStrdPtr */ - /* Flat */ {true, true, false, true, true, true, true, true, true, true}, - /* Global */ {true, true, false, false, true, false, true, true, true, true}, - /* Region */ {false, false, true, false, false, false, false, false, false, false}, - /* Local */ {true, false, false, true, false, false, false, false, false, false}, - /* Constant */ {true, true, false, false, false, false, true, true, true, true}, - /* Private */ {true, false, false, false, false, true, false, false, false, false}, - /* Constant 32-bit */ {true, true, false, false, true, false, false, true, true, true}, - /* Buffer Fat Ptr */ {true, true, false, false, true, false, true, true, true, true}, - /* Buffer Resource */ {true, true, false, false, true, false, true, true, true, true}, - /* Buffer Strided Ptr */ {true, true, false, false, true, false, true, true, true, true}, + /* Flat Global Region Local Constant Private Const32 BufFatPtr BufRsrc BufStrdPtr rsvd10 rsvd11 rsvd12 VGPR */ + /* Flat */ {true, true, false, true, true, true, true, true, true, true, true, true, true, false}, + /* Global */ {true, true, false, false, true, false, true, true, true, true, true, true, true, false}, + /* Region */ {false, false, true, false, false, false, false, false, false, false, true, true, true, false}, + /* Local */ {true, false, false, true, false, false, false, false, false, false, true, true, true, false}, + /* Constant */ {true, true, false, false, false, false, true, true, true, true, true, true, true, false}, + /* Private */ {true, false, false, false, false, true, false, false, false, false, true, true, true, false}, + /* Constant 32-bit */ {true, true, false, false, true, false, false, true, true, true, true, true, true, false}, + /* Buffer Fat Ptr */ {true, true, false, false, true, false, true, true, true, true, true, true, true, false}, + /* Buffer Resource */ {true, true, false, false, true, false, true, true, true, true, true, true, true, false}, + /* Buffer Strided Ptr */ {true, true, false, false, true, false, true, true, true, true, true, true, true, false}, + /* reserved (10) */ {true, true, true, true, true, true, true, true, true, true, true, true, true, true}, + /* reserved (11) */ {true, true, true, true, true, true, true, true, true, true, true, true, true, true}, + /* reserved (12) */ {true, true, true, true, true, true, true, true, true, true, true, true, true, true}, + // A VGPR ("as memory") access only ever touches the wave's own registers, + // which no other address space can reach: a flat pointer obtained by casting + // one cannot be dereferenced. + /* VGPR */ {false, false, false, false, false, false, false, false, false, false, true, true, true, true}, }; // clang-format on static_assert(std::size(ASAliasRules) == AMDGPUAS::MAX_AMDGPU_ADDRESS + 1); diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-alias-analysis.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-alias-analysis.ll index 7e64ed4d95390..4b7549f8fae10 100644 --- a/llvm/test/CodeGen/AMDGPU/amdgpu-alias-analysis.ll +++ b/llvm/test/CodeGen/AMDGPU/amdgpu-alias-analysis.ll @@ -319,6 +319,45 @@ define void @test_9_9(ptr addrspace(9) %p, ptr addrspace(9) %p1) { ret void } +; The VGPR address space is only reachable through its own indexed accesses, so +; it aliases nothing else - not even flat, since a flat pointer obtained by +; casting one cannot be dereferenced. + +; CHECK: NoAlias: i8 addrspace(13)* %p, i8* %p1 +define void @test_13_0(ptr addrspace(13) %p, ptr addrspace(0) %p1) { + load i8, ptr addrspace(13) %p + load i8, ptr addrspace(0) %p1 + ret void +} + +; CHECK: NoAlias: i8 addrspace(13)* %p, i8 addrspace(1)* %p1 +define void @test_13_1(ptr addrspace(13) %p, ptr addrspace(1) %p1) { + load i8, ptr addrspace(13) %p + load i8, ptr addrspace(1) %p1 + ret void +} + +; CHECK: NoAlias: i8 addrspace(13)* %p, i8 addrspace(3)* %p1 +define void @test_13_3(ptr addrspace(13) %p, ptr addrspace(3) %p1) { + load i8, ptr addrspace(13) %p + load i8, ptr addrspace(3) %p1 + ret void +} + +; CHECK: NoAlias: i8 addrspace(13)* %p, i8 addrspace(5)* %p1 +define void @test_13_5(ptr addrspace(13) %p, ptr addrspace(5) %p1) { + load i8, ptr addrspace(13) %p + load i8, ptr addrspace(5) %p1 + ret void +} + +; CHECK: MayAlias: i8 addrspace(13)* %p, i8 addrspace(13)* %p1 +define void @test_13_13(ptr addrspace(13) %p, ptr addrspace(13) %p1) { + load i8, ptr addrspace(13) %p + load i8, ptr addrspace(13) %p1 + ret void +} + ; CHECK-LABEL: Function: test_kernel_arg_local_ptr ; CHECK: MayAlias: i32 addrspace(3)* %arg, i32 addrspace(3)* %arg1 ; CHECK: MayAlias: i32 addrspace(3)* %arg, i32* %arg2 diff --git a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll index f51247ba10964..cf31605b8ecbe 100644 --- a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll +++ b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa.ll @@ -489,8 +489,8 @@ attributes #1 = { nounwind } ; HSA: attributes #[[ATTR13]] = { nounwind "amdgpu-no-cluster-id-x" "amdgpu-no-cluster-id-y" "amdgpu-no-cluster-id-z" "amdgpu-no-completion-action" "amdgpu-no-default-queue" "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-flat-scratch-init" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "amdgpu-no-wwm" } ; HSA: attributes #[[ATTR14]] = { nounwind "amdgpu-no-cluster-id-x" "amdgpu-no-cluster-id-y" "amdgpu-no-cluster-id-z" "amdgpu-no-completion-action" "amdgpu-no-default-queue" "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "amdgpu-no-wwm" } ;. -; HSA: [[META0]] = !{i32 1, i32 3, i32 4, i32 10} -; HSA: [[META1]] = !{i32 1, i32 5, i32 6, i32 10} -; HSA: [[META2]] = !{i32 2, i32 10} -; HSA: [[META3]] = !{i32 1, i32 4, i32 5, i32 10} +; HSA: [[META0]] = !{i32 1, i32 3, i32 4, i32 14} +; HSA: [[META1]] = !{i32 1, i32 5, i32 6, i32 14} +; HSA: [[META2]] = !{i32 2, i32 14} +; HSA: [[META3]] = !{i32 1, i32 4, i32 5, i32 14} ;. diff --git a/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit-undefined-behavior.ll b/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit-undefined-behavior.ll index ccc434842e498..2d30660e18768 100644 --- a/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit-undefined-behavior.ll +++ b/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit-undefined-behavior.ll @@ -153,7 +153,7 @@ attributes #0 = { "amdgpu-no-flat-scratch-init" } ; GFX10: attributes #[[ATTR0]] = { "amdgpu-no-cluster-id-x" "amdgpu-no-cluster-id-y" "amdgpu-no-cluster-id-z" "amdgpu-no-completion-action" "amdgpu-no-default-queue" "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-flat-scratch-init" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "amdgpu-no-wwm" "target-cpu"="gfx1010" } ; GFX10: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) "target-cpu"="gfx1010" } ;. -; GFX9: [[META0]] = !{i32 1, i32 5, i32 6, i32 10} +; GFX9: [[META0]] = !{i32 1, i32 5, i32 6, i32 14} ;. -; GFX10: [[META0]] = !{i32 1, i32 5, i32 6, i32 10} +; GFX10: [[META0]] = !{i32 1, i32 5, i32 6, i32 14} ;. diff --git a/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll b/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll index 1e8a33781ee8d..1dcaf394ac8fa 100644 --- a/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll +++ b/llvm/test/CodeGen/AMDGPU/attributor-flatscratchinit.ll @@ -877,15 +877,15 @@ define amdgpu_kernel void @with_inline_asm() { ; GFX10: attributes #[[ATTR3:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) "target-cpu"="gfx1010" } ; GFX10: attributes #[[ATTR4]] = { "amdgpu-no-cluster-id-x" "amdgpu-no-cluster-id-y" "amdgpu-no-cluster-id-z" "amdgpu-no-completion-action" "amdgpu-no-default-queue" "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-flat-scratch-init" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "amdgpu-no-wwm" "target-cpu"="gfx1010" } ;. -; GFX9: [[META0]] = !{i32 2, i32 10} -; GFX9: [[META1]] = !{i32 1, i32 2, i32 3, i32 10} -; GFX9: [[META2]] = !{i32 1, i32 3, i32 4, i32 10} -; GFX9: [[META3]] = !{i32 1, i32 4, i32 5, i32 10} -; GFX9: [[META4]] = !{i32 1, i32 5, i32 6, i32 10} +; GFX9: [[META0]] = !{i32 2, i32 14} +; GFX9: [[META1]] = !{i32 1, i32 2, i32 3, i32 14} +; GFX9: [[META2]] = !{i32 1, i32 3, i32 4, i32 14} +; GFX9: [[META3]] = !{i32 1, i32 4, i32 5, i32 14} +; GFX9: [[META4]] = !{i32 1, i32 5, i32 6, i32 14} ;. -; GFX10: [[META0]] = !{i32 2, i32 10} -; GFX10: [[META1]] = !{i32 1, i32 2, i32 3, i32 10} -; GFX10: [[META2]] = !{i32 1, i32 3, i32 4, i32 10} -; GFX10: [[META3]] = !{i32 1, i32 4, i32 5, i32 10} -; GFX10: [[META4]] = !{i32 1, i32 5, i32 6, i32 10} +; GFX10: [[META0]] = !{i32 2, i32 14} +; GFX10: [[META1]] = !{i32 1, i32 2, i32 3, i32 14} +; GFX10: [[META2]] = !{i32 1, i32 3, i32 4, i32 14} +; GFX10: [[META3]] = !{i32 1, i32 4, i32 5, i32 14} +; GFX10: [[META4]] = !{i32 1, i32 5, i32 6, i32 14} ;. diff --git a/llvm/test/CodeGen/AMDGPU/attributor-noalias-addrspace.ll b/llvm/test/CodeGen/AMDGPU/attributor-noalias-addrspace.ll index f9edbd070ae7c..8fa5d64c2e9c5 100644 --- a/llvm/test/CodeGen/AMDGPU/attributor-noalias-addrspace.ll +++ b/llvm/test/CodeGen/AMDGPU/attributor-noalias-addrspace.ll @@ -633,7 +633,7 @@ define amdgpu_kernel void @no_alias_addr_space_has_meta(ptr addrspace(3) %sptr, !0 = !{i32 2, i32 3, i32 4, i32 10} ;. -; CHECK: [[META0]] = !{i32 2, i32 3, i32 4, i32 5, i32 6, i32 10} -; CHECK: [[META1]] = !{i32 2, i32 3, i32 5, i32 10} +; CHECK: [[META0]] = !{i32 2, i32 3, i32 4, i32 5, i32 6, i32 14} +; CHECK: [[META1]] = !{i32 2, i32 3, i32 5, i32 14} ; CHECK: [[META2]] = !{i32 2, i32 3, i32 4, i32 10} ;. diff --git a/llvm/test/CodeGen/AMDGPU/simple-indirect-call.ll b/llvm/test/CodeGen/AMDGPU/simple-indirect-call.ll index c6cd2b15203f7..005cbd73da84f 100644 --- a/llvm/test/CodeGen/AMDGPU/simple-indirect-call.ll +++ b/llvm/test/CodeGen/AMDGPU/simple-indirect-call.ll @@ -59,5 +59,5 @@ define amdgpu_kernel void @test_simple_indirect_call() { ;. ; ATTRIBUTOR_GCN: attributes #[[ATTR0]] = { "amdgpu-no-cluster-id-x" "amdgpu-no-cluster-id-y" "amdgpu-no-cluster-id-z" "amdgpu-no-completion-action" "amdgpu-no-default-queue" "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-flat-scratch-init" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "amdgpu-no-wwm" } ;. -; ATTRIBUTOR_GCN: [[META0]] = !{i32 1, i32 5, i32 6, i32 10} +; ATTRIBUTOR_GCN: [[META0]] = !{i32 1, i32 5, i32 6, i32 14} ;. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
