I'm looking into a few cases where we're still getting the base/index operand ordering wrong on PowerPC for an indexed load/store instruction, even after the PTR_PLUS merge and fix for PR28690. One of the cases I observed was caused by reload picking r0 to use for the base reg opnd as a result of spilling. Since r0 is not a valid register for the base reg position, we end up switching the order of the operands before emitting the instruction which then causes the performance hit on Power6. r0 is not a valid BASE_REG_CLASS register, only INDEX_REG_CLASS, but the following section of code from reload.c:find_reloads_address_1() dealing with PLUS(REG REG) may try assigning the base reg opnd to the INDEX_REG class in a couple situations. This then allows r0 to be picked for the base reg opnd. Is this being done on purpose (going on assumption that operands are commutative), such as to allow more opportunities for a successful allocation with reduced spill? If it's not wise for me to modify this code, possibly due to effect on other architectures, what are some other options (maybe introduce a new HONOR_BASE_INDEX_ORDER target macro)?
else if (code0 == REG && code1 == REG) { if (REGNO_OK_FOR_INDEX_P (REGNO (op0)) && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG)) return 0; else if (REGNO_OK_FOR_INDEX_P (REGNO (op1)) && regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG)) return 0; else if (regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG)) >>>> find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG)) find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH, &XEXP (x, 1), opnum, type, ind_levels, insn); else if (REGNO_OK_FOR_INDEX_P (REGNO (op1))) find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG, &XEXP (x, 0), opnum, type, ind_levels, insn); else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))) find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG, &XEXP (x, 1), opnum, type, ind_levels, insn); else { >>>> find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG, &XEXP (x, 1), opnum, type, ind_levels, insn); } } I've also seen the same situation come up during register renaming (regrename.c), but not too surprising since the code there says it's based off find_reloads_address_1() and is coded similarly. -Pat