Hi,
this patch fixes graphite PR68715, a 6 regression.
In scop_detection::merge_sese, we check if the exit bb of the merged
sese region is dominated by the entry bb:
...
if (...
|| !dominated_by_p (CDI_DOMINATORS, get_exit_bb (combined),
get_entry_bb (combined)))
{
...
return invalid_sese;
}
...
Subsequently, we check for an empty exit bb, and if that one's not
empty, we try to merge an empty successor block into the sese:
...
/* FIXME: We should remove this piece of code once
canonicalize_loop_closed_ssa has been removed, because that
function adds a BB with single exit. */
if (!trivially_empty_bb_p (get_exit_bb (combined)))
{
/* Find the first empty succ (with single exit) of
combined.exit. */
basic_block imm_succ = combined.exit->dest;
if (single_succ_p (imm_succ)
&& trivially_empty_bb_p (imm_succ))
combined.exit = single_succ_edge (imm_succ);
else
{
...
return invalid_sese;
}
}
...
However, when the imm_succ block has more than one predecessor, merging
the block into the sese region breaks the property that the exit bb is
dominated by the entry bb. We then run into an ICE in
harmful_loop_in_region a bit later, when re-checking that property.
The patch fixes this by adding a test for 'single_pred_p (imm_succ)' in
the empty-block-merge condition.
Bootstrapped and reg-tested on x86_64.
OK for stage4 trunk?
Thanks,
- Tom
Add missing single_pred_p test in scop_detection::merge_sese
2016-03-15 Tom de Vries <t...@codesourcery.com>
PR tree-optimization/68715
* graphite-scop-detection.c (scop_detection::merge_sese): Add missing
single_pred_p test.
* gcc.dg/graphite/pr68715-2.c: New test.
* gcc.dg/graphite/pr68715.c: New test.
* gfortran.dg/graphite/pr68715.f90: New test.
---
gcc/graphite-scop-detection.c | 4 ++-
gcc/testsuite/gcc.dg/graphite/pr68715-2.c | 35 +++++++++++++++++++++++++
gcc/testsuite/gcc.dg/graphite/pr68715.c | 36 ++++++++++++++++++++++++++
gcc/testsuite/gfortran.dg/graphite/pr68715.f90 | 31 ++++++++++++++++++++++
4 files changed, 105 insertions(+), 1 deletion(-)
diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c
index 9161cb7..f0c13ee 100644
--- a/gcc/graphite-scop-detection.c
+++ b/gcc/graphite-scop-detection.c
@@ -836,7 +836,9 @@ scop_detection::merge_sese (sese_l first, sese_l second) const
{
/* Find the first empty succ (with single exit) of combined.exit. */
basic_block imm_succ = combined.exit->dest;
- if (single_succ_p (imm_succ) && trivially_empty_bb_p (imm_succ))
+ if (single_succ_p (imm_succ)
+ && single_pred_p (imm_succ)
+ && trivially_empty_bb_p (imm_succ))
combined.exit = single_succ_edge (imm_succ);
else
{
diff --git a/gcc/testsuite/gcc.dg/graphite/pr68715-2.c b/gcc/testsuite/gcc.dg/graphite/pr68715-2.c
new file mode 100644
index 0000000..270d948
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/pr68715-2.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -floop-interchange" } */
+
+int a, b, c, d, f, g;
+int e[1], h[1];
+void fn2 ();
+void fn3 ();
+void
+fn1 ()
+{
+ fn2 ();
+ b = 0;
+ for (; b < 10; b++)
+ ;
+}
+
+void
+fn2 ()
+{
+ if (a)
+ {
+ fn3 ();
+ c = d;
+ }
+}
+
+void
+fn3 ()
+{
+ for (; g; g++)
+ e[g] = 2;
+ if (f)
+ for (; g; g++)
+ h[g] = 5;
+}
diff --git a/gcc/testsuite/gcc.dg/graphite/pr68715.c b/gcc/testsuite/gcc.dg/graphite/pr68715.c
new file mode 100644
index 0000000..14da2fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/pr68715.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -floop-interchange" } */
+
+int a[1], c[1];
+int b, d, e;
+
+void
+fn1 (int p1)
+{
+ for (;;)
+ ;
+}
+
+int
+fn3 ()
+{
+ for (; e; e++)
+ c[e] = 2;
+ for (; d; d--)
+ a[d] = 8;
+ return 0;
+}
+
+int fn5 (int);
+
+int
+fn2 ()
+{
+ fn3 ();
+}
+
+void
+fn4 ()
+{
+ fn1 (b || fn5 (fn2 ()));
+}
diff --git a/gcc/testsuite/gfortran.dg/graphite/pr68715.f90 b/gcc/testsuite/gfortran.dg/graphite/pr68715.f90
new file mode 100644
index 0000000..c011756
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/graphite/pr68715.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! { dg-options "-floop-nest-optimize -O1" }
+
+SUBROUTINE se_core_core_interaction(calculate_forces)
+ INTEGER, PARAMETER :: dp=8
+ LOGICAL, INTENT(in) :: calculate_forces
+ REAL(KIND=dp), DIMENSION(3) :: force_ab, rij
+ LOGICAL :: lfoo,kfoo,mfoo,nfoo,ffoo
+ INTEGER, PARAMETER :: mi2=42
+ CALL dummy(lfoo,kfoo,mfoo,nfoo,method_id,core_core)
+ IF (lfoo) THEN
+ DO WHILE (ffoo())
+ IF (lfoo) CYCLE
+ IF (kfoo) CYCLE
+ dr1 = DOT_PRODUCT(rij,rij)
+ IF (dr1 > rij_threshold) THEN
+ SELECT CASE (method_id)
+ CASE (mi2)
+ IF (calculate_forces) THEN
+ CALL dummy2(force_ab)
+ IF (nfoo) THEN
+ force_ab = force_ab + core_core*dr3inv
+ END IF
+ END IF
+ END SELECT
+ END IF
+ enuclear = enuclear + enucij
+ END DO
+ CALL dummy3(enuclear)
+ END IF
+END SUBROUTINE se_core_core_interaction