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