On 12/28/23 19:07, YunQiang Su wrote:
In general, I agree with this change.
When gcc12 on RV64, more than one `sext.w` will be produced with our test.
(Note, use -O1).


There are two things that help here.  The first is that the most significant
bit never appears in the middle of a field, so we don't have to worry about
overlapping, nor writes to the paradoxical bits of the SUBREG.  And secondly,
bits are numbered from zero for least significant, to MODE_BITSIZE (mode) - 1
for most significant, irrespective of the endian-ness.  So the code only needs

I am worrying that the higher bits than MODE_BITSIZE (mode) - 1 are also
modified. In this case, we also need do truncate/sign_extend.
While I cannot produce this C code yet.

to check the highest value bitpos + bitsize is the maximum value for the mode.
The above logic stays the same, but which byte insert requires extension will
change between mips64be and mips64le.  i.e. we test that the most significant
bit of the field/byte being written in the most significant bit of the SUBREG
target. [That's my understanding/rationalization, I could wrong].


The bit higher than MODE_BITSIZE (mode) - 1 also matters.
Since MIPS ISA claims that the src register of SImode instructions should
be sign_extended, otherwise UNPREDICTABLE.
It means,
    li $r2, 0xfff0 ffff ffff 0001
    #              ^
    addu $r1, $r0, $r2
is not allowed.
Right. But that's the whole point behind avoiding the narrowing subreg and forcing use of a truncate operation.

So basically the question becomes is there a way to modify those bits in a way that GCC doesn't know that it needs to to truncate/extend?

The most obvious concern would be bitfield insertions that modify those bits. But in that case the destination must have been DImode and we must truncate it to SImode before we can do anything with the SImode object. BUt that's all supposed to work as long as TRULY_NOOP_TRUNCATION is defined properly.

Jeff

Reply via email to