[Bug target/78516] [7 Regression] ICE in lra_assign for e500v2
bergner at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Dec 20 21:27:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78516
--- Comment #19 from Peter Bergner <bergner at gcc dot gnu.org> ---
(In reply to Peter Bergner from comment #18)
> With the patch Vlad attached minus the one unwanted line/typo, I'm getting
> an ICE on a powerpc64le-linux bootstrap. Looking into it.
Here's a minimal test case:
bergner@genoa:~/gcc/BUGS/PR78516$ cat libgcc2.i
float
fn1 (__int128 a)
{
if ((unsigned)a == a)
return a;
}
bergner@genoa:~/gcc/BUGS/PR78516$
/home/bergner/gcc/build/gcc-fsf-mainline-pr78516/./gcc/xgcc
-B/home/bergner/gcc/build/gcc-fsf-mainline-pr78516/./gcc/ -O2 -S libgcc2.i
libgcc2.i: In function ‘fn1’:
libgcc2.i:6:1: internal compiler error: in lra_set_insn_recog_data, at
lra.c:965
}
^
0x10a8eaaf lra_set_insn_recog_data(rtx_insn*)
/home/bergner/gcc/gcc-fsf-mainline-pr78516/gcc/lra.c:963
We have the following insn after IRA:
(insn 13 12 31 4 (set (reg:SF 157 [ <retval> ])
(float:SF (subreg:DI (reg/v:TI 158 [ aD.2516 ]) 0))) "libgcc2.i":5 407
{floatdisf2_fcfids}
(expr_list:REG_DEAD (reg/v:TI 158 [ aD.2516 ])
(nil)))
With pseudo 157 being assigned to fp reg fr1 and pseudo 158 being assigned to
r3. The floatdisf2_fcfids pattern looks like:
(define_insn "floatdisf2_fcfids"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
(float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
"@
fcfids %0,%1
xscvsxdsp %x0,%x1"
[(set_attr "type" "fp")])
...so pseudo 158 does not match the pattern's constraints.
check_and_process_move() doesn't handle this type of insn, so it returns false
and eventually, we generate the following two insns (haven't tracked down where
they come from yet):
(insn 38 12 13 4 (set (reg:DI 165)
(subreg:DI (reg/v:TI 158 [ a ]) 0)) "libgcc2.i":5 582
{*movdi_internal64}
(nil))
(insn 13 38 31 4 (set (reg:SF 157 [ <retval> ])
(float:SF (reg:DI 165))) "libgcc2.i":5 407 {floatdisf2_fcfids}
(expr_list:REG_DEAD (reg/v:TI 158 [ a ])
(nil)))
This maybe looks ok (?), except for the REG_DEAD on insn 13 should have been
removed and added to the new insn 38.
Later, check_and_process_move() is called again, this time for the new insn 38
and this is where we end up ICEing. We end up seeing:
(gdb) pr dest
(reg:DI 165)
(gdb) pr dreg
(reg:DI 165)
(gdb) p dclass
$54 = FLOAT_REGS
(gdb) p dregno
$55 = 165
(gdb) pr src
(subreg:DI (reg/v:TI 158 [ a ]) 0)
(gdb) pr sreg
(reg/v:TI 158 [ a ])
(gdb) p sregno
$56 = -1
(gdb) p sclass
$57 = BASE_REGS
(gdb) p secondary_class
$58 = NO_REGS
Due to the above, new_reg == NULL_RTX and sri.icode ==
CODE_FOR_reload_vsx_from_gprti. This pushes us down the else clause of the
following if:
if (sri.icode == CODE_FOR_nothing)
lra_emit_move (new_reg, sreg);
else
{
enum reg_class scratch_class;
scratch_class = (reg_class_from_constraints
(insn_data[sri.icode].operand[2].constraint));
scratch_reg = (lra_create_new_reg_with_unique_value
(insn_data[sri.icode].operand[2].mode, NULL_RTX,
scratch_class, "scratch"));
emit_insn (GEN_FCN (sri.icode) (new_reg != NULL_RTX ? new_reg : dest,
new_reg != NULL_RTX ? sreg : src,
scratch_reg));
}
We then up calling gen_reload_vsx_from_gprti() via the emit_insn() with:
op0, op1 and op2 as:
(gdb) pr operand0
(reg:DI 165)
(gdb) pr operand1
(subreg:DI (reg/v:TI 158 [ a ]) 0)
(gdb) pr operand2
(reg:IF 166)
That subreg for operand1 does not look correct to me.
More information about the Gcc-bugs
mailing list