Hi.
The patch is about more fine comparison of loop fields that
are mentioned in the PR.
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Ready to be installed?
Thanks,
Martin
gcc/ChangeLog:
2019-05-23 Martin Liska <[email protected]>
PR ipa/90555
* ipa-icf-gimple.c (func_checker::compare_loops): New function.
* ipa-icf-gimple.h (func_checker::compare_loops): Likewise.
* ipa-icf.c (sem_function::equals_private): Use compare_loops.
gcc/testsuite/ChangeLog:
2019-05-23 Martin Liska <[email protected]>
PR ipa/90555
* gcc.dg/ipa/pr90555.c: New test.
---
gcc/ipa-icf-gimple.c | 40 ++++++++++++++++++
gcc/ipa-icf-gimple.h | 3 ++
gcc/ipa-icf.c | 3 ++
gcc/testsuite/gcc.dg/ipa/pr90555.c | 67 ++++++++++++++++++++++++++++++
4 files changed, 113 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/ipa/pr90555.c
diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 25284936bc3..4d4e4c7c350 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-utils.h"
#include "tree-eh.h"
#include "builtins.h"
+#include "cfgloop.h"
#include "ipa-icf-gimple.h"
@@ -605,6 +606,45 @@ func_checker::compare_variable_decl (tree t1, tree t2)
return return_with_debug (ret);
}
+/* Compare significant loop information. */
+bool
+func_checker::compare_loops (void)
+{
+ struct loop *loop;
+
+ auto_vec <struct loop *> loops1;
+ auto_vec <struct loop *> loops2;
+
+ FOR_EACH_LOOP_FN (DECL_STRUCT_FUNCTION (m_source_func_decl), loop, 0)
+ loops1.safe_push (loop);
+
+ FOR_EACH_LOOP_FN (DECL_STRUCT_FUNCTION (m_target_func_decl), loop, 0)
+ loops2.safe_push (loop);
+
+ gcc_assert (loops1.length () == loops2.length ());
+
+ for (unsigned i = 0; i < loops1.length (); i++)
+ {
+ struct loop *l1 = loops1[i];
+ struct loop *l2 = loops2[i];
+ if (l1->simdlen != l2->simdlen)
+ return return_false_with_msg ("simdlen");
+ if (l1->safelen != l2->safelen)
+ return return_false_with_msg ("safelen");
+ if (l1->can_be_parallel != l2->can_be_parallel)
+ return return_false_with_msg ("can_be_parallel");
+ if (l1->dont_vectorize != l2->dont_vectorize)
+ return return_false_with_msg ("dont_vectorize");
+ if (l1->force_vectorize != l2->force_vectorize)
+ return return_false_with_msg ("force_vectorize");
+ if (l1->unroll != l2->unroll)
+ return return_false_with_msg ("unroll");
+ if (!compare_variable_decl (l1->simduid, l2->simduid))
+ return return_false_with_msg ("simduid");
+ }
+
+ return true;
+}
/* Function visits all gimple labels and creates corresponding
mapping between basic blocks and labels. */
diff --git a/gcc/ipa-icf-gimple.h b/gcc/ipa-icf-gimple.h
index 0035db32e66..0fb0744d912 100644
--- a/gcc/ipa-icf-gimple.h
+++ b/gcc/ipa-icf-gimple.h
@@ -226,6 +226,9 @@ public:
/* Verifies that trees T1 and T2 do correspond. */
bool compare_variable_decl (tree t1, tree t2);
+ /* Compare significant loop information. */
+ bool compare_loops (void);
+
/* Return true if types are compatible for polymorphic call analysis.
COMPARE_PTR indicates if polymorphic type comparsion should be
done for pointers, too. */
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 074181491da..ba5121f2198 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -926,6 +926,9 @@ sem_function::equals_private (sem_item *item)
if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
return return_false_with_msg ("PHI node comparison returns false");
+ if (!m_checker->compare_loops ())
+ return return_false_with_msg ("loops are different");
+
return result;
}
diff --git a/gcc/testsuite/gcc.dg/ipa/pr90555.c b/gcc/testsuite/gcc.dg/ipa/pr90555.c
new file mode 100644
index 00000000000..a9c751cd63c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr90555.c
@@ -0,0 +1,67 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp-simd -O2 -mavx512f -fdump-ipa-icf" } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+
+#define N 1024
+int a[N];
+
+void
+test_simdlen1 (void)
+{
+ int i;
+ #pragma omp simd simdlen (4)
+ for (i = 0; i < N; ++i)
+ a[i] = a[i] + 1;
+}
+
+void
+test_simdlen2 (void)
+{
+ int i;
+ #pragma omp simd simdlen (8)
+ for (i = 0; i < N; ++i)
+ a[i] = a[i] + 1;
+}
+
+void
+test_safelen1 (void)
+{
+ int i;
+ #pragma omp simd safelen (4)
+ for (i = 0; i < N; ++i)
+ a[i] = a[i] + 1;
+}
+
+void
+test_safelen2 (void)
+{
+ int i;
+ #pragma omp simd safelen (8)
+ for (i = 0; i < N; ++i)
+ a[i] = a[i] + 1;
+}
+
+int d[1024];
+
+int
+test_simduid1 (int j, int b)
+{
+ int l, c = 0;
+#pragma omp simd reduction(+: c)
+ for (l = 0; l < b; ++l)
+ c += d[j + l];
+ return c;
+}
+
+int
+test_simduid2 (int j, int b)
+{
+ int l, c2 = 0;
+#pragma omp simd reduction(+: c2)
+ for (l = 0; l < b; ++l)
+ c2 += d[j + l];
+ return c2;
+}
+
+/* { dg-final { scan-ipa-dump "Semantic equality hit:test_simduid1->test_simduid2" "icf" } } */
+/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf" } } */