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.