"Roger Sayle" <ro...@nextmovesoftware.com> writes: > Hi Richard, >> Yes, which is why I think the target should claim argument passing happens > in reg:HI. > > Unfortunately, this hits another "feature" of the nvptx backend; it's a > > /* Implement TARGET_MODES_TIEABLE_P. */ > bool nvptx_modes_tieable_p (machine_mode, machine_mode) { return false; } > /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */ > bool nvptx_can_change_mode_class (machine_mode, machine_mode, reg_class_t) { > return false; } > /* Implement TARGET_TRULY_NOOP_TRUNCATION. */ > bool nvptx_truly_noop_truncation (poly_uint64, poly_uint64) { return false; > } > > Basically, HImode is considered as a different register (bank) to SImode, > and requires > explicit move instructions to move data from HImode to SImode, and back, > unlike > most targets that can simply re-interpret the contents of GPRs. > > Passing an argument as HImode would be incompatible with the requirement to > pass as SImode.
Ah, OK, this was the bit I was missing from all of this. Like Richard says, how important is the zero-extension vs. sign-extension thing? Are callers required to zero-extend, and can callees rely on that? Or does the ABI treat the upper bits as undefined, so that callees can't rely on their contents? If the bits are undefined, have you tried making the ABI code return: (parallel:HF [(expr_list (reg:SI rN) (const_int 0))]) It's admittedly unusual to have the register be *bigger* than the value, but supporting that feels less hacky to me than the current approach. Thanks, Richard