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:
@@ -256,8 +256,19 @@ impl fmt::Display for AbiParam {
|
||||
|
||||
/// Function argument extension options.
|
||||
///
|
||||
/// On some architectures, small integer function arguments are extended to the width of a
|
||||
/// general-purpose register.
|
||||
/// On some architectures, small integer function arguments and/or return values are extended to
|
||||
/// the width of a general-purpose register.
|
||||
///
|
||||
/// This attribute specifies how an argument or return value should be extended *if the platform
|
||||
/// and ABI require it*. Because the frontend (CLIF generator) does not know anything about the
|
||||
/// particulars of the target's ABI, and the CLIF should be platform-independent, these attributes
|
||||
/// specify *how* to extend (according to the signedness of the original program) rather than
|
||||
/// *whether* to extend.
|
||||
///
|
||||
/// For example, on x86-64, the SystemV ABI does not require extensions of narrow values, so these
|
||||
/// `ArgumentExtension` attributes are ignored; but in the Baldrdash (SpiderMonkey) ABI on the same
|
||||
/// platform, all narrow values *are* extended, so these attributes may lead to extra
|
||||
/// zero/sign-extend instructions in the generated machine code.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum ArgumentExtension {
|
||||
|
||||
Reference in New Issue
Block a user