https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63491
Bug ID: 63491 Summary: Ice in LRA with simple vector test case on power Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: bergner at gcc dot gnu.org The following test case causes an ICE in LRA using trunk: [bergner@makalu-lp1 LRA]$ cat pack01.i typedef __int128_t __attribute__((__vector_size__(16))) vector_128_t; typedef unsigned long long scalar_64_t; void bar (vector_128_t); void foo (void) { union { scalar_64_t i64[2]; vector_128_t v128; } u; u.i64[0] = 1; u.i64[1] = 2; bar (u.v128); } [bergner@makalu-lp1 LRA]$ /home/bergner/gcc/build/gcc-fsf-mainline-bootstrap-lra-debug/gcc/xgcc -B/home/bergner/gcc/build/gcc-fsf-mainline-bootstrap-lra-debug/gcc/ -mcpu=power8 -O1 -S -m64 -mlra pack01.i pack01.i: In function ‘foo’: pack01.i:15:1: internal compiler error: in check_and_process_move, at lra-constraints.c:1135 } ^ 0x1087c5e3 check_and_process_move /home/bergner/gcc/gcc-fsf-mainline-bootstrap-reload/gcc/lra-constraints.c:1132 0x108845d3 curr_insn_transform /home/bergner/gcc/gcc-fsf-mainline-bootstrap-reload/gcc/lra-constraints.c:3274 0x108888a3 lra_constraints(bool) /home/bergner/gcc/gcc-fsf-mainline-bootstrap-reload/gcc/lra-constraints.c:4203 0x1086a163 lra(_IO_FILE*) /home/bergner/gcc/gcc-fsf-mainline-bootstrap-reload/gcc/lra.c:2198 0x107ecc9b do_reload /home/bergner/gcc/gcc-fsf-mainline-bootstrap-reload/gcc/ira.c:5311 0x107ed25f execute /home/bergner/gcc/gcc-fsf-mainline-bootstrap-reload/gcc/ira.c:5470 The problematic rtl sequence is setting up the parameter to the call. After IRA, we have the following rtl with pseudo 156 being allocated to hardreg (pair) 10 (and 11). (insn 12 5 13 2 (set (subreg:DI (reg/v:TI 156 [ u ]) 0) (const_int 1 [0x1])) pack01.i:13 534 {*movdi_internal64} (nil)) (insn 13 12 7 2 (set (subreg:DI (reg/v:TI 156 [ u ]) 8) (const_int 2 [0x2])) pack01.i:13 534 {*movdi_internal64} (nil)) (insn 7 13 8 2 (set (reg:V1TI 79 2) (subreg:V1TI (reg/v:TI 156 [ u ]) 0)) pack01.i:14 967 {*vsx_movv1ti} (expr_list:REG_DEAD (reg/v:TI 156 [ u ]) (nil))) With reload (-mno-lra), we do: Reload 1: reload_in (V1TI) = (reg:V1TI 10 10) ALTIVEC_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine reload_in_reg: (subreg:V1TI (reg/v:TI 10 10 [orig:156 u ] [156]) 0) reload_reg_rtx: (reg:V1TI 79 2) secondary_in_reload = 0 secondary_in_icode = reload_vsx_from_gprv1ti which leads to: (insn 12 5 13 2 (set (reg:DI 10 10 [ u ]) (const_int 1 [0x1])) pack01.i:13 534 {*movdi_internal64} (nil)) (insn 13 12 17 2 (set (reg:DI 11 11 [orig:156 u+8 ] [156]) (const_int 2 [0x2])) pack01.i:13 534 {*movdi_internal64} (nil)) (insn 17 13 8 2 (parallel [ (set (reg:V1TI 79 2) (unspec:V1TI [ (reg:V1TI 10 10) ] UNSPEC_P8V_RELOAD_FROM_GPR)) (clobber (reg:TF 32 0)) ]) pack01.i:14 513 {reload_vsx_from_gprv1ti} (nil)) ...and all is fine. However, with LRA (-mlra), we hit the assert in check_and_process_move(): /* Check the target hook consistency. */ lra_assert ((secondary_class == NO_REGS && sri.icode == CODE_FOR_nothing) || (old_sclass == NO_REGS && old_sri.icode == CODE_FOR_nothing) || (secondary_class == old_sclass && sri.icode == old_sri.icode)); Due to: (gdb) p secondary_class $1 = NO_REGS (gdb) p (enum insn_code) sri.icode $2 = CODE_FOR_reload_vsx_from_gprti (gdb) p old_sclass $3 = NO_REGS (gdb) p (enum insn_code) old_sri.icode $4 = CODE_FOR_reload_vsx_from_gprv1ti The problem seems to be that LRA is trying to use CODE_FOR_reload_vsx_from_gprti to reload the src rather than CODE_FOR_reload_vsx_from_gprv1ti. This is due to calling targetm.secondary_reload() with sreg_mode (ie, TImode) rather than V1TImode that reload is calling it with. Shouldn't we be using V1TImode since we're accessing src via a subreg:V1TI? I'm marking this as an rtl issue for now, since the ICE is coming from LRA, but I know this could end up as a target bug in the end.