This fixes a problem with my PR45844 fix. PR45844 was due to rs6000.c reg_offset_addressing_ok_p testing the operand mode to determine whether an insn supports reg+offset addressing, but the VSX splat insn uses a DF/DI mode input operand. So the memory form of this insn was wrongly seen to support reg+offset addressing. I hacked around this by adjusting the mode in the insn predicate, which happened to work for the PR45844 testcase, but actually causes the predicate to reject all MEMs since general_operand checks that the mode matches. (Oddly, this does not stop reload using the memory form of the insn! const_double passes the predicate, reload forces to mem which matches one of the constraints, and the predicate is not checked again.)
This avoids the general_operand mode check by expanding code from there relevant to MEMs. Bootstrapped and regression tested powerpc64-linux. OK for mainline and 4.6/4.7? * config/rs6000/predicates.md (splat_input_operand): Don't call input_operand for MEMs. Instead check for volatile and call memory_address_addr_space_p with modified mode. Index: gcc/config/rs6000/predicates.md =================================================================== --- gcc/config/rs6000/predicates.md (revision 192236) +++ gcc/config/rs6000/predicates.md (working copy) @@ -941,12 +941,16 @@ { if (MEM_P (op)) { + if (! volatile_ok && MEM_VOLATILE_P (op)) + return 0; if (mode == DFmode) mode = V2DFmode; else if (mode == DImode) mode = V2DImode; else - gcc_unreachable (); + gcc_unreachable (); + return memory_address_addr_space_p (mode, XEXP (op, 0), + MEM_ADDR_SPACE (op)); } return input_operand (op, mode); }) -- Alan Modra Australia Development Lab, IBM