Hi! The following testcase started ICEing with my recent changes to enable split4 after sel-sched, but it seems the bug is more general. Some of the i386 splitter condition functions use and rely on df, but the split passes don't really df_analyze/df_finish_pass, so the DF info may be stale or not computed at all - the particular ICE is because there is a new bb and df_get_live_out (bb) returns NULL on it as the live or lr problem has not been computed yet.
The following patch makes it possible to call df_analyze during split on demand (on the first occassion where it is needed) and changes the i386 backend to do so. I needed a target hook that signifies the end of the split pass so that the backend can reset its flag and return the todo flags (TODO_df_finish in this case) to the caller if needed. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2021-02-15 Jakub Jelinek <ja...@redhat.com> PR target/99104 * target.def: Add split_pass_finish hook. * doc/tm.texi.in: Add TARGET_SPLIT_PASS_FINISH. * doc/tm.texi: Regenerated. * rtl.h (split_all_insns): Change return type from void to unsigned int. * recog.c (split_all_insns): Likewise. If targetm.split_pass_finish, call that hook and return what it returned, otherwise return 0. (split_all_insns_noflow): If targetm.split_pass_finish, call that hook and return what it returned. * config/i386/i386.c (df_analyzed_during_split): New variable. (ix86_split_pass_finish): New hook. (ix86_ok_to_clobber_flags): Call df_analyze if it hasn't been called yet during current split pass. Formatting fix. (ix86_avoid_lea_for_add): Formatting fix. (TARGET_SPLIT_PASS_FINISH): Redefine. * gcc.dg/pr99104.c: New test. --- gcc/target.def.jj 2021-01-04 10:25:38.997231967 +0100 +++ gcc/target.def 2021-02-15 17:36:51.997016704 +0100 @@ -3209,6 +3209,13 @@ DEFHOOK bool, (ao_ref *ref), default_ref_may_alias_errno) +DEFHOOK +(split_pass_finish, + "Define this to a return TODO flags from the end of a instruction\ + splitting pass.", + unsigned, (void), + NULL) + /* Support for named address spaces. */ #undef HOOK_PREFIX #define HOOK_PREFIX "TARGET_ADDR_SPACE_" --- gcc/doc/tm.texi.in.jj 2021-01-04 10:25:50.624100311 +0100 +++ gcc/doc/tm.texi.in 2021-02-15 17:50:18.887773367 +0100 @@ -3361,6 +3361,8 @@ stack. @hook TARGET_REF_MAY_ALIAS_ERRNO +@hook TARGET_SPLIT_PASS_FINISH + @hook TARGET_TRANSLATE_MODE_ATTRIBUTE @hook TARGET_SCALAR_MODE_SUPPORTED_P --- gcc/doc/tm.texi.jj 2021-01-04 10:25:50.599100594 +0100 +++ gcc/doc/tm.texi 2021-02-15 17:50:45.754465606 +0100 @@ -4303,6 +4303,10 @@ hook returns true for both @code{ptr_mod Define this to return nonzero if the memory reference @var{ref} may alias with the system C library errno location. The default version of this hook assumes the system C library errno location is either a declaration of type int or accessed by dereferencing a pointer to int. @end deftypefn +@deftypefn {Target Hook} unsigned TARGET_SPLIT_PASS_FINISH (void) +Define this to a return TODO flags from the end of a instruction splitting pass. +@end deftypefn + @deftypefn {Target Hook} machine_mode TARGET_TRANSLATE_MODE_ATTRIBUTE (machine_mode @var{mode}) Define this hook if during mode attribute processing, the port should translate machine_mode @var{mode} to another mode. For example, rs6000's --- gcc/rtl.h.jj 2021-01-04 10:25:38.778234447 +0100 +++ gcc/rtl.h 2021-02-15 17:52:30.411266758 +0100 @@ -3747,7 +3747,7 @@ extern enum reg_class reg_allocno_class extern void setup_reg_classes (int, enum reg_class, enum reg_class, enum reg_class); -extern void split_all_insns (void); +extern unsigned int split_all_insns (void); extern unsigned int split_all_insns_noflow (void); #define MAX_SAVED_CONST_INT 64 --- gcc/recog.c.jj 2021-02-13 16:08:20.793016638 +0100 +++ gcc/recog.c 2021-02-15 17:38:19.500014240 +0100 @@ -3406,7 +3406,7 @@ split_insn (rtx_insn *insn) /* Split all insns in the function. If UPD_LIFE, update life info after. */ -void +unsigned int split_all_insns (void) { bool changed; @@ -3488,6 +3488,9 @@ split_all_insns (void) } checking_verify_flow_info (); + if (targetm.split_pass_finish) + return targetm.split_pass_finish (); + return 0; } /* Same as split_all_insns, but do not expect CFG to be available. @@ -3523,6 +3526,8 @@ split_all_insns_noflow (void) split_insn (insn); } } + if (targetm.split_pass_finish) + return targetm.split_pass_finish (); return 0; } @@ -4380,8 +4385,7 @@ public: opt_pass * clone () { return new pass_split_all_insns (m_ctxt); } virtual unsigned int execute (function *) { - split_all_insns (); - return 0; + return split_all_insns (); } }; // class pass_split_all_insns @@ -4425,8 +4429,7 @@ public: virtual unsigned int execute (function *) { - split_all_insns (); - return 0; + return split_all_insns (); } }; // class pass_split_after_reload @@ -4479,8 +4482,7 @@ public: virtual unsigned int execute (function *) { - split_all_insns (); - return 0; + return split_all_insns (); } }; // class pass_split_before_sched2 @@ -4519,8 +4521,7 @@ public: virtual bool gate (function *); virtual unsigned int execute (function *) { - split_all_insns (); - return 0; + return split_all_insns (); } }; // class pass_split_before_regstack --- gcc/config/i386/i386.c.jj 2021-02-15 10:33:17.550216579 +0100 +++ gcc/config/i386/i386.c 2021-02-15 17:49:19.063458659 +0100 @@ -14968,6 +14968,22 @@ ix86_lea_outperforms (rtx_insn *insn, un return dist_define >= dist_use; } +/* True if df_analyze has been called during the current instruction splitting + pass. */ +static bool df_analyzed_during_split; + +/* Return TODO flags needed at the end of instruction splitting pass. */ + +static unsigned int +ix86_split_pass_finish (void) +{ + unsigned int todo = 0; + gcc_assert (!df_analyzed_during_split || reload_completed); + todo = df_analyzed_during_split ? TODO_df_finish : 0; + df_analyzed_during_split = false; + return todo; +} + /* Return true if it is legal to clobber flags by INSN and false otherwise. */ @@ -14978,6 +14994,11 @@ ix86_ok_to_clobber_flags (rtx_insn *insn df_ref use; bitmap live; + if (!df_analyzed_during_split) + { + df_analyze (); + df_analyzed_during_split = true; + } while (insn) { if (NONDEBUG_INSN_P (insn)) @@ -14996,7 +15017,7 @@ ix86_ok_to_clobber_flags (rtx_insn *insn insn = NEXT_INSN (insn); } - live = df_get_live_out(bb); + live = df_get_live_out (bb); return !REGNO_REG_SET_P (live, FLAGS_REG); } @@ -15013,7 +15034,7 @@ ix86_avoid_lea_for_add (rtx_insn *insn, return false; /* Check it is correct to split here. */ - if (!ix86_ok_to_clobber_flags(insn)) + if (!ix86_ok_to_clobber_flags (insn)) return false; regno0 = true_regnum (operands[0]); @@ -23419,6 +23440,9 @@ ix86_run_selftests (void) #undef TARGET_PROFILE_BEFORE_PROLOGUE #define TARGET_PROFILE_BEFORE_PROLOGUE ix86_profile_before_prologue +#undef TARGET_SPLIT_PASS_FINISH +#define TARGET_SPLIT_PASS_FINISH ix86_split_pass_finish + #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME #define TARGET_MANGLE_DECL_ASSEMBLER_NAME ix86_mangle_decl_assembler_name --- gcc/testsuite/gcc.dg/pr99104.c.jj 2021-02-15 13:40:13.463563957 +0100 +++ gcc/testsuite/gcc.dg/pr99104.c 2021-02-15 13:39:32.351035762 +0100 @@ -0,0 +1,15 @@ +/* PR target/99104 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -fsel-sched-pipelining -fselective-scheduling2 -funroll-loops" } */ + +__int128 a; +int b; +int foo (void); + +int __attribute__ ((simd)) +bar (void) +{ + a = ~a; + if (foo ()) + b = 0; +} Jakub