re PR tree-optimization/60023 (ICE: verify_gimple failed: dead STMT in EH table with...
authorJakub Jelinek <jakub@redhat.com>
Tue, 4 Feb 2014 13:08:00 +0000 (14:08 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 4 Feb 2014 13:08:00 +0000 (14:08 +0100)
PR tree-optimization/60023
* tree-if-conv.c (predicate_mem_writes): Pass true instead of
false to gsi_replace.
* tree-vect-stmts.c (vect_finish_stmt_generation): If stmt
has been in some EH region and vec_stmt could throw, add
vec_stmt into the same EH region.
* tree-data-ref.c (get_references_in_stmt): If IFN_MASK_LOAD
has no lhs, ignore it.
* internal-fn.c (expand_MASK_LOAD): Likewise.

* g++.dg/vect/pr60023.cc: New test.

From-SVN: r207464

gcc/ChangeLog
gcc/internal-fn.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/vect/pr60023.cc [new file with mode: 0644]
gcc/tree-data-ref.c
gcc/tree-if-conv.c
gcc/tree-vect-stmts.c

index 6c6dfd6cd9490928cd08dfe74baccb0002e0de09..17a62621325e227f2daaf894ed5836370c69c0c7 100644 (file)
@@ -1,5 +1,15 @@
 2014-02-04  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/60023
+       * tree-if-conv.c (predicate_mem_writes): Pass true instead of
+       false to gsi_replace.
+       * tree-vect-stmts.c (vect_finish_stmt_generation): If stmt
+       has been in some EH region and vec_stmt could throw, add
+       vec_stmt into the same EH region.
+       * tree-data-ref.c (get_references_in_stmt): If IFN_MASK_LOAD
+       has no lhs, ignore it.
+       * internal-fn.c (expand_MASK_LOAD): Likewise.
+
        PR ipa/60026
        * tree-inline.c (copy_forbidden): Fail for
        __attribute__((optimize (0))) functions.
index 43aaecba9718df0d045b4dd2dcb421625284c626..3efd2b119340c6ea0cb88d1e4f3fda5bd229aae5 100644 (file)
@@ -820,6 +820,8 @@ expand_MASK_LOAD (gimple stmt)
 
   maskt = gimple_call_arg (stmt, 2);
   lhs = gimple_call_lhs (stmt);
+  if (lhs == NULL_TREE)
+    return;
   type = TREE_TYPE (lhs);
   rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0),
                     gimple_call_arg (stmt, 1));
index f23b6c47455395e0080fc2a162ca76593a9df436..4c49fc3c2a7b702217d6c6bb4233a00dbc8e6561 100644 (file)
@@ -1,5 +1,8 @@
 2014-02-04  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/60023
+       * g++.dg/vect/pr60023.cc: New test.
+
        PR ipa/60026
        * c-c++-common/torture/pr60026.c: New test.
 
diff --git a/gcc/testsuite/g++.dg/vect/pr60023.cc b/gcc/testsuite/g++.dg/vect/pr60023.cc
new file mode 100644 (file)
index 0000000..78f325e
--- /dev/null
@@ -0,0 +1,80 @@
+// PR tree-optimization/60023
+// { dg-do compile }
+// { dg-additional-options "-O3 -std=c++11 -fnon-call-exceptions" }
+// { dg-additional-options "-mavx2" { target { i?86-*-* x86_64-*-* } } }
+
+struct A { A (); ~A (); };
+
+void
+f1 (int *p, int *q, int *r) noexcept (true)
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    if (r[i])
+      p[i] = q[i] + 1;
+}
+
+void
+f2 (int *p, int *q, int *r)
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    if (r[i])
+      p[i] = q[i] + 1;
+}
+
+void
+f3 (int *p, int *q) noexcept (true)
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    p[i] = q[i] + 1;
+}
+
+void
+f4 (int *p, int *q)
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    p[i] = q[i] + 1;
+}
+
+void
+f5 (int *p, int *q, int *r) noexcept (true)
+{
+  int i;
+  A a;
+  for (i = 0; i < 1024; i++)
+    if (r[i])
+      p[i] = q[i] + 1;
+}
+
+void
+f6 (int *p, int *q, int *r)
+{
+  int i;
+  A a;
+  for (i = 0; i < 1024; i++)
+    if (r[i])
+      p[i] = q[i] + 1;
+}
+
+void
+f7 (int *p, int *q) noexcept (true)
+{
+  int i;
+  A a;
+  for (i = 0; i < 1024; i++)
+    p[i] = q[i] + 1;
+}
+
+void
+f8 (int *p, int *q)
+{
+  int i;
+  A a;
+  for (i = 0; i < 1024; i++)
+    p[i] = q[i] + 1;
+}
+
+// { dg-final { cleanup-tree-dump "vect" } }
index 91601effccd5127b03270fedc221e03efc901bd7..01d0a7a79d832826f0e0109f20c5ed129f4bd388 100644 (file)
@@ -4401,6 +4401,8 @@ get_references_in_stmt (gimple stmt, vec<data_ref_loc, va_heap> *references)
        switch (gimple_call_internal_fn (stmt))
          {
          case IFN_MASK_LOAD:
+           if (gimple_call_lhs (stmt) == NULL_TREE)
+             break;
            ref.is_read = true;
          case IFN_MASK_STORE:
            ref.ref = fold_build2 (MEM_REF,
index d2327761724767135f8941eb1e20a2a6d71e4ca1..0dc340f15aab9336db5c18920b3b657db69458b1 100644 (file)
@@ -1723,7 +1723,7 @@ predicate_mem_writes (loop_p loop)
              new_stmt
                = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
                                              mask, rhs);
-           gsi_replace (&gsi, new_stmt, false);
+           gsi_replace (&gsi, new_stmt, true);
          }
        else if (gimple_vdef (stmt))
          {
index 2a2364d9542667fec9ecd011fcd6e11df108615f..8ed834bc5fa59c5fc153e94f6aaebb6e0aefe05a 100644 (file)
@@ -1691,6 +1691,13 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
     }
 
   gimple_set_location (vec_stmt, gimple_location (stmt));
+
+  /* While EH edges will generally prevent vectorization, stmt might
+     e.g. be in a must-not-throw region.  Ensure newly created stmts
+     that could throw are part of the same region.  */
+  int lp_nr = lookup_stmt_eh_lp (stmt);
+  if (lp_nr != 0 && stmt_could_throw_p (vec_stmt))
+    add_stmt_to_eh_lp (vec_stmt, lp_nr);
 }
 
 /* Checks if CALL can be vectorized in type VECTYPE.  Returns