https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68149
Bug ID: 68149 Summary: [ARM] ICE when splitting unaligned DImode load Product: gcc Version: 6.0 Status: UNCONFIRMED Keywords: ice-on-valid-code Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: ktkachov at gcc dot gnu.org Target Milestone: --- Created attachment 36617 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36617&action=edit Testcase The attached testcase (reduced from a testcase in the testsuite) ICEs with -O2 -mthumb -mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard -mfp16-format=ieee -w on arm targets. As reported at https://gcc.gnu.org/ml/gcc-patches/2015-10/msg03074.html this started with r229344 but it's a latend bug exposed by that commit. internal compiler error: in change_address_1, at emit-rtl.c:2132 } ^ 0x7a44f4 change_address_1 $SRC/gcc/emit-rtl.c:2132 0x7a74b3 adjust_address_1(rtx_def*, machine_mode, long, int, int, int, long) $SRC/gcc/emit-rtl.c:2270 0xab79f1 gen_lowpart_general(machine_mode, rtx_def*) $SRC/gcc/rtlhooks.c:90 0xfd7201 gen_split_47(rtx_insn*, rtx_def**) $SRC/gcc/config/arm/arm.md:4336 0x12473e3 split_11 $SRC/gcc/config/arm/arm.md:4331 0x12473e3 split_insns(rtx_def*, rtx_insn*) $SRC/gcc/config/arm/sync.md:361 0x7af36e try_split(rtx_def*, rtx_insn*, int) $SRC/gcc/emit-rtl.c:3664 0xa53e89 split_insn $SRC/gcc/recog.c:2874 0xa5cdb9 split_all_insns() $SRC/gcc/recog.c:2964 0xa5cea7 rest_of_handle_split_after_reload $SRC/gcc/recog.c:3900 0xa5cea7 execute $SRC/gcc/recog.c:3929 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. This is the unaligned_loaddi splitter in arm.md The DImode memory load it's trying to split into two is: (insn 105 403 122 2 (set (reg:DI 0 r0 [198]) (unspec:DI [ (mem/u/c:DI (plus:SI (reg:SI 2 r2) (const_int -256 [0xffffffffffffff00])) [0 S8 A8]) ] UNSPEC_UNALIGNED_LOAD)) besttry.c:408 137 {unaligned_loaddi} The splitter wants to split it into two SImode loads and -256 is not a valid offset for such a load. -256 was accepted as valid during reload because at that point it's seen as a DImode load and it's accepted there because DImode is a valid VALID_NEON_DREG_MODE, but it's not a NEON load :(