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