summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/cfgrtl.c8
-rw-r--r--gcc/cfgrtl.h2
-rw-r--r--gcc/config/i386/i386.c7
-rw-r--r--gcc/cse.c21
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr70807.c18
7 files changed, 58 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 84d5ddcba2c..b0d0949a62e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2016-05-11 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR middle-end/70807
+ * cfgrtl.h (delete_insn_and_edges): Now return bool.
+ * cfgrtl.c (delete_insn_and_edges): Likewise.
+ * config/i386/i386.c (convert_scalars_to_vector): Remove
+ redundant code.
+ * cse.c (cse_insn): Compute cse_cfg_altered.
+ (delete_trivially_dead_insns): Likewise.
+ (cse_cc_succs): Likewise.
+ (rest_of_handle_cse): Free dominance info if required.
+ (rest_of_handle_cse2): Likewise.
+ (rest_of_handle_cse_after_global_opts): Likewise.
+
2016-05-11 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.c (is_complex_IBM_long_double,
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 62b0596203f..3d8ed60c2a0 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -215,9 +215,10 @@ delete_insn (rtx uncast_insn)
}
}
-/* Like delete_insn but also purge dead edges from BB. */
+/* Like delete_insn but also purge dead edges from BB.
+ Return true if any edges are eliminated. */
-void
+bool
delete_insn_and_edges (rtx_insn *insn)
{
bool purge = false;
@@ -228,7 +229,8 @@ delete_insn_and_edges (rtx_insn *insn)
purge = true;
delete_insn (insn);
if (purge)
- purge_dead_edges (BLOCK_FOR_INSN (insn));
+ return purge_dead_edges (BLOCK_FOR_INSN (insn));
+ return false;
}
/* Unlink a chain of insns between START and FINISH, leaving notes
diff --git a/gcc/cfgrtl.h b/gcc/cfgrtl.h
index 0d880242354..d81928a6ebf 100644
--- a/gcc/cfgrtl.h
+++ b/gcc/cfgrtl.h
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_CFGRTL_H
extern void delete_insn (rtx);
-extern void delete_insn_and_edges (rtx_insn *);
+extern bool delete_insn_and_edges (rtx_insn *);
extern void delete_insn_chain (rtx, rtx, bool);
extern basic_block create_basic_block_structure (rtx_insn *, rtx_insn *,
rtx_note *, basic_block);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 237ba8009d6..9f62089b8b1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3969,13 +3969,6 @@ convert_scalars_to_vector ()
bitmap_obstack_release (NULL);
df_process_deferred_rescans ();
- /* FIXME: Since the CSE pass may change dominance info, which isn't
- expected by the fwprop pass, call free_dominance_info to
- invalidate dominance info. Otherwise, the fwprop pass may crash
- when dominance info is changed. */
- if (TARGET_64BIT)
- free_dominance_info (CDI_DOMINATORS);
-
/* Conversion means we may have 128bit register spills/fills
which require aligned stack. */
if (converted_insns)
diff --git a/gcc/cse.c b/gcc/cse.c
index 7456e84c329..04e1a8563d7 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -5505,7 +5505,7 @@ cse_insn (rtx_insn *insn)
else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx)
{
/* One less use of the label this insn used to jump to. */
- delete_insn_and_edges (insn);
+ cse_cfg_altered |= delete_insn_and_edges (insn);
cse_jumps_altered = true;
/* No more processing for this set. */
sets[i].rtl = 0;
@@ -5516,7 +5516,7 @@ cse_insn (rtx_insn *insn)
{
if (cfun->can_throw_non_call_exceptions && can_throw_internal (insn))
cse_cfg_altered = true;
- delete_insn_and_edges (insn);
+ cse_cfg_altered |= delete_insn_and_edges (insn);
/* No more processing for this set. */
sets[i].rtl = 0;
}
@@ -5551,7 +5551,7 @@ cse_insn (rtx_insn *insn)
REG_NOTES (new_rtx) = note;
}
- delete_insn_and_edges (insn);
+ cse_cfg_altered |= delete_insn_and_edges (insn);
insn = new_rtx;
}
else
@@ -7131,7 +7131,7 @@ delete_trivially_dead_insns (rtx_insn *insns, int nreg)
count_reg_usage (insn, counts, NULL_RTX, -1);
ndead++;
}
- delete_insn_and_edges (insn);
+ cse_cfg_altered |= delete_insn_and_edges (insn);
}
}
@@ -7427,7 +7427,7 @@ cse_cc_succs (basic_block bb, basic_block orig_bb, rtx cc_reg, rtx cc_src,
newreg);
}
- delete_insn_and_edges (insns[i]);
+ cse_cfg_altered |= delete_insn_and_edges (insns[i]);
}
return mode;
@@ -7568,6 +7568,9 @@ rest_of_handle_cse (void)
else if (tem == 1 || optimize > 1)
cleanup_cfg (0);
+ if (cse_cfg_altered && dom_info_available_p (CDI_DOMINATORS))
+ free_dominance_info (CDI_DOMINATORS);
+
return 0;
}
@@ -7637,6 +7640,9 @@ rest_of_handle_cse2 (void)
else if (tem == 1)
cleanup_cfg (0);
+ if (cse_cfg_altered && dom_info_available_p (CDI_DOMINATORS))
+ free_dominance_info (CDI_DOMINATORS);
+
cse_not_expected = 1;
return 0;
}
@@ -7695,7 +7701,7 @@ rest_of_handle_cse_after_global_opts (void)
rebuild_jump_labels (get_insns ());
tem = cse_main (get_insns (), max_reg_num ());
- purge_all_dead_edges ();
+ cse_cfg_altered |= purge_all_dead_edges ();
delete_trivially_dead_insns (get_insns (), max_reg_num ());
cse_not_expected = !flag_rerun_cse_after_loop;
@@ -7711,6 +7717,9 @@ rest_of_handle_cse_after_global_opts (void)
else if (tem == 1)
cleanup_cfg (0);
+ if (cse_cfg_altered && dom_info_available_p (CDI_DOMINATORS))
+ free_dominance_info (CDI_DOMINATORS);
+
flag_cse_follow_jumps = save_cfj;
return 0;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dc87b0c34d6..de582b8f357 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-05-11 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR middle-end/70807
+ * gcc.dg/pr70807.c: New test.
+
2016-05-10 Martin Sebor <msebor@redhat.com>
PR c++/38611
diff --git a/gcc/testsuite/gcc.dg/pr70807.c b/gcc/testsuite/gcc.dg/pr70807.c
new file mode 100644
index 00000000000..9ef2a4d9097
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr70807.c
@@ -0,0 +1,18 @@
+/* PR middle-end/70807 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef int INT;
+int a, b, c, d, e, f;
+void fn1() {
+ INT g;
+ if (d && a)
+ ;
+ else if (e && b)
+ ;
+ else if (!a && !b && c)
+ ;
+ else if (b && d || a && e)
+ a = 0;
+ f = g || d;
+}