diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index a75f630e1a4c7..9fe8f1d7da780 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3038,9 +3038,20 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { return MakeAddrLValue(CGM.GetAddrOfMSGuidDecl(GD), T, AlignmentSource::Decl); - if (const auto *TPO = dyn_cast(ND)) - return MakeAddrLValue(CGM.GetAddrOfTemplateParamObject(TPO), T, - AlignmentSource::Decl); + if (const auto *TPO = dyn_cast(ND)) { + auto ATPO = CGM.GetAddrOfTemplateParamObject(TPO); + auto AS = getLangASFromTargetAS(ATPO.getAddressSpace()); + + if (AS != T.getAddressSpace()) { + auto TargetAS = getContext().getTargetAddressSpace(T.getAddressSpace()); + auto PtrTy = ATPO.getElementType()->getPointerTo(TargetAS); + auto ASC = getTargetHooks().performAddrSpaceCast( + CGM, ATPO.getPointer(), AS, T.getAddressSpace(), PtrTy); + ATPO = ConstantAddress(ASC, ATPO.getElementType(), ATPO.getAlignment()); + } + + return MakeAddrLValue(ATPO, T, AlignmentSource::Decl); + } llvm_unreachable("Unhandled DeclRefExpr"); } diff --git a/clang/test/CodeGenCXX/template-param-objects-address-space.cpp b/clang/test/CodeGenCXX/template-param-objects-address-space.cpp new file mode 100644 index 0000000000000..b54dcfe77934e --- /dev/null +++ b/clang/test/CodeGenCXX/template-param-objects-address-space.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -std=c++20 %s -emit-llvm -o - | FileCheck %s + +struct S { char buf[32]; }; +template constexpr const char *begin() { return s.buf; } +template constexpr const char *end() { return s.buf + __builtin_strlen(s.buf); } +template constexpr const void *retval() { return &s; } +extern const void *callee(const S*); +template constexpr const void* observable_addr() { return callee(&s); } + +// CHECK: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE]] +// 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 + +// CHECK: @p +// CHECK-SAME: addrspace(1) global ptr addrspacecast (ptr addrspace(1) [[HELLO]] to ptr) +const char *p = begin(); + +// CHECK: @q +// CHECK-SAME: addrspace(1) global ptr addrspacecast (ptr addrspace(1) getelementptr (i8, ptr addrspace(1) [[HELLO]], i64 11) to ptr) +const char *q = end(); + +const void *(*r)() = &retval; + +// CHECK: @s +// CHECK-SAME: addrspace(1) global ptr null +const void *s = observable_addr(); + +// CHECK: define linkonce_odr noundef ptr @_Z6retvalIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv() +// CHECK: ret ptr addrspacecast (ptr addrspace(1) [[HELLO]] to ptr) + +// CHECK: define linkonce_odr noundef ptr @_Z15observable_addrIXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEEEPKvv() +// CHECK: %call = call noundef ptr @_Z6calleePK1S(ptr noundef addrspacecast (ptr addrspace(1) [[HELLO]] to ptr)) +// CHECK: declare noundef ptr @_Z6calleePK1S(ptr noundef)