Hi! The 991213-3.c testcase ICEs on aarch64-linux with -mabi=ilp32 since wide-int merge. The problem is that x = convert_memory_address (Pmode, x) is used twice on a VOIDmode CONST_INT, which is wrong. For non-VOIDmode rtl the second convert_memory_address is a NOP, but for VOIDmode the second call treats the CONST_INT returned by the first call as if it was again ptr_mode, rather than Pmode. On aarch64-linux in particular, the constant is zero-extended from SImode to DImode in the first call, so it is not valid SImode CONST_INT any longer.
emit_indirect_jump always calls convert_memory_address (Pmode, ...) on the operand in optabs.c when handling EXPAND_ADDRESS case in maybe_legitimize_operand, so the first convert_memory_address is both unnecessary and harmful. Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux (which do not define POINTERS_EXTEND_UNSIGNED) and tested on the problematic testcase with aarch64-linux cross. Can anyone with easy access to POINTERS_EXTEND_UNSIGNED targets (aarch64-linux ilp32, x86_64 -mx32, ia64-hpux) please test this? Ok for trunk if it works there? 2015-01-12 Jakub Jelinek <ja...@redhat.com> PR middle-end/63974 * cfgexpand.c (expand_computed_goto): Don't call convert_memory_address here. --- gcc/cfgexpand.c.jj 2015-01-09 21:59:54.000000000 +0100 +++ gcc/cfgexpand.c 2015-01-12 14:41:35.210705174 +0100 @@ -3060,8 +3060,6 @@ expand_computed_goto (tree exp) { rtx x = expand_normal (exp); - x = convert_memory_address (Pmode, x); - do_pending_stack_adjust (); emit_indirect_jump (x); } Jakub