When the vectorizer removes a forwarder created earlier by split_edge
it uses redirect_edge_pred for convenience and efficiency. That breaks
down when the edge split is originating from an asm goto as that is
a jump that needs adjustments from redirect_edge_and_branch. The
following factores a simple vect_remove_forwarder handling this
situation appropriately.
Bootstrap and regtest running on x86_64-unknown-linux-gnu.
PR tree-optimization/121829
* cfgloopmanip.cc (create_preheader): Ensure we can insert
at the end of a preheader.
* gcc.dg/torture/pr121829.c: New testcase.
---
gcc/cfgloopmanip.cc | 12 +++++++++++-
gcc/testsuite/gcc.dg/torture/pr121829.c | 21 +++++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr121829.c
diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc
index 2c28437b34d..808f730b95e 100644
--- a/gcc/cfgloopmanip.cc
+++ b/gcc/cfgloopmanip.cc
@@ -32,6 +32,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop-manip.h"
#include "dumpfile.h"
#include "sreal.h"
+#include "tree-cfg.h"
+#include "tree-pass.h"
static void copy_loops_to (class loop **, int,
class loop *);
@@ -1615,7 +1617,15 @@ create_preheader (class loop *loop, int flags)
just a single successor and a normal edge. */
if ((flags & CP_SIMPLE_PREHEADERS)
&& ((single_entry->flags & EDGE_COMPLEX)
- || !single_succ_p (single_entry->src)))
+ || !single_succ_p (single_entry->src)
+ /* We document LOOPS_HAVE_PREHEADERS as to forming a
+ natural place to move code outside of the loop, so it
+ should not end with a control instruction. */
+ /* ??? This, and below JUMP_P check needs to be a new
+ CFG hook. */
+ || (cfun->curr_properties & PROP_gimple
+ && !gsi_end_p (gsi_last_bb (single_entry->src))
+ && stmt_ends_bb_p (*gsi_last_bb (single_entry->src)))))
need_forwarder_block = true;
/* If we want fallthru preheaders, also create forwarder block when
preheader ends with a jump or has predecessors from loop. */
diff --git a/gcc/testsuite/gcc.dg/torture/pr121829.c
b/gcc/testsuite/gcc.dg/torture/pr121829.c
new file mode 100644
index 00000000000..afcf7595a73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121829.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+int a[1][1];
+int *b(int *);
+int c() {
+ int *d[4];
+ int **e = &d[3];
+ int f;
+ for (; f; f++)
+ d[f] = &a[1][0];
+ b(*e);
+}
+int *b(int *g) {
+ asm goto("" : : : : h);
+ int i[9];
+h:
+ int f;
+ for (f = 0; f < 9; f++)
+ i[f] = 1;
+ *g = i[4];
+}
--
2.51.0