Skip to content

Commit 653e99e

Browse files
committed
[SYCL] Fix Lambda Mangling in Namespace-Scope Variable Initializers.
1 parent f722fcf commit 653e99e

File tree

6 files changed

+153
-4
lines changed

6 files changed

+153
-4
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9183,7 +9183,13 @@ class Sema final : public SemaBase {
91839183
};
91849184

91859185
/// Compute the mangling number context for a lambda expression or
9186-
/// block literal. Also return the extra mangling decl if any.
9186+
/// block literal that appears in the specified declaration context in
9187+
/// consideration of the current expression evaluation and template
9188+
/// instantiation contexts. If the mangling context requires external linkage,
9189+
/// then a mangling number context is returned in the first tuple
9190+
/// element. If the mangling context is non-normal (specialized for
9191+
/// lambda and block types relative to other entities), the overriding
9192+
/// declaration is returned in the second tuple element.
91879193
///
91889194
/// \param DC - The DeclContext containing the lambda expression or
91899195
/// block literal.

clang/lib/AST/ASTContext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13356,6 +13356,7 @@ MangleNumberingContext &
1335613356
ASTContext::getManglingNumberContext(const DeclContext *DC) {
1335713357
assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C.
1335813358
std::unique_ptr<MangleNumberingContext> &MCtx = MangleNumberingContexts[DC];
13359+
DC = DC->getPrimaryContext();
1335913360
if (!MCtx)
1336013361
MCtx = createMangleNumberingContext();
1336113362
return *MCtx;

clang/lib/Sema/SemaLambda.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,14 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC) {
356356
return std::make_tuple(&Context.getManglingNumberContext(DC), nullptr);
357357
}
358358

359-
return std::make_tuple(nullptr, nullptr);
359+
if (ManglingContextDecl) {
360+
// Lambdas defined in the initializer of a local variable are mangled
361+
// in the enclosing function context.
362+
if (isa<VarDecl>(ManglingContextDecl) &&
363+
!cast<VarDecl>(ManglingContextDecl)->hasGlobalStorage())
364+
ManglingContextDecl = nullptr;
365+
}
366+
return std::make_tuple(nullptr, ManglingContextDecl);
360367
}
361368

362369
case NonInlineInModulePurview:
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// RUN: %clang_cc1 -O0 -triple x86_64-unknown-unknown \
2+
// RUN: -emit-llvm %s -o - | FileCheck %s
3+
4+
// RUN: %clang_cc1 -O0 -triple x86_64-pc-windows-msvc \
5+
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=MSVC
6+
7+
namespace QL {
8+
auto dg1 = [] { return 1; };
9+
inline auto dg_inline1 = [] { return 1; };
10+
}
11+
12+
namespace QL {
13+
auto dg2 = [] { return 2; };
14+
template<int N>
15+
auto dg_template = [] { return N; };
16+
}
17+
18+
using namespace QL;
19+
template<typename T>
20+
void f(T t) {
21+
t();
22+
}
23+
24+
void g() {
25+
f(dg1);
26+
f(dg2);
27+
f(dg_inline1);
28+
f(dg_template<3>);
29+
}
30+
31+
// CHECK: @_ZN2QL3dg1E = internal global %class.anon undef, align 1
32+
// CHECK: @_ZN2QL3dg2E = internal global %class.anon.0 undef, align 1
33+
// CHECK: @_ZN2QL10dg_inline1E = linkonce_odr global %class.anon.2 undef, comdat, align 1
34+
// CHECK: @_ZN2QL11dg_templateILi3EEE = linkonce_odr global %class.anon.4 undef, comdat, align 1
35+
36+
// MSVC: @"?dg1@QL@@3V<lambda_0>@1@A" = internal global %class.anon undef, align 1
37+
// MSVC: @"?dg2@QL@@3V<lambda_1>@1@A" = internal global %class.anon.0 undef, align 1
38+
// MSVC: @"?dg_inline1@QL@@3V<lambda_1>@01@A" = linkonce_odr dso_local global %class.anon.2 undef, comdat, align 1
39+
// MSVC: @"??$dg_template@$02@QL@@3V<lambda_1>@01@A" = linkonce_odr dso_local global %class.anon.4 undef, comdat, align 1
40+
41+
42+
// CHECK: define internal void @"_Z1fIN2QL3$_0EEvT_"
43+
// CHECK: call noundef i32 @"_ZNK2QL3$_0clEv"
44+
// CHECK: define internal void @"_Z1fIN2QL3$_1EEvT_"
45+
// CHECK: define linkonce_odr void @_Z1fIN2QL10dg_inline1MUlvE_EEvT_
46+
// CHECK: call noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
47+
// CHECK: define linkonce_odr void @_Z1fIN2QL11dg_templateILi3EEMUlvE_EEvT_
48+
// CHECK: call noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv
49+
// CHECK: define internal noundef i32 @"_ZNK2QL3$_0clEv"
50+
// CHECK: define internal noundef i32 @"_ZNK2QL3$_1clEv"
51+
// CHECK: define linkonce_odr noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
52+
// CHECK: define linkonce_odr noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv
53+
54+
// MSVC: define linkonce_odr dso_local void @"??$f@V<lambda_1>@dg_inline1@QL@@@@YAXV<lambda_1>@dg_inline1@QL@@@Z"
55+
// MSVC: call noundef i32 @"??R<lambda_1>@dg_inline1@QL@@QEBA?A?<auto>@@XZ"
56+
// MSVC: define linkonce_odr dso_local void @"??$f@V<lambda_1>@?$dg_template@$02@QL@@@@YAXV<lambda_1>@?$dg_template@$02@QL@@@Z"
57+
// MSVC: call noundef i32 @"??R<lambda_1>@?$dg_template@$02@QL@@QEBA?A?<auto>@@XZ"
58+
// MSVC: define internal noundef i32 @"??R<lambda_0>@QL@@QEBA?A?<auto>@@XZ"
59+
// MSVC: define internal noundef i32 @"??R<lambda_1>@QL@@QEBA?A?<auto>@@XZ"
60+
// MSVC: define linkonce_odr dso_local noundef i32 @"??R<lambda_1>@dg_inline1@QL@@QEBA?A?<auto>@@XZ"
61+
// MSVC: define linkonce_odr dso_local noundef i32 @"??R<lambda_1>@?$dg_template@$02@QL@@QEBA?A?<auto>@@XZ"

clang/test/CodeGenCUDA/anon-ns.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
2626

2727
// HIP-DAG: define weak_odr {{.*}}void @[[KERN:_ZN12_GLOBAL__N_16kernelEv\.intern\.b04fd23c98500190]](
2828
// HIP-DAG: define weak_odr {{.*}}void @[[KTX:_Z2ktIN12_GLOBAL__N_11XEEvT_\.intern\.b04fd23c98500190]](
29-
// HIP-DAG: define weak_odr {{.*}}void @[[KTL:_Z2ktIN12_GLOBAL__N_1UlvE_EEvT_\.intern\.b04fd23c98500190]](
29+
// HIP-DAG: define weak_odr {{.*}}void @[[KTL:_Z2ktIN12_GLOBAL__N_16lambdaMUlvE_EEvT_.intern\.b04fd23c98500190]](
3030
// HIP-DAG: @[[VM:_ZN12_GLOBAL__N_12vmE\.static\.b04fd23c98500190]] = addrspace(1) externally_initialized global
3131
// HIP-DAG: @[[VC:_ZN12_GLOBAL__N_12vcE\.static\.b04fd23c98500190]] = addrspace(4) externally_initialized constant
3232
// HIP-DAG: @[[VT:_Z2vtIN12_GLOBAL__N_11XEE\.static\.b04fd23c98500190]] = addrspace(1) externally_initialized global
3333

3434
// CUDA-DAG: define weak_odr {{.*}}void @[[KERN:_ZN12_GLOBAL__N_16kernelEv__intern__b04fd23c98500190]](
3535
// CUDA-DAG: define weak_odr {{.*}}void @[[KTX:_Z2ktIN12_GLOBAL__N_11XEEvT___intern__b04fd23c98500190]](
36-
// CUDA-DAG: define weak_odr {{.*}}void @[[KTL:_Z2ktIN12_GLOBAL__N_1UlvE_EEvT___intern__b04fd23c98500190]](
36+
// CUDA-DAG: define weak_odr {{.*}}void @[[KTL:_Z2ktIN12_GLOBAL__N_16lambdaMUlvE_EEvT___intern__b04fd23c98500190]](
3737
// CUDA-DAG: @[[VC:_ZN12_GLOBAL__N_12vcE__static__b04fd23c98500190]] = addrspace(4) externally_initialized constant
3838
// CUDA-DAG: @[[VT:_Z2vtIN12_GLOBAL__N_11XEE__static__b04fd23c98500190]] = addrspace(1) externally_initialized global
3939

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -O0 -triple spirv64-unknown-unknown \
2+
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=DEVICE
3+
4+
// RUN: %clang_cc1 -fsycl-is-host -O0 -triple spirv64-unknown-unknown \
5+
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=HOST
6+
7+
// RUN: %clang_cc1 -fsycl-is-device -emit-llvm \
8+
// RUN: -aux-triple x86_64-pc-windows-msvc -triple spir64-unknown--unknown \
9+
// RUN: %s -o - | FileCheck %s --check-prefix=MSVC
10+
11+
namespace QL {
12+
auto dg1 = [] { return 1; };
13+
inline auto dg_inline1 = [] { return 1; };
14+
}
15+
16+
namespace QL {
17+
auto dg2 = [] { return 2; };
18+
template<int N>
19+
auto dg_template = [] { return N; };
20+
}
21+
22+
using namespace QL;
23+
template<typename T>
24+
[[clang::sycl_kernel_entry_point(T)]] void f(T t) {
25+
t();
26+
}
27+
28+
void g() {
29+
f(dg1);
30+
f(dg2);
31+
f(dg_inline1);
32+
f(dg_template<3>);
33+
}
34+
35+
// HOST: @_ZN2QL3dg1E = internal global %class.anon undef, align 1
36+
// HOST: @_ZN2QL3dg2E = internal global %class.anon.0 undef, align 1
37+
// HOST: @_ZN2QL10dg_inline1E = linkonce_odr global %class.anon.2 undef, comdat, align 1
38+
// HOST: @_ZN2QL11dg_templateILi3EEE = linkonce_odr global %class.anon.4 undef, comdat, align 1
39+
40+
// DEVICE: define spir_kernel void @_ZTSN2QL3dg1MUlvE_E
41+
// DEVICE: call spir_func noundef i32 @_ZNK2QL3dg1MUlvE_clEv
42+
// DEVICE: define internal spir_func noundef i32 @_ZNK2QL3dg1MUlvE_clEv
43+
// DEVICE: define spir_kernel void @_ZTSN2QL3dg2MUlvE_E
44+
// DEVICE: call spir_func noundef i32 @_ZNK2QL3dg2MUlvE_clEv
45+
// DEVICE: define internal spir_func noundef i32 @_ZNK2QL3dg2MUlvE_clEv
46+
// DEVICE: define spir_kernel void @_ZTSN2QL10dg_inline1MUlvE_E
47+
// DEVICE: call spir_func noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
48+
// DEVICE: define linkonce_odr spir_func noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
49+
// DEVICE: define spir_kernel void @_ZTSN2QL11dg_templateILi3EEMUlvE_E
50+
// DEVICE: call spir_func noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv
51+
// DEVICE: define linkonce_odr spir_func noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv
52+
53+
// HOST: define spir_func void @_Z1gv
54+
// HOST: call spir_func void @_Z1fIN2QL3dg1MUlvE_EEvT_
55+
// HOST: call spir_func void @_Z1fIN2QL3dg2MUlvE_EEvT_
56+
// HOST: call spir_func void @_Z1fIN2QL10dg_inline1MUlvE_EEvT_
57+
// HOST: call spir_func void @_Z1fIN2QL11dg_templateILi3EEMUlvE_EEvT_
58+
// HOST: define internal spir_func void @_Z1fIN2QL3dg1MUlvE_EEvT
59+
// HOST: define internal spir_func void @_Z1fIN2QL3dg2MUlvE_EEvT_
60+
// HOST: define linkonce_odr spir_func void @_Z1fIN2QL10dg_inline1MUlvE_EEvT_
61+
// HOST: define linkonce_odr spir_func void @_Z1fIN2QL11dg_templateILi3EEMUlvE_EEvT_
62+
63+
// MSVC: define dso_local spir_kernel void @_ZTSN2QL3dg1MUlvE_E
64+
// MSVC: call spir_func noundef i32 @_ZNK2QL3dg1MUlvE_clEv
65+
// MSVC: define internal spir_func noundef i32 @_ZNK2QL3dg1MUlvE_clEv
66+
// MSVC: define dso_local spir_kernel void @_ZTSN2QL3dg2MUlvE_E
67+
// MSVC: call spir_func noundef i32 @_ZNK2QL3dg2MUlvE_clEv
68+
// MSVC: define internal spir_func noundef i32 @_ZNK2QL3dg2MUlvE_clEv
69+
// MSVC: define dso_local spir_kernel void @_ZTSN2QL10dg_inline1MUlvE_E
70+
// MSVC: call spir_func noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
71+
// MSVC: define linkonce_odr spir_func noundef i32 @_ZNK2QL10dg_inline1MUlvE_clEv
72+
// MSVC: define dso_local spir_kernel void @_ZTSN2QL11dg_templateILi3EEMUlvE_E
73+
// MSVC: call spir_func noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv
74+
// MSVC: define linkonce_odr spir_func noundef i32 @_ZNK2QL11dg_templateILi3EEMUlvE_clEv

0 commit comments

Comments
 (0)