[llvm] [SystemZ] XPLINK64: emit narrow sign/zero-extend instructions for sub-i32 formal args (PR #206833)
Ulrich Weigand via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 28 09:14:31 PDT 2026
================
@@ -2152,8 +2153,23 @@ SDValue SystemZTargetLowering::LowerFormalArguments(
assert(PartOffset && "Offset should be non-zero.");
}
}
- } else
- InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, ArgValue));
+ } else {
+ SDValue Val = convertLocVTToValVT(DAG, DL, VA, Chain, ArgValue);
----------------
uweigand wrote:
Hmm. I see the problem. Currently, we get something like:
```
t2: i64,ch = CopyFromReg t0, Register:i64 %0
t4: i64 = AssertSext t2, ValueType:ch:i32
t5: i32 = truncate t4
t7: i32 = AssertSext t5, ValueType:ch:i8
t8: i8 = truncate t7
```
where the first `AssertSext` / `truncate` pair comes from our `convertLocVTToValVT`, and the second `AssertSext` / `truncate` pair comes from `getCopyFromParts` common code.
The `SystemZCallingConv.td` changes really only affect `convertLocVTToValVT`; common code will simply check the original argument attributes again.
The only reason the code you added here helps is that you actually return a value of `i8` or `i16` type from `LowerFormalArguments`. Strictly speaking, this violates the defined API of this function as I understand it - it is supposed to return values whose type match the register class carrying the (part of the) argument. It turns out that returning a small integer happens to work with the current `getCopyFromParts` implementation and causes it to not generate the `AssertSext` / `truncate` pair.
Now this all seems somewhat fragile for two reasons: 1) maybe some future changes to common code will get it to break if `LowerFormalArguments` returns an unexpected type; and 2) common code actually checks the argument attributes in several other places throughout the optimizers - if we're actually lying about the incoming argument being properly extended, some other code might be subtly miscompiled ...
There is no good way to express an "asymmetric" argument extension to common code, so this whole thing seems hard to properly implement.
If we accept a solution somewhat along the lines of the current implementation, however, then I at least would implement it all in this one place. Simply do not even call `convertLocVTToValVT` at all if you detect this special case and just truncate the incoming `ArgValue` directly. Then all the changes involving `SystemZCallingConvention.td` can just go away - they have no other effect than influencing the behavior of `convertLocVTToValVT` anyway, as it turns out.
https://github.com/llvm/llvm-project/pull/206833
More information about the llvm-commits
mailing list