Author: Erich Keane Date: 2026-08-11T18:53:46-07:00 New Revision: c402a3b4be9be294fd51058b230a13b0c15547ee
URL: https://github.com/llvm/llvm-project/commit/c402a3b4be9be294fd51058b230a13b0c15547ee DIFF: https://github.com/llvm/llvm-project/commit/c402a3b4be9be294fd51058b230a13b0c15547ee.diff LOG: [CIR] Fix a linking problem with a abi_tag deduced lambda (#215702) This showed up in self build, but only happens when there is a lambda with a deduced return type inside another lambda, that returns a type with an abi_tag on it (std::string in this case). The problem was that we weren't pulling our mangled name out of the cache, and instead were re-calculating it every time. This takes code effectively-exactly from classic-codegen an d puts it into CIRGenModule.cpp Note the teest is a little fragile for the reproducer, so it needs to be its own file. Also, there are some parts that are not necessary in it to reproduce (the 'i' in particular) because this avoids us having 'padded' lambdas, which results in a call-conv NYI. I considered disabling that, but it is more work to go back and un-do that flag later, than to just deal with an extra 'i' for the near future. Added: clang/test/CIR/CodeGen/lambda-generic-in-cxx11abi-lambda.cpp Modified: clang/lib/CIR/CodeGen/CIRGenModule.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 3aa381fec5a70..b55dc71969c74 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -2789,6 +2789,16 @@ StringRef CIRGenModule::getMangledName(GlobalDecl gd) { } } + // In CUDA/HIP device compilation with -fgpu-rdc, the mangled name of a + // static device variable depends on whether the variable is referenced by + // a host or device host function. Therefore the mangled name cannot be + // cached. + if (!langOpts.CUDAIsDevice || !astContext.mayExternalize(gd.getDecl())) { + auto foundName = mangledDeclNames.find(canonicalGd); + if (foundName != mangledDeclNames.end()) + return foundName->second; + } + // Keep the first result in the case of a mangling collision. const auto *nd = cast<NamedDecl>(gd.getDecl()); std::string mangledName = getMangledNameImpl(*this, gd, nd); diff --git a/clang/test/CIR/CodeGen/lambda-generic-in-cxx11abi-lambda.cpp b/clang/test/CIR/CodeGen/lambda-generic-in-cxx11abi-lambda.cpp new file mode 100644 index 0000000000000..34d037935b0fb --- /dev/null +++ b/clang/test/CIR/CodeGen/lambda-generic-in-cxx11abi-lambda.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -o - %s | FileCheck %s --check-prefix=CIR +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -o - %s | FileCheck %s --check-prefix=LLVM +// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=OGCG + +struct __attribute__((__abi_tag__("cxx11"))) S { int i;}; + +template <typename F> auto f(int c, F fn) { return fn(c); } +S s(int) { return {}; } + +void g() { + // The 'i' isn't required to reproduce, but it prevents an NYI in call-conv lowering. + int i; + auto r = [i] { return s(f(1, [i](auto x) { return x; })); }(); + (void)r; +} +int main() { g(); } + +// CIR-LABEL: cir.func no_inline lambda internal private dso_local @_ZZZ1gvENK3$_0clEvENKUlT_E_clIiEEDaS0_ +// LLVM-LABEL: define internal noundef i32 @"_ZZZ1gvENK3$_0clEvENKUlT_E_clIiEEDaS0_" + +// Testing to make sure we emit this in particular as a definition. +// CIR-LABEL: cir.func no_inline internal private dso_local @_Z1fIZZ1gvENK3$_0clEvEUlT_E_EDaiS1_ +// CIR-NOT: cir.func +// CIR: cir.call @_ZZZ1gvENK3$_0clEvENKUlT_E_clIiEEDaS0_ + +// LLVM-LABEL: define internal noundef i32 @"_Z1fIZZ1gvENK3$_0clEvEUlT_E_EDaiS1_" +// LLVM-NOT: define +// LLVM: call noundef i32 @"_ZZZ1gvENK3$_0clEvENKUlT_E_clIiEEDaS0_" + +// CIR-LABEL: cir.func no_inline lambda internal private dso_local @_ZZ1gvENK3$_0clB5cxx11Ev +// CIR-NOT: define +// CIR: %[[ONE:.*]] = cir.const #cir.int<1> +// CIR: cir.call @_Z1fIZZ1gvENK3$_0clEvEUlT_E_EDaiS1_(%[[ONE]], %{{.*}}) + +// LLVM-LABEL: define internal i32 @"_ZZ1gvENK3$_0clB5cxx11Ev"( +// LLVM-NOT: define +// LLVM: call noundef i32 @"_Z1fIZZ1gvENK3$_0clEvEUlT_E_EDaiS1_"(i32 noundef 1, i32 %{{.*}}) + +// NOTE: Only diff erence between these is the ordering being reversed. +// OGCG-LABEL: define internal i32 @"_ZZ1gvENK3$_0clB5cxx11Ev"( +// OGCG-NOT: define +// OGCG: call noundef i32 @"_Z1fIZZ1gvENK3$_0clEvEUlT_E_EDaiS1_"(i32 noundef 1, i32 %{{.*}}) + +// Testing to make sure we emit this in particular as a definition. +// OGCG-LABEL: define internal noundef i32 @"_Z1fIZZ1gvENK3$_0clEvEUlT_E_EDaiS1_" +// OGCG-NOT: define +// OGCG: call noundef i32 @"_ZZZ1gvENK3$_0clEvENKUlT_E_clIiEEDaS0_" + +// OGCG-LABEL: define internal noundef i32 @"_ZZZ1gvENK3$_0clEvENKUlT_E_clIiEEDaS0_" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
