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.

Reply via email to