Do value-extensions at ABI boundaries only when ABI requires it.
There has been some confusion over the meaning of the "sign-extend" (`sext`) and "zero-extend" (`uext`) attributes on parameters and return values in signatures. According to the three implemented backends, these attributes indicate that a value narrower than a full register should always be extended in the way specified. However, they are much more useful if they mean "extend in this way if the ABI requires extending": only the ABI backend knows whether or not a particular ABI (e.g., x64 SysV vs. x64 Baldrdash) requires extensions, while only the frontend (CLIF generator) knows whether or not a value is signed, so the two have to work in concert. This is the result of some very helpful discussion in #2354 (thanks to @uweigand for raising the issue and @bjorn3 for helping to reason about it). This change respects the extension attributes in the above way, rather than unconditionally extending, to avoid potential performance degradation as we introduce more extension attributes on signatures.
This commit is contained in:
@@ -144,8 +144,13 @@ impl ArgAssigner for Args {
|
||||
return ValueConversion::VectorSplit.into();
|
||||
}
|
||||
|
||||
// Small integers are extended to the size of a pointer register.
|
||||
if ty.is_int() && ty.bits() < u16::from(self.pointer_bits) {
|
||||
// Small integers are extended to the size of a pointer register, but
|
||||
// only in ABIs that require this. The Baldrdash (SpiderMonkey) ABI
|
||||
// does, but our other supported ABIs on x86 do not.
|
||||
if ty.is_int()
|
||||
&& ty.bits() < u16::from(self.pointer_bits)
|
||||
&& self.call_conv.extends_baldrdash()
|
||||
{
|
||||
match arg.extension {
|
||||
ArgumentExtension::None => {}
|
||||
ArgumentExtension::Uext => return ValueConversion::Uext(self.pointer_type).into(),
|
||||
|
||||
Reference in New Issue
Block a user