This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/78516] [7 Regression] ICE in lra_assign for e500v2


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

Peter Bergner <bergner at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |vmakarov at gcc dot gnu.org

--- Comment #8 from Peter Bergner <bergner at gcc dot gnu.org> ---
Adding Vlad as this seems like it may be a LRA bug...or we at least need his
input about what we should be doing.

We have the following "fixed" pattern from the updated fix patch attached
above:

(define_insn "*mov_si<mode>_e500_subreg0_2_be"
  [(set (match_operand:SI 0 "int_reg_or_mem_operand" "=r,m")
        (subreg:SI (match_operand:SPE64TF 1 "gpc_reg_operand" "+r,&r") 0))]
  "WORDS_BIG_ENDIAN
   && ((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
       || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))"
  "@
   evmergelohi %0,%1,%1
   evmergelohi %1,%1,%1\;stw%U0%X0 %1,%0"
  [(set_attr "length" "4,8")])

After IRA, we have the following rtl dump results, with pseudo 192 not getting
a color and pseudo 283 getting assigned to the CTR (hard reg 66 ...ick!):

(insn 223 222 51 2 (set (reg/v:DF 192 [ tD.1744 ])
        (mem/u/c:DF (reg/f:SI 339) [1  S8 A64])) "q.i":28 2031
{*movdf_e500_double}
     (expr_list:REG_DEAD (reg/f:SI 339)
        (expr_list:REG_EQUIV (const_double:DF 0.0 [0x0.0p+0])
            (nil))))
...
(insn 113 97 234 2 (set (reg:SI 283)
        (subreg:SI (reg/v:DF 192 [ tD.1744 ]) 0)) "q.i":9 1975
{*mov_sidf_e500_subreg0_2_be}
     (nil))
...
(insn 111 107 116 2 (set (reg:DF 278)
        (mult:DF (reg/v:DF 192 [ tD.1744 ])
            (reg:DF 279))) "q.i":28 2038 {spe_muldf3}
     (expr_list:REG_DEAD (reg:DF 279)
        (expr_list:REG_DEAD (reg/v:DF 192 [ tD.1744 ])
            (nil))))

In lra-constraints.c:check_and_process_move() with curr_insn == insn 113, we
end up modifying insn 113 and emitting an insn before 113 that looks like:

(insn 273 97 113 2 (set (reg:SI 345)
        (subreg:SI (reg/v:DF 192 [ t ]) 0)) "q.i":9 1975
{*mov_sidf_e500_subreg0_2_be}
     (nil))

(insn 113 273 234 2 (set (reg:SI 283)
        (reg:SI 345)) "q.i":9 1975 {*mov_sidf_e500_subreg0_2_be}
     (nil))

Notice that the new insn 273 looks just like the old insn 113 and now insn 113
is invalid since this is a SImode reg to SImode reg copy without the subreg
which won't match the mov_sidf_e500_subreg0_2_be pattern, which leads us to
SEGV during check_rtl()'s call to constrain_operands() via
extract_constrain_insn().

The invalid insn 113 modification occurs due to the following code near the
bottom of check_and_process_move():

  if (new_reg != NULL_RTX)
    SET_SRC (curr_insn_set) = new_reg;

In this case, new_reg was created by:

  if (secondary_class != NO_REGS)
    new_reg = lra_create_new_reg_with_unique_value (GET_MODE (src), NULL_RTX,
                                                    secondary_class,
                                                    "secondary");

where "src" is the subreg:SI ..., so the new_reg mode will be SImode and we
then replace the whole SET_SRC (curr_insn_set) which is the subreg:SI (reg:DF
...) which doesn't seem correct.

Vlad, should we have never got this far into check_and_process_move() with this
type of insn?  Adding an ugly hack that creates an early out for this insn (ie,
set (reg:SI) (subreg:SI (reg:DF))) seems to make us compile.

If we are supposed to still process this insn, then how about something like
the following patch that creates a new_reg with the mode of the src register
and not the subreg and then replacing that instead of the entire subreg src? 
This too eliminates the SEGV/ICE.

Joseph, in the mean time, can you try the patch below to see if you get farther
into your glibc build?

Index: lra-constraints.c
===================================================================
--- lra-constraints.c   (revision 243444)
+++ lra-constraints.c   (working copy)
@@ -1237,12 +1237,12 @@ check_and_process_move (bool *change_p,
   *change_p = true;
   new_reg = NULL_RTX;
   if (secondary_class != NO_REGS)
-    new_reg = lra_create_new_reg_with_unique_value (GET_MODE (src), NULL_RTX,
+    new_reg = lra_create_new_reg_with_unique_value (GET_MODE (sreg), NULL_RTX,
                                                    secondary_class,
                                                    "secondary");
   start_sequence ();
   if (sri.icode == CODE_FOR_nothing)
-    lra_emit_move (new_reg, src);
+    lra_emit_move (new_reg, sreg);
   else
     {
       enum reg_class scratch_class;
@@ -1259,7 +1259,12 @@ check_and_process_move (bool *change_p,
   end_sequence ();
   lra_process_new_insns (curr_insn, before, NULL, "Inserting the move");
   if (new_reg != NULL_RTX)
-    SET_SRC (curr_insn_set) = new_reg;
+    {
+      if (SUBREG_P (src))
+       SUBREG_REG (SET_SRC (curr_insn_set)) = new_reg;
+      else
+       SET_SRC (curr_insn_set) = new_reg;
+    }
   else
     {
       if (lra_dump_file != NULL)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]