diff options
author | Richard Biener <rguenther@suse.de> | 2025-09-08 12:40:30 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2025-09-11 11:16:58 +0200 |
commit | e9c2a69fe6fe1a20f8ad7b37ecbb3877cd14c514 (patch) | |
tree | 2bbb85d70a954b4c3648746c3bc128d28e8c3636 | |
parent | 5c4f1313e753aeb6920a48c62c7c99ad36e1adae (diff) | |
download | gcc-e9c2a69fe6fe1a20f8ad7b37ecbb3877cd14c514.zip gcc-e9c2a69fe6fe1a20f8ad7b37ecbb3877cd14c514.tar.gz gcc-e9c2a69fe6fe1a20f8ad7b37ecbb3877cd14c514.tar.bz2 |
tree-optimization/121829 - bogus CFG with asm goto
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.
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.
-rw-r--r-- | gcc/cfgloopmanip.cc | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr121829.c | 21 |
2 files changed, 32 insertions, 1 deletions
diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index 2c28437..dda2fb6 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 0000000..afcf759 --- /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]; +} |