Hi Marcus:

Thank you for digging this issue out, I would suggest you sent v4
patch which only v3 + riscv_subword fix, and then merge into master
first, and then sent separate patch for that issue, not sure what your
fix, but I guess it might fix some code for IRA/LRA, so I think has a
separate patch would be easy to discussion with other (non-RISC-V)
maintainers.


On Mon, Mar 15, 2021 at 5:42 AM Marcus Comstedt <mar...@mc.pp.se> wrote:
>
>
> Hello again Kito.
>
> I've now delved a bit deeper into the failure of the testcase
> gcc.c-torture/compile/pr35318.c on big endian RV32.
>
> The point at which big endian diverges from little endian is where
> process_alt_operands() is processing the "%0" constraint.  It calls
> operands_match_p(), which succeeds on little endian but fails on
> big endian.
>
> On little endian, the two rtx:es passed to operands_match_p are
> "r79:DF#0" and "r79:DF", while on big endian they are "r79:DF#4" and
> "r79:DF".  While the first operand is different, it's actually saying
> the same thing: The subreg with the least significant bits (meaning
> the second register in the pair on big endian, and the first register
> in the pair on little endian, what with two 32-bit integer registers
> being allocated to hold a single 64-bit float).
>
> The helper function lra_constraint_offset(), which is used by
> operands_match_p, seems to be intended to handle this discrepancy.  It
> contains the code
>
>   if (WORDS_BIG_ENDIAN
>       && is_a <scalar_int_mode> (mode, &int_mode)
>       && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD)
>     return hard_regno_nregs (regno, mode) - 1;
>
> However, in this case the rule does not trigger because the mode of
> the second operand (which is the one where an adjustment would be
> needed) does not have a scalar_int_mode, it has DFmode.  If I relax
> this code to also allow scalar_float_mode, then the operands_match_p
> call succeeds also on big endian.  There is still an ICE triggered
> further down the line though.
>
> I seem to be finding more questions than answers here.  Questions such
> as "is it really correct that the first operand to operands_match_p()
> has modeSI but the second one has modeDF?", "_should_ the operands
> match?", and "why is the least significant half singled out when there
> is no computation being perfomed".
>
> Given that the code generated for LE seems incorrect, I still suspect
> that there is some deeper issue here not related to endianness (but
> possibly related to using integer registers for passing floating point
> values to/from asm statements) and that it just happens to not cause
> an internal error (only bad code) on LE.
>
> How would you like to proceed?  I don't feel confident that I will
> find a definitive solution to this issue anytime soon, but it feels
> like such a weird special case (who passes 64-bit floats in 32-bit
> integer registers to their asm?) that it might be ok to just ignore
> it.  If you agree I'll just repost the patchset with the final fix
> added (solves all remaining 32-bit testcases save for this one)...
>
>
>   // Marcus
>
>

Reply via email to