[clang] baf2ed3 - [SystemZ][Clang]Use the function name from the source for name PPA1 (#209215)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 13 11:47:41 PDT 2026
Author: Sean Perry
Date: 2026-10-13T14:47:35-04:00
New Revision: baf2ed3d286a25f7fdd1dd963d3fe1df9c2cdc15
URL: https://github.com/llvm/llvm-project/commit/baf2ed3d286a25f7fdd1dd963d3fe1df9c2cdc15
DIFF: https://github.com/llvm/llvm-project/commit/baf2ed3d286a25f7fdd1dd963d3fe1df9c2cdc15.diff
LOG: [SystemZ][Clang]Use the function name from the source for name PPA1 (#209215)
For z/OS, the behaviour for asm labels and #pragma map (PR coming
shortly) is to use the function name in the source code in the PPA1.
The zos-ppa1-name attribute behaviour for each function will be:
- if -mno-zos-ppa1-name is present use an empty string
- else if function has asm label use the mangled name if asm label
wasn't present
- otherwise don't generate the attribute
Also see https://github.com/llvm/llvm-project/pull/208870 for the llvm
side
Added:
clang/test/CodeGen/SystemZ/zos-ppa1-asm-label.c
clang/test/CodeGen/SystemZ/zos-ppa1-asm-label.cpp
Modified:
clang/include/clang/AST/Mangle.h
clang/lib/AST/Mangle.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/CodeGen/CodeGenModule.h
Removed:
################################################################################
diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h
index d62495095c7e4e..0e0bfef9053f98 100644
--- a/clang/include/clang/AST/Mangle.h
+++ b/clang/include/clang/AST/Mangle.h
@@ -126,6 +126,7 @@ class MangleContext {
/// @{
bool shouldMangleDeclName(const NamedDecl *D);
+ bool shouldMangleDeclNameIgnoringAsmLabel(const NamedDecl *D);
virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
@@ -145,6 +146,7 @@ class MangleContext {
// FIXME: consider replacing raw_ostream & with something like SmallString &.
void mangleName(GlobalDecl GD, raw_ostream &);
+ void mangleNameIgnoringAsmLabel(GlobalDecl GD, raw_ostream &);
virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
bool ElideOverrideInfo, raw_ostream &) = 0;
diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index 76c51b8d9e827e..a11aa02785d090 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -127,6 +127,15 @@ static CCMangling getCallingConvMangling(const ASTContext &Context,
}
bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
+ // Any decl can be declared with __asm("foo") on it, and this takes precedence
+ // over all other naming in the .o file.
+ if (D->hasAttr<AsmLabelAttr>())
+ return true;
+
+ return shouldMangleDeclNameIgnoringAsmLabel(D);
+}
+
+bool MangleContext::shouldMangleDeclNameIgnoringAsmLabel(const NamedDecl *D) {
const ASTContext &ASTContext = getASTContext();
CCMangling CC = getCallingConvMangling(ASTContext, D);
@@ -148,11 +157,6 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
return false;
- // Any decl can be declared with __asm("foo") on it, and this takes precedence
- // over all other naming in the .o file.
- if (D->hasAttr<AsmLabelAttr>())
- return true;
-
// Declarations that don't have identifier names always need to be mangled.
if (isa<MSGuidDecl>(D))
return true;
@@ -243,7 +247,6 @@ static void emitLLDBAsmLabel(llvm::StringRef label, GlobalDecl GD,
}
void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
- const ASTContext &ASTContext = getASTContext();
const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
// Any decl can be declared with __asm("foo") on it, and this takes precedence
@@ -283,6 +286,14 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
return;
}
+ mangleNameIgnoringAsmLabel(GD, Out);
+}
+
+void MangleContext::mangleNameIgnoringAsmLabel(GlobalDecl GD,
+ raw_ostream &Out) {
+ const ASTContext &ASTContext = getASTContext();
+ const NamedDecl *D = cast<NamedDecl>(GD.getDecl());
+
if (auto *GD = dyn_cast<MSGuidDecl>(D))
return mangleMSGuidDecl(GD, Out);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 70586425974872..e5bca359e6a855 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1224,6 +1224,11 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
if (!CGM.getCodeGenOpts().ZOSPPA1Name)
Fn->addFnAttr("zos-ppa1-name", "");
+ else if (getContext().getTargetInfo().getTriple().isOSzOS() && FD &&
+ FD->hasAttr<AsmLabelAttr>()) {
+ std::string SrcName = CGM.getMangledNameIgnoringAsmLabel(GD, FD);
+ Fn->addFnAttr("zos-ppa1-name", SrcName);
+ }
if (CGM.getCodeGenOpts().WarnStackSize != UINT_MAX &&
!CGM.getDiags().isIgnored(diag::warn_fe_backend_frame_larger_than, Loc))
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index bce2106a749884..bf03e10f9fb422 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2541,15 +2541,21 @@ static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
const NamedDecl *ND,
- bool OmitMultiVersionMangling = false) {
+ bool OmitMultiVersionMangling = false,
+ bool IgnoreAsmLabel = false) {
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
MangleContext &MC = CGM.getCXXABI().getMangleContext();
if (!CGM.getModuleNameHash().empty())
MC.needsUniqueInternalLinkageNames();
- bool ShouldMangle = MC.shouldMangleDeclName(ND);
+ bool ShouldMangle = !IgnoreAsmLabel
+ ? MC.shouldMangleDeclName(ND)
+ : MC.shouldMangleDeclNameIgnoringAsmLabel(ND);
if (ShouldMangle)
- MC.mangleName(GD.getWithDecl(ND), Out);
+ if (!IgnoreAsmLabel)
+ MC.mangleName(GD.getWithDecl(ND), Out);
+ else
+ MC.mangleNameIgnoringAsmLabel(GD.getWithDecl(ND), Out);
else {
IdentifierInfo *II = ND->getIdentifier();
assert(II && "Attempt to mangle unnamed decl.");
@@ -2743,6 +2749,14 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
return MangledDeclNames[CanonicalGD] = Result.first->first();
}
+std::string CodeGenModule::getMangledNameIgnoringAsmLabel(GlobalDecl GD,
+ const NamedDecl *ND) {
+ std::string MangledName =
+ getMangledNameImpl(*this, GD, ND, /*OmitMultiVersionMangling=*/false,
+ /*IgnoreAsmLabel=*/true);
+ return MangledName;
+}
+
StringRef CodeGenModule::getBlockMangledName(GlobalDecl GD,
const BlockDecl *BD) {
MangleContext &MangleCtx = getCXXABI().getMangleContext();
@@ -5527,8 +5541,8 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
IFunc = GI;
}
- std::string AliasName = getMangledNameImpl(
- *this, GD, FD, /*OmitMultiVersionMangling=*/true);
+ std::string AliasName =
+ getMangledNameImpl(*this, GD, FD, /*OmitMultiVersionMangling=*/true);
llvm::Constant *AliasFunc = GetGlobalValue(AliasName);
if (!AliasFunc) {
auto *GA = llvm::GlobalAlias::create(DeclTy, AS, Linkage, AliasName,
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index cb1f910366829e..77ed7abc48a9ed 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1541,6 +1541,8 @@ class CodeGenModule : public CodeGenTypeCache {
void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs);
StringRef getMangledName(GlobalDecl GD);
+ std::string getMangledNameIgnoringAsmLabel(GlobalDecl GD,
+ const NamedDecl *ND);
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD);
const GlobalDecl getMangledNameDecl(StringRef);
diff --git a/clang/test/CodeGen/SystemZ/zos-ppa1-asm-label.c b/clang/test/CodeGen/SystemZ/zos-ppa1-asm-label.c
new file mode 100644
index 00000000000000..fec775fc3e4edc
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/zos-ppa1-asm-label.c
@@ -0,0 +1,23 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -emit-llvm -o- -triple s390x-ibm-zos %s |FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o- -triple s390x-ibm-zos -mno-zos-ppa1-name %s |FileCheck --check-prefix=NONAME %s
+void foo() {
+}
+
+void bar() asm("OtherName");
+
+void bar() {
+}
+
+// CHECK:define void @foo() #[[a1:[0-9]+]]
+// CHECK:define void @OtherName() #[[a2:[0-9]+]]
+// CHECK-NOT:attributes #[[a1]] = {{{.*}}"zos-ppa1-name"{{.*}}}
+// CHECK: attributes #[[a2]] = {{{.*}}"zos-ppa1-name"="bar"{{.*}}}
+
+
+// NONAME:define void @foo() #[[a1:[0-9]+]]
+// NONAME:define void @OtherName() #[[a1]]
+// NONAME:attributes #[[a1]] = {{{.*}}"zos-ppa1-name"{{.*}}}
+
+
+
diff --git a/clang/test/CodeGen/SystemZ/zos-ppa1-asm-label.cpp b/clang/test/CodeGen/SystemZ/zos-ppa1-asm-label.cpp
new file mode 100644
index 00000000000000..39bb1e122f939e
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/zos-ppa1-asm-label.cpp
@@ -0,0 +1,23 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -emit-llvm -o- -triple s390x-ibm-zos %s |FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o- -triple s390x-ibm-zos -mno-zos-ppa1-name %s |FileCheck --check-prefix=NONAME %s
+void foo() {
+}
+
+void bar() asm("OtherName");
+
+void bar() {
+}
+
+// CHECK:define void @_Z3foov() #[[a1:[0-9]+]]
+// CHECK:define void @OtherName() #[[a2:[0-9]+]]
+// CHECK-NOT:attributes #[[a1]] = {{{.*}}"zos-ppa1-name"{{.*}}}
+// CHECK: attributes #[[a2]] = {{{.*}}"zos-ppa1-name"="_Z3barv"{{.*}}}
+
+
+// NONAME:define void @_Z3foov() #[[a1:[0-9]+]]
+// NONAME:define void @OtherName() #[[a1]]
+// NONAME:attributes #[[a1]] = {{{.*}}"zos-ppa1-name"{{.*}}}
+
+
+
More information about the cfe-commits
mailing list