PR57936 is regarding a reload problem with rs6000_secondary_reload_inner. This is the failing instruction, as at the start of reload:
(insn 61 60 62 3 (set (reg:V16QI 220) (unspec:V16QI [ (subreg:V16QI (reg:V2DI 159 [ D.2446 ]) 0) (subreg:V16QI (reg:V2DI 159 [ D.2446 ]) 0) (reg:V16QI 213) ] UNSPEC_VPERM)) /home/pthaugen/src/gcc/gcc-4_9-power8/gcc/gcc/testsuite/g++.dg/torture/vshuf-main.inc:15 1253 {altivec_vperm_v16qi} (expr_list:REG_DEAD (reg:V16QI 213) (expr_list:REG_DEAD (reg:V2DI 159 [ D.2446 ]) (nil)))) You'll notice that none of the operands got a hard register. Here are the reloads: Reloads for insn # 61 Reload 0: BASE_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1), can't combine reload_in_reg: (plus:SI (reg/f:SI 1 1) (const_int 64 [0x40])) Reload 1: BASE_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 2), can't combine reload_in_reg: (plus:SI (reg/f:SI 1 1) (const_int 64 [0x40])) Reload 2: BASE_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1), can't combine, secondary_reload_p reload_reg_rtx: (reg:SI 10 10) Reload 3: reload_in (V16QI) = (reg:V16QI 32 0) ALTIVEC_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine reload_in_reg: (subreg:V16QI (reg:V2DI 159 [ D.2446 ]) 0) reload_reg_rtx: (reg:V16QI 78 1) secondary_in_reload = 2 secondary_in_icode = reload_v16qi_si_load Reload 4: BASE_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 2), can't combine, secondary_reload_p reload_reg_rtx: (reg:SI 10 10) Reload 5: reload_in (V16QI) = (reg:V16QI 32 0) ALTIVEC_REGS, RELOAD_FOR_INPUT (opnum = 2), can't combine reload_in_reg: (subreg:V16QI (reg:V2DI 159 [ D.2446 ]) 0) reload_reg_rtx: (reg:V16QI 78 1) secondary_in_reload = 4 secondary_in_icode = reload_v16qi_si_load Reload 3 completely reloads pseudo reg 159, which lives at (mem/c:V16QI (plus:SI (reg/f:SI 1 1) (const_int 64 [0x40])) [4 %sfp+64 S16 A128]) That's good and proper (except that duplicate reload 5 does the same thing unnecessarily, which is cleaned up later BTW). Pseudos that don't get a hard reg must be reloaded to a reg to satisfy the altivec_vperm insn constraint of "v". Normally, reload 2, the secondary reload for reload 3, would result in a call to reload_v16qi_si_load with (reg:V16QI 78 1) as its "reg" argument, and the mem home for pseudo reg 159 as its "mem" arg. However, reload1.c:choose_reload_regs has code to, as the comment says: /* First see if this pseudo is already available as reloaded for a previous insn. In this case reload finds such a register, so reload_v16qi_si_load then sees the register as its "mem" argument, and spits the dummy. I don't think the generic reload machinery is doing anything wrong at this point, although it is a little unusual in that secondary reloads like reload 2 above are not deleted when inheriting reloads. (Other reloads are. See remove_address_replacements calls in choose_reload_regs.) I guess there may be some circumstances when the secondary reload can't just be replaced with an insn moving from one reg to another.. Bootstrapped and regression tested powerpc64-linux. OK to apply? PR target/57936 * config/rs6000/rs6000.c (rs6000_secondary_reload_inner): Do not fail when "mem" arg is not a MEM. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 208097) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -16363,7 +16363,18 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, r rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p); if (GET_CODE (mem) != MEM) - rs6000_secondary_reload_fail (__LINE__, reg, mem, scratch, store_p); + { + /* If MEM was the home of a pseudo reg that wasn't allocated a + hard register, then when optimising reload will look at + previous instructions to see whether the MEM has already been + reloaded into a hard register. If that register is still + valid then we'll see it here rather than the MEM. */ + if (store_p) + emit_insn (gen_rtx_SET (VOIDmode, mem, reg)); + else + emit_insn (gen_rtx_SET (VOIDmode, reg, mem)); + return; + } rclass = REGNO_REG_CLASS (regno); addr = find_replacement (&XEXP (mem, 0)); -- Alan Modra Australia Development Lab, IBM