Currently we found that when clang handles 8/16 bits integer parameter, it will always assume the parameter has been sign/zero extend. This will cause some ABI compatibility issues: Compiler Explorer .
The summary is as follows:
clang: caller do the zero/sign extension while callee do nothing.
gcc: both caller and callee do the zero/sign extension.
icc: callee do the zero/sign extension while caller do nothong.
Now we want to make a patch that make clang follow the gcc behavior by removing the zeroext/signext attribute from the parameter: Compiler Explorer .
Any comments here?
Hi, @rjmccall , @topperc , what’s your opinion here?
If we remove the attribute, does that meant that new versions of clang won’t be able to call code compiled with old versions of clang because the caller(new clang) won’t extend the operands like the callee(old clang) code expects?
This is not what I expected. We want do the extension on both caller and callee. It looks like we can’t simply remove this attribute in the FE. I checked the
CodeGenModule::ConstructAttributeList in CGCall.cpp and didn’t find anything we can do about this attribute.
At present the way I can think of is to ignore sign/zero attribute in the X86 backend.
FWIW I reworked that patch to actually remove the zeroext/signext attributes in ⚙ D72742 Don't assume promotable integers are zero/sign-extended already in x86-64 ABI.. But maybe the code has changed a lot since then and it can’t be done that way?
On our legacy systems, we provide an “assume clean parameters” option to tell the compiler that the caller sign/zero extended out to the width of the argument slot. If not, the called routine will have to do the extension as needed. We default to “assume clean parameters” on Alpha and Itanium, but should change that to “don’t assume clean parameters” on x86.
On OpenVMS, our ABI on Alpha and Itanium specifies that the caller extend the argument and so far we’ve been riding along on LLVM doing something similar but we’ll have to do OpenVMS-specific changes. For example, we sign-extend 32-bit unsigned parameters (yes, sign extend, not zero extend). It helps legacy programs with mismatched prototypes when then moved from the 32-bit VAX to later 64-bit systems like Alpha and Itanium.
If we remove the attribute on the FE, it will cause the caller to no longer do zero/sign extension. Just as Craig said, this will cause compatibility issues with previous clang.