https://github.com/shiltian updated https://github.com/llvm/llvm-project/pull/175610
>From 93cfec6b023050c02e6d332284e9439911d99d83 Mon Sep 17 00:00:00 2001 From: Shilei Tian <[email protected]> Date: Mon, 12 Jan 2026 13:56:17 -0500 Subject: [PATCH 1/2] [Clang][AMDGPU] Get correct nullptr value for AS3 and AS5 --- clang/lib/Basic/Targets/AMDGPU.h | 16 ++++-- .../nullptr-in-different-address-spaces.cpp | 57 +++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 clang/test/CodeGen/AMDGPU/nullptr-in-different-address-spaces.cpp diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index 0076f822c02a1..3cb0d5a63ec81 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -446,10 +446,18 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { // value ~0. uint64_t getNullPointerValue(LangAS AS) const override { // FIXME: Also should handle region. - return (AS == LangAS::opencl_local || AS == LangAS::opencl_private || - AS == LangAS::sycl_local || AS == LangAS::sycl_private) - ? ~0 - : 0; + // Check language-specific address spaces + if (AS == LangAS::opencl_local || AS == LangAS::opencl_private || + AS == LangAS::sycl_local || AS == LangAS::sycl_private) + return ~0; + // Also check target address spaces that map to local or private + if (isTargetAddressSpace(AS)) { + unsigned TargetAS = toTargetAddressSpace(AS); + if (TargetAS == llvm::AMDGPUAS::LOCAL_ADDRESS || + TargetAS == llvm::AMDGPUAS::PRIVATE_ADDRESS) + return ~0; + } + return 0; } void setAuxTarget(const TargetInfo *Aux) override; diff --git a/clang/test/CodeGen/AMDGPU/nullptr-in-different-address-spaces.cpp b/clang/test/CodeGen/AMDGPU/nullptr-in-different-address-spaces.cpp new file mode 100644 index 0000000000000..98fa4b51e3131 --- /dev/null +++ b/clang/test/CodeGen/AMDGPU/nullptr-in-different-address-spaces.cpp @@ -0,0 +1,57 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx900 -emit-llvm -o - %s | FileCheck %s + +extern __attribute__((address_space(3))) unsigned char * ptr_as3; +extern __attribute__((address_space(5))) unsigned char * ptr_as5; + +// CHECK-LABEL: define dso_local noundef ptr @_Z11get_ptr_as3b( +// CHECK-SAME: i1 noundef zeroext [[V:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RETVAL:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[V_ADDR:%.*]] = alloca i8, align 1, addrspace(5) +// CHECK-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// CHECK-NEXT: [[V_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[V_ADDR]] to ptr +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[V]] to i8 +// CHECK-NEXT: store i8 [[STOREDV]], ptr [[V_ADDR_ASCAST]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[V_ADDR_ASCAST]], align 1 +// CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: br i1 [[LOADEDV]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]] +// CHECK: [[COND_TRUE]]: +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(3), ptr addrspacecast (ptr addrspace(1) @ptr_as3 to ptr), align 4 +// CHECK-NEXT: br label %[[COND_END:.*]] +// CHECK: [[COND_FALSE]]: +// CHECK-NEXT: br label %[[COND_END]] +// CHECK: [[COND_END]]: +// CHECK-NEXT: [[COND:%.*]] = phi ptr addrspace(3) [ [[TMP1]], %[[COND_TRUE]] ], [ addrspacecast (ptr null to ptr addrspace(3)), %[[COND_FALSE]] ] +// CHECK-NEXT: [[COND_ASCAST:%.*]] = addrspacecast ptr addrspace(3) [[COND]] to ptr +// CHECK-NEXT: ret ptr [[COND_ASCAST]] +// +unsigned char *get_ptr_as3(bool v) { + return v ? ptr_as3 : nullptr; +} + +// CHECK-LABEL: define dso_local noundef ptr @_Z11get_ptr_as5b( +// CHECK-SAME: i1 noundef zeroext [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RETVAL:%.*]] = alloca ptr, align 8, addrspace(5) +// CHECK-NEXT: [[V_ADDR:%.*]] = alloca i8, align 1, addrspace(5) +// CHECK-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// CHECK-NEXT: [[V_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[V_ADDR]] to ptr +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[V]] to i8 +// CHECK-NEXT: store i8 [[STOREDV]], ptr [[V_ADDR_ASCAST]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[V_ADDR_ASCAST]], align 1 +// CHECK-NEXT: [[LOADEDV:%.*]] = trunc i8 [[TMP0]] to i1 +// CHECK-NEXT: br i1 [[LOADEDV]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]] +// CHECK: [[COND_TRUE]]: +// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(5), ptr addrspacecast (ptr addrspace(1) @ptr_as5 to ptr), align 4 +// CHECK-NEXT: br label %[[COND_END:.*]] +// CHECK: [[COND_FALSE]]: +// CHECK-NEXT: br label %[[COND_END]] +// CHECK: [[COND_END]]: +// CHECK-NEXT: [[COND:%.*]] = phi ptr addrspace(5) [ [[TMP1]], %[[COND_TRUE]] ], [ addrspacecast (ptr null to ptr addrspace(5)), %[[COND_FALSE]] ] +// CHECK-NEXT: [[COND_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[COND]] to ptr +// CHECK-NEXT: ret ptr [[COND_ASCAST]] +// +unsigned char *get_ptr_as5(bool v) { + return v ? ptr_as5 : nullptr; +} >From 5c9ab8ede9236cdfcb0a602bed617793da881ded Mon Sep 17 00:00:00 2001 From: Shilei Tian <[email protected]> Date: Mon, 12 Jan 2026 16:08:01 -0500 Subject: [PATCH 2/2] resolve comments --- clang/lib/Basic/Targets/AMDGPU.h | 10 ++-------- .../nullptr-in-different-address-spaces.cpp | 4 ++-- llvm/include/llvm/Support/AMDGPUAddrSpace.h | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index 3cb0d5a63ec81..35bca74505b37 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -445,18 +445,12 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { // address space has value 0 but in private and local address space has // value ~0. uint64_t getNullPointerValue(LangAS AS) const override { - // FIXME: Also should handle region. // Check language-specific address spaces if (AS == LangAS::opencl_local || AS == LangAS::opencl_private || AS == LangAS::sycl_local || AS == LangAS::sycl_private) return ~0; - // Also check target address spaces that map to local or private - if (isTargetAddressSpace(AS)) { - unsigned TargetAS = toTargetAddressSpace(AS); - if (TargetAS == llvm::AMDGPUAS::LOCAL_ADDRESS || - TargetAS == llvm::AMDGPUAS::PRIVATE_ADDRESS) - return ~0; - } + if (isTargetAddressSpace(AS)) + return llvm::AMDGPU::getNullPointerValue(toTargetAddressSpace(AS)); return 0; } diff --git a/clang/test/CodeGen/AMDGPU/nullptr-in-different-address-spaces.cpp b/clang/test/CodeGen/AMDGPU/nullptr-in-different-address-spaces.cpp index 98fa4b51e3131..6f00e5e2bfed1 100644 --- a/clang/test/CodeGen/AMDGPU/nullptr-in-different-address-spaces.cpp +++ b/clang/test/CodeGen/AMDGPU/nullptr-in-different-address-spaces.cpp @@ -1,8 +1,8 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 // RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx900 -emit-llvm -o - %s | FileCheck %s -extern __attribute__((address_space(3))) unsigned char * ptr_as3; -extern __attribute__((address_space(5))) unsigned char * ptr_as5; +extern __attribute__((address_space(3))) unsigned char * ptr_as3; // local address space +extern __attribute__((address_space(5))) unsigned char * ptr_as5; // private address space // CHECK-LABEL: define dso_local noundef ptr @_Z11get_ptr_as3b( // CHECK-SAME: i1 noundef zeroext [[V:%.*]]) #[[ATTR0:[0-9]+]] { diff --git a/llvm/include/llvm/Support/AMDGPUAddrSpace.h b/llvm/include/llvm/Support/AMDGPUAddrSpace.h index 0c89512310289..3fe6492584d84 100644 --- a/llvm/include/llvm/Support/AMDGPUAddrSpace.h +++ b/llvm/include/llvm/Support/AMDGPUAddrSpace.h @@ -15,6 +15,8 @@ #ifndef LLVM_SUPPORT_AMDGPUADDRSPACE_H #define LLVM_SUPPORT_AMDGPUADDRSPACE_H +#include <cstdint> + namespace llvm { /// OpenCL uses address spaces to differentiate between /// various memory regions on the hardware. On the CPU @@ -165,6 +167,19 @@ constexpr int mapToDWARFAddrSpace(unsigned LLVMAddrSpace) { return impl::LLVMToDWARFAddrSpaceMapping[LLVMAddrSpace]; return -1; } + +/// Get the null pointer value for the given address space. +constexpr int64_t getNullPointerValue(unsigned AS) { + switch (AS) { + using namespace AMDGPUAS; + case PRIVATE_ADDRESS: + case LOCAL_ADDRESS: + case REGION_ADDRESS: + return -1; + default: + return 0; + } +} } // end namespace AMDGPU } // end namespace llvm _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
