From a9c33665ea9ba27e79bcb19e256e754209de9acb Mon Sep 17 00:00:00 2001 From: arti Date: Wed, 11 Nov 2026 16:50:00 +0000 Subject: [PATCH] tms34010: accept the optimizer's returned argument attribute --- llvm/lib/Target/TMS34010/TMS34010ISelLowering.cpp | 10 +++++++--- llvm/test/CodeGen/TMS34010/m2-reject-sret.ll | 2 +- llvm/test/CodeGen/TMS34010/m2-returned.ll | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/TMS34010/m2-returned.ll diff --git a/llvm/lib/Target/TMS34010/TMS34010ISelLowering.cpp b/llvm/lib/Target/TMS34010/TMS34010ISelLowering.cpp index 8ca048b630d3..c5e7d2b43ff1 100644 --- a/llvm/lib/Target/TMS34010/TMS34010ISelLowering.cpp +++ b/llvm/lib/Target/TMS34010/TMS34010ISelLowering.cpp @@ -70,11 +70,15 @@ SDValue TMS34010TargetLowering::LowerFormalArguments( // elimination). for (unsigned i = 0, e = Ins.size(); i != e; ++i) { const ISD::InputArg &In = Ins[i]; + // `returned` is an optimization hint, not an ABI feature: the argument is + // still passed in its normal stack slot, and the callee already returns + // through the ABI's A8. The optimizer infers it for ordinary C such as + // `int first(int a, int b) { return a; }`, so rejecting it made valid -O2 + // input uncompilable. The ABI-affecting flags stay rejected. if (In.Flags.isSRet() || In.Flags.isByVal() || In.Flags.isInReg() || - In.Flags.isNest() || In.Flags.isReturned()) + In.Flags.isNest()) report_fatal_error( - "M2 supports only plain arguments " - "(no sret/byval/inreg/nest/returned)", + "M2 supports only plain arguments (no sret/byval/inreg/nest)", false); if (In.VT != MVT::i32) report_fatal_error("M2 supports only i32 and pointer arguments", false); diff --git a/llvm/test/CodeGen/TMS34010/m2-reject-sret.ll b/llvm/test/CodeGen/TMS34010/m2-reject-sret.ll index de8f55bf2287..8c132aeecb8f 100644 --- a/llvm/test/CodeGen/TMS34010/m2-reject-sret.ll +++ b/llvm/test/CodeGen/TMS34010/m2-reject-sret.ll @@ -3,7 +3,7 @@ ; ; M2 has no sret convention. The pointer attribute must be rejected even ; though its legalized type is a plain i32. -; CHECK: M2 supports only plain arguments (no sret/byval/inreg/nest/returned) +; CHECK: M2 supports only plain arguments (no sret/byval/inreg/nest) define void @sret_arg(ptr sret(i32) %out) { entry: store i32 0, ptr %out diff --git a/llvm/test/CodeGen/TMS34010/m2-returned.ll b/llvm/test/CodeGen/TMS34010/m2-returned.ll new file mode 100644 index 000000000000..1e81c0f626a8 --- /dev/null +++ b/llvm/test/CodeGen/TMS34010/m2-returned.ll @@ -0,0 +1,15 @@ +; RUN: llc -march=tms34010 -O0 -filetype=asm < %s | FileCheck %s +; RUN: llc -march=tms34010 -O2 -filetype=asm < %s | FileCheck %s +; +; `returned` is an optimizer hint, not an ABI convention: the optimizer infers +; it for `return a`, and the argument still lives in its normal FP-relative +; stack slot. It must not be rejected. +define i32 @first(i32 returned %a, i32 %b) { +entry: + ret i32 %a +} +; CHECK-LABEL: _first: +; CHECK: MOVE A13, -*SP, 1 +; CHECK: ADDI -32, A{{[0-9]+}} +; CHECK: MOVE {{A[0-9]+}}, A8 +; CHECK: RETS 2