Port-vax archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Issues with native build of -10 on VAX



Hi all,

I *think* I've worked out what the 'reload' pass has done when compiling this test case, though I'm not sure that I understand it well enough to be able to explain it properly.

On 24/11/23 15:02, Kalvis Duckmanton wrote:
/* function call (5 arguments)
   cp_finish_decl(l, 0, am->ad.e.ab.d, __null, au);
*/
        movl *8(%r6),%r0
        subl2 $4,%sp          /* space for argument 5 */ 
        movl %sp,%r1
        movb 4(%r0),%r0
        rotl $21,%r0,(%r1)
        bicl2 $-8388609,(%r1) /* argument 5 */
        pushl $0              /* argument 4 */
        movl am,%r0
        movzbl 4(%r0),%r0
        movl %sp,%r1
        rotl $30,%r0,(%r1)
        bicl2 $-2,(%r1)       /* argument 3
                                 but it overwrites argument 4
                                 oops */

        pushl $0              /* argument 2 */
        pushl %r6             /* argument 1 */
        calls $5,_Z14cp_finish_declP9tree_nodeS0_bS0_i

I'm not yet sure what the cause is, but I have noticed that the output from g++'s 'reload' pass isn't correct.

What seems to have happened is that the instructions to push argument 3 have inherited the output reload of --%sp into %r1 from the instructions pushing argument 5, but GCC hasn't noted that the pushl $0 for argument 4 has also changed %sp so the output reload can't be reused.

There's a block of code in gcc/reload1.c which does invalidate old output reloads; the attached patch adds to this block to invalidate a reload of an output register if the output register is a reference to memory using an autoincrement or autodecrement addressing mode.

With the patch applied, I've been able to compile the test case using the resulting native compiler, and a native build of NetBSD hasn't failed yet, which is promising.  I have not applied any workarounds to sancov.c or to tree-switch-conversion.c, and I'm also compiling GCC with the default optimisation level (-O2; I haven't applied any of Matthew's changes mentioned earlier).

I've also applied this change to a copy of GCC 10.5.0 from upstream and on amd64 at least there was no change to the regression test results so I don't think this introduces any regressions.

I'm curious to know if this will work for anyone else.

cheers

kalvis


diff --git a/external/gpl3/gcc.old/dist/gcc/reload1.c b/external/gpl3/gcc.old/dist/gcc/reload1.c
index 88f4727d5453..8d481071a12b 100644
--- a/external/gpl3/gcc.old/dist/gcc/reload1.c
+++ b/external/gpl3/gcc.old/dist/gcc/reload1.c
@@ -8377,6 +8377,43 @@ emit_reload_insns (class insn_chain *chain)
 		reg_last_reload_reg[out_regno + k] = 0;
 	    }
 	}
+
+#if AUTO_INC_DEC /* XXX KD */
+      /* Where an output register might be reloaded, and it is a
+         memory reference, and the address is auto-incremented, any
+         previously reloaded copy of the address must be
+         invalidated. */
+      if (i < 0
+          && rld[r].out != 0
+          && MEM_P (rld[r].out))
+        {
+          rtx out = XEXP (rld[r].out, 0); /* address expression */
+          enum rtx_code code = GET_CODE (out);
+
+          if (code != POST_INC && code != POST_DEC
+              && code != PRE_INC && code != PRE_DEC)
+            {
+              /* do nothing */
+            }
+          else
+            {
+              int out_regno = REGNO (XEXP (out, 0));
+              machine_mode mode = GET_MODE (XEXP (out, 0));
+
+              /* for the moment, handle only the case where out_regno
+                 is a hardware register */
+
+              if (HARD_REGISTER_NUM_P (out_regno))
+                {
+                  int k, out_nregs = hard_regno_nregs (out_regno, mode);
+
+                  for (k = 0; k < out_nregs; k++)
+                    reg_last_reload_reg[out_regno + k] = 0;
+                }
+            }
+        }
+#endif /* AUTO_INC_DEC */ /* XXX KD */
+
     }
   reg_reloaded_dead |= reg_reloaded_died;
 }


Home | Main Index | Thread Index | Old Index