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 <[email protected]> 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@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 <[email protected]> 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:: _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
