On 03/14/2017 05:22 PM, Bernd Schmidt wrote:
This triggered a kernel miscompilation with an old (4.8 I think) aarch64 toolchain.Here's the reloads for the insn where things go wrong: Reloads for insn # 210 Reload 0: reload_in (DI) = (reg/v/f:DI 80 [ pgdata ]) GENERAL_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 0) reload_in_reg: (reg/v/f:DI 80 [ pgdata ]) reload_reg_rtx: (reg:DI 5 x5) Reload 1: reload_in (DI) = (plus:DI (reg/v/f:DI 80 [ pgdata ]) (const_int 7172 [0x1c04])) GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 0), inc by 2 reload_in_reg: (plus:DI (reg/v/f:DI 80 [ pgdata ]) (const_int 7172 [0x1c04])) reload_reg_rtx: (reg:DI 5 x5) Note how the input and input_address reloads use the same reload register. This is intended as the two categories aren't supposed to conflict. The problem is that reload 1 is a PLUS expression, and when reloading these, gen_reload may have to resort to tricks, such as loading one of the operands (the constant 7172) into the reload register, and then adding the other operand to it. In effect that's an earlyclobber of the reload register, and that is not represented in the for_input/for_input_address classification. Most likely we haven't tripped over this earlier because on other machines the addition can be done in a single insn. The following fixes this by using RELOAD_OTHER in this case. This is pessimistic, but at that point I don't think we can really know what gen_reload will have to do. Bootstrapped and tested on x86_64-linux on the 4.7 branch - that's the best method of testing that I can think of (but I think I'll also run some c6x tests with trunk). If no one objects, I'll check this in soonish. Bernd rld-other.diff * reload.c (find_reloads): When reloading a nonoffsettable address, use RELOAD_OTHER for it and its address reloads.
I've already got state on this... OK. jeff
