https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-December/123776.html
shows gcc-5 miscompiling a powerpc64 linux kernel.  The executive
summary is that the rs6000 backend has a bug in its RTL description of
indirect calls.  We specify a parallel containing both the actual call
and an action that happens after the call, the restore of r2.  The
restore is simply a memory load:
            (set (reg:DI 2 2)
                (mem/v/c:DI (plus:DI (reg/f:DI 1 1)
                        (const_int 40 [0x28])) [0  S8 A8]))
This leads to cprop concluding that it is valid to replace the
reference to r1 with another register having the same value before the
call.  Unfortunately, sometimes a call-clobbered register is chosen.

OK, so we need to fix this in the rs6000 backend, but it occurs to me
that cprop also has a bug here.  It shouldn't be touching fixed hard
registers.  Bootstrapped and regression tested powerpc64-linux.  OK
for mainline?

        * cprop.c (do_local_cprop): Disallow replacement of fixed
        hard registers.

Index: gcc/cprop.c
===================================================================
--- gcc/cprop.c (revision 219662)
+++ gcc/cprop.c (working copy)
@@ -1189,10 +1189,12 @@ do_local_cprop (rtx x, rtx_insn *insn)
   rtx newreg = NULL, newcnst = NULL;
 
   /* Rule out USE instructions and ASM statements as we don't want to
-     change the hard registers mentioned.  */
+     change the hard registers mentioned, and don't change fixed hard
+     registers.  */
   if (REG_P (x)
       && (REGNO (x) >= FIRST_PSEUDO_REGISTER
           || (GET_CODE (PATTERN (insn)) != USE
+             && !fixed_regs[REGNO (x)]
              && asm_noperands (PATTERN (insn)) < 0)))
     {
       cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);

-- 
Alan Modra
Australia Development Lab, IBM

Reply via email to