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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The STV pass is just weird.
For the addition of insns to chains from candidates (wonder why for candidates
it doesn't consider CONST_INT srcs, those, perhaps with somewhat higher cost,
can be either loaded from memory, or if the constant is some cheap SSE
constant, computed that way (0 or all ones)) it uses the UD and DU chains
(seems walking in both directions greedily), but then convert_reg works not
just on the definitions and uses from the current chain, but all.  For the ICE
e.g. the following works:
--- i386.c.jj1  2016-03-09 10:19:20.000000000 +0100
+++ i386.c      2016-03-10 11:28:37.465500423 +0100
@@ -3374,8 +3374,22 @@ scalar_chain::convert_reg (unsigned regn
       }
     else if (NONDEBUG_INSN_P (DF_REF_INSN (ref)))
       {
-       replace_rtx (DF_REF_INSN (ref), reg, scopy);
-       df_insn_rescan (DF_REF_INSN (ref));
+       if (!scalar_copy)
+         {
+           /* This can happen for uninitialized uses, if the register
+              is defined later on.  */
+           df_ref ref2;
+           df_link *chain;
+           for (ref2 = DF_INSN_UID_USES (DF_REF_INSN_UID (ref));
+                ref2; ref2 = DF_REF_NEXT_LOC (ref2))
+             if (DF_REF_REGNO (ref2) == regno)
+               gcc_assert (DF_REF_CHAIN (ref2) == NULL);
+         }
+       else
+         {
+           replace_rtx (DF_REF_INSN (ref), reg, scopy);
+           df_insn_rescan (DF_REF_INSN (ref));
+         }
       }

   BITMAP_FREE (conv);
or if I didn't want to verify it, perhaps just else if (scalar_copy &&
NONDEBUG_INSN_P ...) would be enough, replacing a reg with NULL is always a
bug,
but wonder how this can work well even if e.g. the same pseudo is set multiple
times in different, unrelated chains - then Id think convert_reg will be called
on the same regno multiple times, for each chain, but have in all cases a
global action on all defs and all uses of that pseudo.
Another problem I see is with DEBUG_INSNs - the analysis phase correctly
ignores those, but e.g. convert_reg ignores them too, while I'd expect if it
replaces all other uses with scopy (for the scalar_reg case), then it sould
replace those too in the debug insns, and otherwise it should figure out if the
original pseudo lives somewhere else (subreg of something, whatever) and
replace those in the debug insns too, or worst case reset those debug insns.

Anyway, not familiar enough with STV, so I'll leave my analysis here and leave
this to Ilya.

Reply via email to