[llvm] [SystemZ][z/OS] Use a function descriptor for external functions in initializers (PR #226682)

via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 26 04:48:50 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-systemz

Author: MMS IT GmbH (mms-it-ch)

<details>
<summary>Changes</summary>

The address of an external function in a static initializer was emitted as a V-con, i.e. the entry point, while an XPLINK function pointer must point to a function descriptor. A call through such a pointer loads the environment and entry point from the machine code of the function. Create a descriptor in the ADA for external functions as well, as is already done for internal functions and for constructor/destructor lists (`emitXXStructorList`).

`zos-lower-constant.ll` is updated: the pointer to the external function `bar` now points to its descriptor in the ADA.

A minimal program (`int (*p)(void) = ext;` called from `main`) ended with S0C6 at address `0707070707070707` on z/OS 3.1; with this change it returns the expected value.

Tests: `llvm-lit test/CodeGen/SystemZ test/MC/SystemZ test/MC/GOFF` passes (1303 passed, 19 unsupported).

Fixes #<!-- -->226658.

Assisted-by: Claude Code (Anthropic)

🤖 Generated with [Claude Code](https://claude.com/claude-code)


---
Full diff: https://github.com/llvm/llvm-project/pull/226682.diff


2 Files Affected:

- (modified) llvm/lib/Target/SystemZ/SystemZXPLINKAsmPrinter.cpp (+3-5) 
- (modified) llvm/test/CodeGen/SystemZ/zos-lower-constant.ll (+4-1) 


``````````diff
diff --git a/llvm/lib/Target/SystemZ/SystemZXPLINKAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZXPLINKAsmPrinter.cpp
index 3ab3dfc4a0bcb..7e69a53838262 100644
--- a/llvm/lib/Target/SystemZ/SystemZXPLINKAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZXPLINKAsmPrinter.cpp
@@ -775,11 +775,9 @@ const MCExpr *SystemZXPLINKAsmPrinter::lowerConstant(const Constant *CV,
 
   if (IsFunc) {
     OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
-    if (FV->hasExternalLinkage())
-      return MCSpecifierExpr::create(MCSymbolRefExpr::create(Sym, OutContext),
-                                     SystemZ::S_VCon, OutContext);
-    // Trigger creation of function descriptor in ADA for internal
-    // functions.
+    // A function pointer must point to a function descriptor. Trigger
+    // creation of a function descriptor in the ADA, for internal and external
+    // functions alike (a V-con would yield the entry point instead).
     unsigned Disp = ADATable.insert(Sym, SystemZII::MO_ADA_DIRECT_FUNC_DESC);
     return MCBinaryExpr::createAdd(
         MCSpecifierExpr::create(
diff --git a/llvm/test/CodeGen/SystemZ/zos-lower-constant.ll b/llvm/test/CodeGen/SystemZ/zos-lower-constant.ll
index 64a51f8e43582..61d4653540d59 100644
--- a/llvm/test/CodeGen/SystemZ/zos-lower-constant.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-lower-constant.ll
@@ -5,9 +5,12 @@
 ; CHECK: func_s CSECT
 ; CHECK: DC AD(AD({{.*}}#S)+XL8'0')
 ; CHECK: func_e CSECT
-; CHECK: DC VD(bar)
+; CHECK: DC AD(AD({{.*}}#S)+XL8'16')
 ; CHECK: DC RD(foo)
 ; CHECK-NEXT: DC VD(foo)
+; CHECK-NEXT: * Offset 16 function descriptor of bar
+; CHECK-NEXT: DC RD(bar)
+; CHECK-NEXT: DC VD(bar)
 @x = hidden global i32 4077, align 4
 @y = hidden global ptr @x, align 8
 @func_s = hidden global ptr @foo, align 8

``````````

</details>


https://github.com/llvm/llvm-project/pull/226682


More information about the llvm-commits mailing list