https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92090

--- Comment #10 from Xiong Hu XS Luo <luoxhu at cn dot ibm.com> ---
(In reply to Xiong Hu XS Luo from comment #9)
> (In reply to Segher Boessenkool from comment #7)
> > LRA creates
> > 
> > ;; Insn is not within a basic block
> > (insn 7037 0 0 (set (reg:PTI 3703)
> >         (const_wide_int 0x3ff00000000000000000000000000000)) -1
> >      (nil))
> > 
> > but that is not a valid insn.
> > 
> > This started as
> > 
> > (insn 3756 3755 3757 363 (set (reg:TI 2388)
> >         (const_wide_int 0x3ff00000000000000000000000000000))
> > "c11-atomic-exec-5.c":406:1 1179 {vsx_movti_64bit}
> >      (expr_list:REG_EQUIV (const_wide_int 
> > 0x3ff00000000000000000000000000000)
> >         (nil)))
> > 
> > (insn 3758 3757 3759 363 (set (reg:PTI 2389)
> >         (subreg:PTI (reg:TI 2388) 0)) "c11-atomic-exec-5.c":406:1 623
> > {*movpti_ppc64}
> >      (expr_list:REG_EQUIV (const_wide_int 
> > 0x3ff00000000000000000000000000000)
> >         (nil)))
> > 
> > which is fine.  But we have no insns (in the md) to load an immediate into
> > a PTI reg.
> 
> 
> This instruction is generated in function curr_insn_transform of
> lra-constraints.c, maybe need add a target hook to avoid it if subst is
> immediate and old is PTI register?
> 
>    for (i = 0; i < n_operands; i++)
>       {
>       rtx op, subst, old;
>       bool op_change_p = false;
> 
>       if (curr_static_id->operand[i].is_operator)
>         continue;
>       
>       old = op = *curr_id->operand_loc[i];
>       if (GET_CODE (old) == SUBREG)
>         old = SUBREG_REG (old);
>       subst = get_equiv_with_elimination (old, curr_insn);
>       original_subreg_reg_mode[i] = VOIDmode;
>       equiv_substition_p[i] = false;
>       if (subst != old)
>         {
>           equiv_substition_p[i] = true;
>           subst = copy_rtx (subst);
>           lra_assert (REG_P (old));
>           if (GET_CODE (op) != SUBREG)
>             *curr_id->operand_loc[i] = subst;
>           else
>             {
>               SUBREG_REG (op) = subst;
>               if (GET_MODE (subst) == VOIDmode)
>                 original_subreg_reg_mode[i] = GET_MODE (old);
>             }
>           if (lra_dump_file != NULL)
>             {
>               fprintf (lra_dump_file,
>                        "Changing pseudo %d in operand %i of insn %u on equiv 
> ",
>                        REGNO (old), i, INSN_UID (curr_insn));
>               dump_value_slim (lra_dump_file, subst, 1);
>               fprintf (lra_dump_file, "\n");
>             }

This could fix the ICE, but I am not sure whether it is reasonable:

diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 0db6d3151cd..325904ac473 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -3886,7 +3886,9 @@ curr_insn_transform (bool check_only_p)
        subst = get_equiv_with_elimination (old, curr_insn);
        original_subreg_reg_mode[i] = VOIDmode;
        equiv_substition_p[i] = false;
-       if (subst != old)
+       if (subst != old
+           && !(GET_MODE (old) == E_PTImode && GET_CODE (old) == REG
+                && GET_CODE (subst) == CONST_WIDE_INT))
          {
            equiv_substition_p[i] = true;
            subst = copy_rtx (subst);

Reply via email to