Peter Bergner <berg...@linux.ibm.com> writes: > rtl-optimization: ICE on testsuite/gcc.dg/sso/t5.c with -mcpu=future -mpcrel > -O1 [PR94740] > > We ICE on the test case below because decompose_normal_address() doesn't > expect to see memory operands with constant addresses like below without > a (const:DI ...) wrapped around the PLUS: > > (mem/c:SI (plus:DI (symbol_ref:DI ("*.LANCHOR0") [flags 0x182]) > (const_int 4 [0x4])) [1 array+4 S4 A32]) > > What we expect to see is: > > (mem/c:SI (const:DI (plus:DI (symbol_ref:DI ("*.LANCHOR0") [flags > 0x182]) > (const_int 4 [0x4]))) [1 arrayD.2903+4 S4 > A32]) > > Sometimes, combine adds the (const: ...) for us via simplify_binary_operand > call, but that only happens when combine actually does something with this > insn. The bad address from the test case actually comes from CSE, so the > fix here is to make CSE add the (const: ...) whenever it creates a MEM with > a constant address.
I think we should do this in cse_process_notes_1, both to avoid creating an invalid MEM in the first place, and so that we handle embedded MEMs correctly too. Also, the (const:P ...) ought to be there even outside of a MEM. E.g. we ought to have: (set (reg X) (const:P (plus:P (symbol_ref:P S) (const_int D)))) rather than: (set (reg X) (plus:P (symbol_ref:P S) (const_int D))) Adding a PLUS case would fix this example, but I guess a more general fix would be to add a second switch statement (after the first) that switches on GET_RTX_CLASS and uses logic like simplify_replace_fn_rtx: case RTX_BIN_ARITH: case RTX_COMM_ARITH: op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data); op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data); if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1)) return x; return simplify_gen_binary (code, mode, op0, op1); Maybe we could even replace cse_process_notes_1 with simplify_replace_fn_rtx, but that's obviously a much more invasive change :-) Thanks, Richard