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