aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-09-08 12:40:30 +0200
committerRichard Biener <rguenther@suse.de>2025-09-11 11:16:58 +0200
commite9c2a69fe6fe1a20f8ad7b37ecbb3877cd14c514 (patch)
tree2bbb85d70a954b4c3648746c3bc128d28e8c3636
parent5c4f1313e753aeb6920a48c62c7c99ad36e1adae (diff)
downloadgcc-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.cc12
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr121829.c21
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];
+}