https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124439

--- Comment #3 from Robin Dapp <rdapp at gcc dot gnu.org> ---
Either I'm hopelessly complicating things or this is a real mess:

So we start with

 (insn 105 103 108 9 (set (reg:DI 221)                                          
        (sign_extend:DI (minus:SI (subreg:SI (reg/f:DI 249 [ _47 ]) 0)          
                (subreg:SI (reg/f:DI 244) 0)))) "a-tigeli.adb":120:39 15
{subsi3_extended}                                                               
     (expr_list:REG_DEAD (reg/f:DI 249 [ _47 ])                                 
        (nil))) 

Before the patch we did an equiv replacement

Changing pseudo 244 in operand 2 of insn 105 on equiv frame:DI                  

and performed a reload

(insn 168 103 105 9 (set (reg:DI 14 a4 [253])                                   
        (plus:DI (reg/f:DI 2 sp)                                                
            (const_int 16 [0x10]))) "a-tigeli.adb":120:39 5 {*adddi3}           
     (nil))

Then we are basically done.

The first question is why we don't perform the equiv replacement from
  (subreg:SI (reg/f:DI 244) 0)
to
  (subreg:SI (reg/f:DI 65 frame) 0)
anymore.

It looks like that's due to a mistake in riscv_hard_regno_mode_ok.
We have

  if (GP_REG_P (regno))
    ...
  else if (FP_REG_P (regno))
    ...
  else if (V_REG_P (regno))
    ...
   else if (VTYPE_REG_P (regno) || VL_REG_P (regno) || VXRM_REG_P (regno)
           || FRM_REG_P (regno))
    ...
  else
    return false;

  /* Require same callee-savedness for all registers.  */
  ...
  /* Only use even registers in RV32 ZDINX */
  ...
  return true;

with the else capturing everything regardless of the mode and always returning
false.  The code behind it is dead (we should probably start running coverage
analysis...)
With the else removed, the codegen is as before and the testsuite is unchanged.
 So that might be the quickest way forward.

There's more, however.

Reply via email to