[clang] [llvm] [SystemZ, Clang] Enable verification of int args extensions by default. (PR #223755)
Jonas Paulsson via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 15 09:45:55 PDT 2026
https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/223755
>From 8d00bdd2f5ae3c976ea9d76baea06b2f1e08dc77 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Tue, 15 Sep 2026 18:34:54 +0200
Subject: [PATCH 1/2] [SystemZ, Clang] Enable verification of integer args
extensions by default.
This has been temporarily disabled behind a CL option with hopes to enable it
by default globally, which unfortunately did not yet seem like a good idea.
At least now the Clang frontend will verify this always, and hopefully more
frontends will enable this over time.
---
clang/lib/CodeGen/BackendUtil.cpp | 1 +
.../CodeGen/SystemZ/systemz-abi-intargs.c | 28 ++++++++++++++
llvm/include/llvm/Target/TargetOptions.h | 7 ++--
.../Target/SystemZ/SystemZISelLowering.cpp | 38 ++++++++++---------
llvm/lib/Target/SystemZ/SystemZISelLowering.h | 1 +
llvm/tools/llc/lib/llcdriver.cpp | 4 --
6 files changed, 53 insertions(+), 26 deletions(-)
create mode 100644 clang/test/CodeGen/SystemZ/systemz-abi-intargs.c
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 9d8fd319f6f17..ef92b27b461a1 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -523,6 +523,7 @@ static bool initTargetOptions(const CompilerInstance &CI,
Options.MCOptions.PPCUseFullRegisterNames =
CodeGenOpts.PPCUseFullRegisterNames;
Options.MisExpect = CodeGenOpts.MisExpect;
+ Options.VerifyArgABICompliance = true;
return true;
}
diff --git a/clang/test/CodeGen/SystemZ/systemz-abi-intargs.c b/clang/test/CodeGen/SystemZ/systemz-abi-intargs.c
new file mode 100644
index 0000000000000..1b9ec7776c02e
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/systemz-abi-intargs.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple s390x-linux-gnu -S -O3 %s -o - \
+// RUN: -mllvm -debug-only=systemz-lower 2>&1 | FileCheck %s
+//
+// REQUIRES: systemz-registered-target, asserts
+//
+// Check that clang verifies the extensions of narrow integer arguments by default.
+
+int __attribute__ ((noinline)) foo(int Arg, unsigned Arg2) {
+ return Arg + Arg2;
+}
+
+int fun(short *Arg, unsigned char *Arg2) {
+ return foo(*Arg, *Arg2);
+}
+
+// CHECK: Return argument verified as ABI compliant : noundef signext i32 @foo(i32 signext, i32 zeroext)
+// CHECK: Outgoing call arguments verified as ABI compliant: noundef signext i32 @foo(i32 signext, i32 zeroext)
+
+// CHECK-LABEL: foo:
+// CHECK: ar %r3, %r2
+// CHECK-NEXT: lgfr %r2, %r3
+// CHECK-NEXT: br %r14
+//
+// CHECK-LABEL: fun:
+// CHECK: lgh %r2, 0(%r2)
+// CHECK-NEXT: llgc %r3, 0(%r3)
+// CHECK-NEXT: jg foo at PLT
+
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index 2bf9877e318f9..da8a471498068 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -121,7 +121,7 @@ class TargetOptions {
ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false),
JMCInstrument(false), EnableCFIFixup(false), MisExpect(false),
- XCOFFReadOnlyPointers(false), VerifyArgABICompliance(true) {}
+ XCOFFReadOnlyPointers(false), VerifyArgABICompliance(false) {}
/// EnableAIXExtendedAltivecABI - This flag returns true when -vec-extabi is
/// specified. The code generator is then able to use both volatile and
@@ -293,9 +293,8 @@ class TargetOptions {
unsigned XCOFFReadOnlyPointers : 1;
/// When set to true, call/return argument extensions of narrow integers
- /// are verified in the target backend if it cares about them. This is
- /// not done with internal tools like llc that run many tests that ignore
- /// (lack) these extensions.
+ /// are verified in the target backend if it cares about them. This is off
+ /// by default and enabled explicitly by each front-end separately.
unsigned VerifyArgABICompliance : 1;
/// Name of the stack usage file (i.e., .su file) if user passes
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 8e621aafe27d2..bb324949d1e52 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -11433,7 +11433,7 @@ SDValue SystemZTargetLowering::lowerVECREDUCE_ADD(SDValue Op,
DAG.getConstant(OpVT.getVectorNumElements() - 1, DL, MVT::i32));
}
-static void printFunctionArgExts(const Function *F, raw_fd_ostream &OS) {
+static void printFunctionArgExts(const Function *F, raw_ostream &OS) {
FunctionType *FT = F->getFunctionType();
const AttributeList &Attrs = F->getAttributes();
if (Attrs.hasRetAttrs())
@@ -11461,14 +11461,21 @@ bool SystemZTargetLowering::isInternal(const Function *Fn) const {
return Itr->second;
}
+bool SystemZTargetLowering::enableNarrowIntArgsVerification() const {
+ if (!Subtarget.isTargetELF())
+ return false;
+
+ if (EnableIntArgExtCheck.getNumOccurrences())
+ return EnableIntArgExtCheck;
+
+ return getTargetMachine().Options.VerifyArgABICompliance;
+}
+
void SystemZTargetLowering::
verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
const Function *F, SDValue Callee) const {
- // Temporarily only do the check when explicitly requested, until it can be
- // enabled by default.
- if (!EnableIntArgExtCheck)
+ if (!enableNarrowIntArgsVerification())
return;
-
bool IsInternal = false;
const Function *CalleeFn = nullptr;
if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee))
@@ -11485,37 +11492,32 @@ verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
printFunctionArgExts(F, errs());
llvm_unreachable("");
}
+ LLVM_DEBUG(dbgs() << "Outgoing call arguments verified as ABI compliant: ";
+ if (CalleeFn != nullptr)
+ printFunctionArgExts(CalleeFn, dbgs());
+ else
+ dbgs() << "-\n";);
}
void SystemZTargetLowering::
verifyNarrowIntegerArgs_Ret(const SmallVectorImpl<ISD::OutputArg> &Outs,
const Function *F) const {
- // Temporarily only do the check when explicitly requested, until it can be
- // enabled by default.
- if (!EnableIntArgExtCheck)
+ if (!enableNarrowIntArgsVerification())
return;
-
if (!isInternal(F) && !verifyNarrowIntegerArgs(Outs)) {
errs() << "ERROR: Missing extension attribute of returned "
<< "value from function:\n";
printFunctionArgExts(F, errs());
llvm_unreachable("");
}
+ LLVM_DEBUG(dbgs() << "Return argument verified as ABI compliant : ";
+ printFunctionArgExts(F, dbgs()));
}
// Verify that narrow integer arguments are extended as required by the ABI.
// Return false if an error is found.
bool SystemZTargetLowering::verifyNarrowIntegerArgs(
const SmallVectorImpl<ISD::OutputArg> &Outs) const {
- if (!Subtarget.isTargetELF())
- return true;
-
- if (EnableIntArgExtCheck.getNumOccurrences()) {
- if (!EnableIntArgExtCheck)
- return true;
- } else if (!getTargetMachine().Options.VerifyArgABICompliance)
- return true;
-
for (unsigned i = 0; i < Outs.size(); ++i) {
MVT VT = Outs[i].VT;
ISD::ArgFlagsTy Flags = Outs[i].Flags;
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index f01f7dcc6ab1d..0bb90419b26a0 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -495,6 +495,7 @@ class SystemZTargetLowering : public TargetLowering {
const TargetRegisterClass *getRepRegClassFor(MVT VT) const override;
private:
+ bool enableNarrowIntArgsVerification() const;
bool isInternal(const Function *Fn) const;
mutable std::map<const Function *, bool> IsInternalCache;
void verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
diff --git a/llvm/tools/llc/lib/llcdriver.cpp b/llvm/tools/llc/lib/llcdriver.cpp
index a41a728ad6650..b40cf13577159 100644
--- a/llvm/tools/llc/lib/llcdriver.cpp
+++ b/llvm/tools/llc/lib/llcdriver.cpp
@@ -685,10 +685,6 @@ static int compileModule(char **argv, SmallVectorImpl<PassPlugin> &PluginList,
// Return a copy of the output filename via the output param
OutputFilename = Out->outputFilename();
- // Tell target that this tool is not necessarily used with argument ABI
- // compliance (i.e. narrow integer argument extensions).
- Target->Options.VerifyArgABICompliance = 0;
-
std::unique_ptr<ToolOutputFile> DwoOut;
if (!SplitDwarfOutputFile.empty()) {
std::error_code EC;
>From e4e9742f17561f1eb67bdf731b1a3fd0e4ff6e71 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <Jonas.Paulsson2 at ibm.com>
Date: Tue, 15 Sep 2026 18:45:36 +0200
Subject: [PATCH 2/2] clang-format
---
llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index bb324949d1e52..e055060bee668 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -11493,10 +11493,8 @@ verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
llvm_unreachable("");
}
LLVM_DEBUG(dbgs() << "Outgoing call arguments verified as ABI compliant: ";
- if (CalleeFn != nullptr)
- printFunctionArgExts(CalleeFn, dbgs());
- else
- dbgs() << "-\n";);
+ if (CalleeFn != nullptr) printFunctionArgExts(CalleeFn, dbgs());
+ else dbgs() << "-\n";);
}
void SystemZTargetLowering::
More information about the llvm-commits
mailing list