On 8/12/24 3:50 PM, Jeff Law wrote:


On 8/12/24 1:49 PM, Richard Sandiford wrote:

-      regno = subreg_regno (x);
+      /* A paradoxical should always be REGNO (y) + 0.  Using subreg_regno +         for something like (subreg:DI (reg:SI N) 0) on a WORDS_BIG_ENDIAN +         target will return N-1 which is catastrophic for N == 0 and just
+         wrong for other cases.
+
+         Fixing subreg_regno would be a better option, except that reload
+         depends on its current behavior.  */
+      if (paradoxical_subreg_p (x))
+        regno = REGNO (y);
+      else
+        regno = subreg_regno (x);

Are you sure that's right?  For a 32-bit big-endian target,
(subreg:DI (reg:SI 1) 0) really should simplify to (reg:DI 0) rather
than (reg:DI 1).
Correct, we want to get (reg:DI 0).  We get "0" back from REGNO (y). And we get 0 back from byte_lowpart_offset (remember, it's paradoxical).  The sum is 0 resulting in (reg:DI 0).
So rewinding this discussion a bit.

Focusing on this insn:

(insn 77 75 80 6 (parallel [
            (set (reg:DI 75 [ _32 ])
                (plus:DI (reg:DI 73 [ _31 ])
                    (subreg:DI (reg/v:SI 41 [ __n ]) 0)))
            (clobber (scratch:SI))
        ]) "j.C":50:38 discrim 1 155 {adddi3}
     (expr_list:REG_DEAD (reg:DI 73 [ _31 ])
        (expr_list:REG_DEAD (reg/v:SI 41 [ __n ])
            (nil))))

Not surprisingly we're focused on the subreg expression in there.

The first checkpoint in my mind is IRA's allocation where we assign it to reg 0.


      Popping a0(r41,l0)  --         assign reg 0


So given the use inside a paradoxical subreg, do we consider this valid?

After the discussion from last week, I'm leaning a bit more towards no than before.

Let's take a simpler case, the meaning of:

(subreg:DI (reg:SI 1) 0)

Actually refers to d0, not d1 on the m68k.  If we agree on that, then

(subreg:DI (reg:SI 0) 0)

Logically makes no sense since we can't reference register -1.

Note that Georg has a roughly similar looking issue on the avr, but at the high end of the register file (little endian target) which would roughly correspond to the discussion we had last week about paradoxicals on little endian targets.


In both cases I'm thinking now that the problem is really a failure to properly define HARD_REGNO_MODE_OK, particularly around boundary conditions where the multi-reg mode either can't be represented or crosses into other physical registers that have fixed uses.


Jeff





Reply via email to