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

Reply via email to