Skip to content

Commit 57a0416

Browse files
authored
[clang][CodeGen] Handle template parameter objects with explicit address spaces (llvm#69266)
For certain cases (e.g. when their address is observable at run time) it is necessary to provide physical backing for non-type template parameter objects. Said backing comes in the form of a global variable. For certain targets (e.g. AMDGPU), which use a non-default address space for globals, this can lead to an issue when referencing said global in address space agnostic languages (such as HIP), for example when passing them to a function. This patch addresses this issue by inserting an address space cast iff there is an address space mismatch between the type of a reference expression and the address space of the backing global. A test is also added.
1 parent 97e16da commit 57a0416

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3038,9 +3038,20 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
30383038
return MakeAddrLValue(CGM.GetAddrOfMSGuidDecl(GD), T,
30393039
AlignmentSource::Decl);
30403040

3041-
if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND))
3042-
return MakeAddrLValue(CGM.GetAddrOfTemplateParamObject(TPO), T,
3043-
AlignmentSource::Decl);
3041+
if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
3042+
auto ATPO = CGM.GetAddrOfTemplateParamObject(TPO);
3043+
auto AS = getLangASFromTargetAS(ATPO.getAddressSpace());
3044+
3045+
if (AS != T.getAddressSpace()) {
3046+
auto TargetAS = getContext().getTargetAddressSpace(T.getAddressSpace());
3047+
auto PtrTy = ATPO.getElementType()->getPointerTo(TargetAS);
3048+
auto ASC = getTargetHooks().performAddrSpaceCast(
3049+
CGM, ATPO.getPointer(), AS, T.getAddressSpace(), PtrTy);
3050+
ATPO = ConstantAddress(ASC, ATPO.getElementType(), ATPO.getAlignment());
3051+
}
3052+
3053+
return MakeAddrLValue(ATPO, T, AlignmentSource::Decl);
3054+
}
30443055

30453056
llvm_unreachable("Unhandled DeclRefExpr");
30463057
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -std=c++20 %s -emit-llvm -o - | FileCheck %s
2+
3+
struct S { char buf[32]; };
4+
template<S s> constexpr const char *begin() { return s.buf; }
5+
template<S s> constexpr const char *end() { return s.buf + __builtin_strlen(s.buf); }
6+
template<S s> constexpr const void *retval() { return &s; }
7+
extern const void *callee(const S*);
8+
template<S s> constexpr const void* observable_addr() { return callee(&s); }
9+
10+
// CHECK: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE]]
11+
// CHECK-SAME: = linkonce_odr addrspace(1) constant { <{ [11 x i8], [21 x i8] }> } { <{ [11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer }> }, comdat
12+
13+
// CHECK: @p
14+
// CHECK-SAME: addrspace(1) global ptr addrspacecast (ptr addrspace(1) [[HELLO]] to ptr)
15+
const char *p = begin<S{"hello world"}>();
16+
17+
// CHECK: @q
18+
// CHECK-SAME: addrspace(1) global ptr addrspacecast (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) [[HELLO]], i64 11) to ptr)
19+
const char *q = end<S{"hello world"}>();
20+
21+
const void *(*r)() = &retval<S{"hello world"}>;
22+
23+
// CHECK: @s
24+
// CHECK-SAME: addrspace(1) global ptr null
25+
const void *s = observable_addr<S{"hello world"}>();
26+
27+
// CHECK: define linkonce_odr noundef ptr @_Z6retvalIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
28+
// CHECK: ret ptr addrspacecast (ptr addrspace(1) [[HELLO]] to ptr)
29+
30+
// CHECK: define linkonce_odr noundef ptr @_Z15observable_addrIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv()
31+
// CHECK: %call = call noundef ptr @_Z6calleePK1S(ptr noundef addrspacecast (ptr addrspace(1) [[HELLO]] to ptr))
32+
// CHECK: declare noundef ptr @_Z6calleePK1S(ptr noundef)

0 commit comments

Comments
 (0)