Skip to content

Commit 30596a0

Browse files
authored
[Clang][AMDGPU] Get correct nullptr value for AS3 and AS5 (#175610)
1 parent 12ecbfb commit 30596a0

File tree

3 files changed

+77
-5
lines changed

3 files changed

+77
-5
lines changed

clang/lib/Basic/Targets/AMDGPU.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -445,11 +445,13 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
445445
// address space has value 0 but in private and local address space has
446446
// value ~0.
447447
uint64_t getNullPointerValue(LangAS AS) const override {
448-
// FIXME: Also should handle region.
449-
return (AS == LangAS::opencl_local || AS == LangAS::opencl_private ||
450-
AS == LangAS::sycl_local || AS == LangAS::sycl_private)
451-
? ~0
452-
: 0;
448+
// Check language-specific address spaces
449+
if (AS == LangAS::opencl_local || AS == LangAS::opencl_private ||
450+
AS == LangAS::sycl_local || AS == LangAS::sycl_private)
451+
return ~0;
452+
if (isTargetAddressSpace(AS))
453+
return llvm::AMDGPU::getNullPointerValue(toTargetAddressSpace(AS));
454+
return 0;
453455
}
454456

455457
void setAuxTarget(const TargetInfo *Aux) override;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6
2+
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx900 -O1 -emit-llvm -o - %s | FileCheck %s
3+
4+
extern __attribute__((address_space(3))) unsigned char * ptr_as3; // local address space
5+
extern __attribute__((address_space(5))) unsigned char * ptr_as5; // private address space
6+
7+
// CHECK-LABEL: define dso_local noundef ptr @_Z11get_ptr_as3b(
8+
// CHECK-SAME: i1 noundef zeroext [[V:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
9+
// CHECK-NEXT: [[ENTRY:.*:]]
10+
// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(3), ptr addrspace(1) @ptr_as3, align 4
11+
// CHECK-NEXT: [[TMP1:%.*]] = select i1 [[V]], ptr addrspace(3) [[TMP0]], ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3))
12+
// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(3) [[TMP1]] to ptr
13+
// CHECK-NEXT: ret ptr [[TMP2]]
14+
//
15+
unsigned char *get_ptr_as3(bool v) {
16+
return v ? ptr_as3 : nullptr;
17+
}
18+
19+
// CHECK-LABEL: define dso_local noundef ptr @_Z20get_ptr_as3_with_tmpb(
20+
// CHECK-SAME: i1 noundef zeroext [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
21+
// CHECK-NEXT: [[ENTRY:.*:]]
22+
// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(3), ptr addrspace(1) @ptr_as3, align 4
23+
// CHECK-NEXT: [[TMP1:%.*]] = select i1 [[V]], ptr addrspace(3) [[TMP0]], ptr addrspace(3) addrspacecast (ptr null to ptr addrspace(3))
24+
// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(3) [[TMP1]] to ptr
25+
// CHECK-NEXT: ret ptr [[TMP2]]
26+
//
27+
unsigned char *get_ptr_as3_with_tmp(bool v) {
28+
unsigned char *tmp = nullptr;
29+
return v ? ptr_as3 : tmp;
30+
}
31+
32+
// CHECK-LABEL: define dso_local noundef ptr @_Z11get_ptr_as5b(
33+
// CHECK-SAME: i1 noundef zeroext [[V:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
34+
// CHECK-NEXT: [[ENTRY:.*:]]
35+
// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(5), ptr addrspace(1) @ptr_as5, align 4
36+
// CHECK-NEXT: [[TMP1:%.*]] = select i1 [[V]], ptr addrspace(5) [[TMP0]], ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5))
37+
// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(5) [[TMP1]] to ptr
38+
// CHECK-NEXT: ret ptr [[TMP2]]
39+
//
40+
unsigned char *get_ptr_as5(bool v) {
41+
return v ? ptr_as5 : nullptr;
42+
}
43+
44+
// CHECK-LABEL: define dso_local noundef ptr @_Z20get_ptr_as5_with_tmpb(
45+
// CHECK-SAME: i1 noundef zeroext [[V:%.*]]) local_unnamed_addr #[[ATTR1]] {
46+
// CHECK-NEXT: [[ENTRY:.*:]]
47+
// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(5), ptr addrspace(1) @ptr_as5, align 4
48+
// CHECK-NEXT: [[TMP1:%.*]] = select i1 [[V]], ptr addrspace(5) [[TMP0]], ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5))
49+
// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(5) [[TMP1]] to ptr
50+
// CHECK-NEXT: ret ptr [[TMP2]]
51+
//
52+
unsigned char *get_ptr_as5_with_tmp(bool v) {
53+
unsigned char *tmp = nullptr;
54+
return v ? ptr_as5 : tmp;
55+
}

llvm/include/llvm/Support/AMDGPUAddrSpace.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#ifndef LLVM_SUPPORT_AMDGPUADDRSPACE_H
1616
#define LLVM_SUPPORT_AMDGPUADDRSPACE_H
1717

18+
#include <cstdint>
19+
1820
namespace llvm {
1921
/// OpenCL uses address spaces to differentiate between
2022
/// various memory regions on the hardware. On the CPU
@@ -165,6 +167,19 @@ constexpr int mapToDWARFAddrSpace(unsigned LLVMAddrSpace) {
165167
return impl::LLVMToDWARFAddrSpaceMapping[LLVMAddrSpace];
166168
return -1;
167169
}
170+
171+
/// Get the null pointer value for the given address space.
172+
constexpr int64_t getNullPointerValue(unsigned AS) {
173+
switch (AS) {
174+
using namespace AMDGPUAS;
175+
case PRIVATE_ADDRESS:
176+
case LOCAL_ADDRESS:
177+
case REGION_ADDRESS:
178+
return -1;
179+
default:
180+
return 0;
181+
}
182+
}
168183
} // end namespace AMDGPU
169184

170185
} // end namespace llvm

0 commit comments

Comments
 (0)