i386: Handle REG_EH_REGION note
authorH.J. Lu <hongjiu.lu@intel.com>
Thu, 14 Mar 2019 20:38:52 +0000 (20:38 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Thu, 14 Mar 2019 20:38:52 +0000 (13:38 -0700)
When we split:

(insn 18 17 76 2 (set (reg:SF 88 [ _19 ])
        (float:SF (mem/c:SI (symbol_ref:DI ("d") [flags 0x2]  <var_decl 0x7fd6d8290c60 d>) [1 d+0 S4 A32]))) "x.ii":4:20 170 {*floatsisf2}
     (expr_list:REG_EH_REGION (const_int 2 [0x2])
        (nil)))

to

(insn 94 17 18 2 (set (reg:V4SF 115)
        (vec_merge:V4SF (vec_duplicate:V4SF (float:SF (mem/c:SI (symbol_ref:DI ("d") [flags 0x2]  <var_decl 0x7f346837ac60 d>) [1 d+0 S4 A32])))
            (reg:V4SF 114)
            (const_int 1 [0x1]))) "x.ii":4:20 -1
     (nil))
(insn 18 94 76 2 (set (reg:SF 88 [ _19 ])
        (subreg:SF (reg:V4SF 115) 0)) "x.ii":4:20 112 {*movsf_internal}
     (expr_list:REG_EH_REGION (const_int 2 [0x2])
        (nil)))

we must copy the REG_EH_REGION note to the first insn and split the block
after the newly added insn.  The REG_EH_REGION on the second insn will be
removed later since it no longer traps.

gcc/

PR target/89650
* config/i386/i386.c (remove_partial_avx_dependency): Handle
REG_EH_REGION note.

gcc/testsuite/

PR target/89650
* g++.target/i386/pr89650.C: New test.

From-SVN: r269694

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.target/i386/pr89650.C [new file with mode: 0644]

index aa4d8ed..4890c75 100644 (file)
@@ -1,3 +1,9 @@
+2019-03-15  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/89650
+       * config/i386/i386.c (remove_partial_avx_dependency): Handle
+       REG_EH_REGION note.
+
 2019-03-14  Martin Liska  <mliska@suse.cz>
 
        PR other/89712
index 783a810..70e1011 100644 (file)
@@ -2819,6 +2819,8 @@ remove_partial_avx_dependency (void)
   rtx set;
   rtx v4sf_const0 = NULL_RTX;
 
+  auto_vec<rtx_insn *> control_flow_insns;
+
   FOR_EACH_BB_FN (bb, cfun)
     {
       FOR_BB_INSNS (bb, insn)
@@ -2875,6 +2877,17 @@ remove_partial_avx_dependency (void)
          set_insn = emit_insn_before (set, insn);
          df_insn_rescan (set_insn);
 
+         if (cfun->can_throw_non_call_exceptions)
+           {
+             /* Handle REG_EH_REGION note.  */
+             rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+             if (note)
+               {
+                 control_flow_insns.safe_push (set_insn);
+                 add_reg_note (set_insn, REG_EH_REGION, XEXP (note, 0));
+               }
+           }
+
          src = gen_rtx_SUBREG (dest_mode, vec, 0);
          set = gen_rtx_SET (dest, src);
 
@@ -2925,6 +2938,23 @@ remove_partial_avx_dependency (void)
       df_insn_rescan (set_insn);
       df_process_deferred_rescans ();
       loop_optimizer_finalize ();
+
+      if (!control_flow_insns.is_empty ())
+       {
+         free_dominance_info (CDI_DOMINATORS);
+
+         unsigned int i;
+         FOR_EACH_VEC_ELT (control_flow_insns, i, insn)
+           if (control_flow_insn_p (insn))
+             {
+               /* Split the block after insn.  There will be a fallthru
+                  edge, which is OK so we keep it.  We have to create
+                  the exception edges ourselves.  */
+               bb = BLOCK_FOR_INSN (insn);
+               split_block (bb, insn);
+               rtl_make_eh_edge (NULL, bb, BB_END (bb));
+             }
+       }
     }
 
   bitmap_obstack_release (NULL);
index 34f41e5..8f7288e 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-15  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/89650
+       * g++.target/i386/pr89650.C: New test.
+
 2019-03-14  Richard Biener  <rguenther@suse.de>
 
        * gcc.dg/gimplefe-13.c: Adjust.
diff --git a/gcc/testsuite/g++.target/i386/pr89650.C b/gcc/testsuite/g++.target/i386/pr89650.C
new file mode 100644 (file)
index 0000000..4b253cb
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -flive-range-shrinkage -fno-tree-dce -fno-dce -fnon-call-exceptions -mavx" }
+
+int d, e;
+struct g {
+  float f;
+  g(float h) : f(h + d) {}
+  ~g() {}
+};
+struct i {
+  int a;
+  int b : 4;
+  int &c;
+  i(int h) : a(), b(), c(h) {}
+};
+int main() {
+  i j(e);
+  g k[]{1, 2};
+}