aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-09-08 14:32:38 +0200
committerRichard Biener <rguenth@gcc.gnu.org>2025-09-08 16:01:22 +0200
commit00cd34b1046076a3272f8e8e85c97dc8f4d2ea44 (patch)
tree18628b34cb228f0da0914f6bd161e7260e8adfaa /gcc
parent2abfcc6cfc9cd82fbbef47f2b03ee7595277023e (diff)
downloadgcc-00cd34b1046076a3272f8e8e85c97dc8f4d2ea44.zip
gcc-00cd34b1046076a3272f8e8e85c97dc8f4d2ea44.tar.gz
gcc-00cd34b1046076a3272f8e8e85c97dc8f4d2ea44.tar.bz2
tree-optimization/121844 - IVOPTs and asm goto in latch
When there's an asm goto in the latch of a loop we may not use IP_END IVs since instantiating those would (need to) split the latch edge which in turn invalidates IP_NORMAL position handling. This is a revision of the PR107997 fix. PR tree-optimization/107997 PR tree-optimization/121844 * tree-ssa-loop-ivopts.cc (allow_ip_end_pos_p): Do not allow IP_END for latches ending with a control stmt. (create_new_iv): Do not split the latch edge, instead assert that's not necessary. * gcc.dg/torture/pr121844.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr121844.c16
-rw-r--r--gcc/tree-ssa-loop-ivopts.cc13
2 files changed, 23 insertions, 6 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr121844.c b/gcc/testsuite/gcc.dg/torture/pr121844.c
new file mode 100644
index 0000000..149d5ea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121844.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+typedef unsigned long a;
+int b[] = {};
+int **c;
+short d(a *e, int f)
+{
+ *c = &f;
+ for (;;)
+ asm goto("" : : : : g);
+ for (; f; f--) {
+ asm goto("" : : : : g);
+ g:
+ *e ^= b[f + 1];
+ }
+}
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 2fe2655..ba727ad 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -3200,6 +3200,12 @@ add_candidate_1 (struct ivopts_data *data, tree base, tree step, bool important,
static bool
allow_ip_end_pos_p (class loop *loop)
{
+ /* Do not allow IP_END when creating the IV would need to split the
+ latch edge as that makes all IP_NORMAL invalid. */
+ auto pos = gsi_last_bb (ip_end_pos (loop));
+ if (!gsi_end_p (pos) && stmt_ends_bb_p (*pos))
+ return false;
+
if (!ip_normal_pos (loop))
return true;
@@ -7222,12 +7228,7 @@ create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
case IP_END:
incr_pos = gsi_last_bb (ip_end_pos (data->current_loop));
after = true;
- if (!gsi_end_p (incr_pos) && stmt_ends_bb_p (gsi_stmt (incr_pos)))
- {
- edge e = find_edge (gsi_bb (incr_pos), data->current_loop->header);
- incr_pos = gsi_after_labels (split_edge (e));
- after = false;
- }
+ gcc_assert (gsi_end_p (incr_pos) || !stmt_ends_bb_p (*incr_pos));
break;
case IP_AFTER_USE: