On 7/3/24 6:48 PM, Li, Pan2 wrote:
Thanks Jeff for comments.

I would expect that QI/HI shouldn't be happening in practice due to the
definition of WORD_REGISTER_OPERATIONS.
Sorry I don't get the point here, I suppose there may be 6 kinds of truncation 
for scalar.

uint64_t => uint32_t 
uint64_t => uint16_t
uint64_t => uint8_t
uint32_t => uint16_t
uint32_t => uint8_t
uint16_t => uint8_t

Take uint16_t to uint8_t as example:

uint8_t   test (uint16_t x)
{
   bool overflow = x > (uint16_t)(uint8_t)(-1);
   return ((uint8_t)x) | (uint8_t)-overflow;
}

Will be expand to:

uint8_t sat_u_truc_uint16_t_to_uint8_t_fmt_1 (uint16_t x)
{
   uint8_t _6;
   _6 = .SAT_TRUNC (x_4(D)); [tail call]
   return _6;
}

Then we will have HImode as src and the QImode as the dest when enter 
riscv_expand_ustrunc.
But if you look at what the hardware can actually support, it doesn't have HImode or QImode operations other than load/store and for rv64 there are no SImode logicals.
That's what WORD_REGISTER_OPERATIONS is designed to support.  Regardless 
of what happens at the source level, the generic parts of gimple->RTL 
expansion arrange to widen the types appropriately.
I haven't looked at the expansion of the SAT_* builtins, but the way 
this is generally supposed to work is you just have to have your 
expander only accept the modes the processor actually supports and 
generic code will handle the widening for you.

Jeff

Reply via email to