On 2/22/22 17:08, Roger Sayle wrote:
Hi Tom,
I'll admit that I'd not myself considered the ABI issues when I initially
proposed
experimental HFmode support for the nvptx backend, and was surprised when
I finally tracked down the source of the problem you'd reported: that libgcc
spots HFmode support exists and immediately starts passing/returning values
in this type.
The one precedent that I can point to is that LLVM's nvptx backend passes
HFmode values in SImode regs, see https://reviews.llvm.org/D28540
Interesting, thanks for the link.
Their motivation is that not all PTX ISAs support fp16, so for compatibility
with say sm_30/sm_35, fp16 values are treated like b16, i.e. HImode.
At this point, the nvptx ABI states that HImode values are passed as SImode,
so we end up with the interesting mismatch of HFmode<->SImode.
Indeed, that sounds plausible.
And IIUC, that also means that this leaves the door open for us to
implement fp16 support for pre-sm_53 using b16 in a compatible way.
Then I think the current solution is OK, thanks for digging this up.
Thanks,
-Tom
I guess the same thing affects host code, where an i386/x86 host that
doesn't support 16-bit floating point, can pass "unsigned short" values
to and from the accelerator, and likewise this HImode locally gets passed
in a wider (often WORD_MODE) integer types on most x86 ABIs.
My guess is that passing SFmode in DImode may have been supported
in older versions of GCC, before handling of SUBREGs was tightened up,
so this might be considered a regression.
Cheers,
Roger
--
-----Original Message-----
From: Tom de Vries <tdevr...@suse.de>
Sent: 22 February 2022 15:43
To: Roger Sayle <ro...@nextmovesoftware.com>; gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] middle-end: Support ABIs that pass FP values as wider
integers.
On 2/9/22 21:12, Roger Sayle wrote:
This patch adds middle-end support for target ABIs that pass/return
floating point values in integer registers with precision wider than
the original FP mode. An example, is the nvptx backend where 16-bit
HFmode registers are passed/returned as (promoted to) SImode registers.
Unfortunately, this currently falls foul of the various (recent?)
sanity checks that (very sensibly) prevent creating paradoxical
SUBREGs of floating point registers. The approach below is to
explicitly perform the conversion/promotion in two steps, via an
integer mode of same precision as the floating point value. So on
nvptx, 16-bit HFmode is initially converted to 16-bit HImode (using
SUBREG), then zero-extended to SImode, and likewise when going the
other way, parameters truncated to HImode then converted to HFmode
(using SUBREG). These changes are localized to expand_value_return
and expanding DECL_RTL to support strange ABIs, rather than inside
convert_modes or gen_lowpart, as mismatched precision integer/FP
conversions should be explicit in the RTL, and these semantics not generally
visible/implicit in user code.
Hi Roger,
I cannot comment on the patch, but I do wonder (after your "strange ABI"
comment): did we actively decide on (or align to) a register passing ABI for
HFmode, or has it merely been decided by the implementation of
promote_arg:
...
static machine_mode
promote_arg (machine_mode mode, bool prototyped) {
if (!prototyped && mode == SFmode)
/* K&R float promotion for unprototyped functions. */
mode = DFmode;
else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
mode = SImode;
return mode;
}
...
There may be a rationale why it's good to pass a HF as SI, but it's not
documented there.
Anyway, I checked what cuda does for HF, and it passes a byte array:
...
.param .align 2 .b8 _Z5helloPj6__halfs_param_1[2], ...
So, I guess what I'm saying is I'd like to understand why we're having the HF
-> SI
promotion.
Thanks,
- Tom