https://gcc.gnu.org/g:15bf02001fd7ab5e22726d6288df51aa0b1db5f2

commit r15-10974-g15bf02001fd7ab5e22726d6288df51aa0b1db5f2
Author: Richard Biener <[email protected]>
Date:   Tue Feb 17 11:05:45 2026 +0100

    tree-optimization/124132 - fix type problem in loop splitting
    
    The following fixes the computation of the 2nd loop IV bound after
    loop splitting when only one of the split IV and the loop control
    variable is a pointer.
    
            PR tree-optimization/124132
            * tree-ssa-loop-split.cc (compute_new_first_bound): Fix
            bound difference computation.
    
            * gcc.dg/torture/pr124132.c: New testcase.
    
    (cherry picked from commit 9a5ee941a2cc525811748f78d42a36d1100c12d7)

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr124132.c | 16 ++++++++++++++++
 gcc/tree-ssa-loop-split.cc              | 19 ++++++++-----------
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr124132.c 
b/gcc/testsuite/gcc.dg/torture/pr124132.c
new file mode 100644
index 000000000000..8d14fc0346d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr124132.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-w" } */
+
+char slow_mul1_dst1, code_some_shards___gf_mulc__0, code_some_shards_lim;
+long slow_mul1_dst_max;
+long long code_some_shards_pos;
+void code_some_shards()
+{
+  char *dst = &slow_mul1_dst1;
+  for (; dst < &code_some_shards_lim; dst++)
+    {
+      if (code_some_shards_pos < slow_mul1_dst_max)
+        *dst = code_some_shards___gf_mulc__0;
+      code_some_shards_pos += 1;
+    }
+}
diff --git a/gcc/tree-ssa-loop-split.cc b/gcc/tree-ssa-loop-split.cc
index 5f78c0be2075..7ad193fe53db 100644
--- a/gcc/tree-ssa-loop-split.cc
+++ b/gcc/tree-ssa-loop-split.cc
@@ -458,21 +458,15 @@ compute_new_first_bound (gimple_seq *stmts, class 
tree_niter_desc *niter,
   tree end = force_gimple_operand (niter->bound, &stmts2,
                                        true, NULL_TREE);
   gimple_seq_add_seq_without_update (stmts, stmts2);
-  if (POINTER_TYPE_P (TREE_TYPE (enddiff)))
-    {
-      tree tem = gimple_convert (stmts, sizetype, enddiff);
-      tem = gimple_build (stmts, NEGATE_EXPR, sizetype, tem);
-      enddiff = gimple_build (stmts, POINTER_PLUS_EXPR,
-                             TREE_TYPE (enddiff),
-                             end, tem);
-    }
+  if (POINTER_TYPE_P (TREE_TYPE (controlbase)))
+    enddiff = gimple_build (stmts, POINTER_DIFF_EXPR,
+                           ssizetype, end, enddiff);
   else
     enddiff = gimple_build (stmts, MINUS_EXPR, TREE_TYPE (enddiff),
                            end, enddiff);
 
   /* Compute guard_init + (end-beg).  */
   tree newbound;
-  enddiff = gimple_convert (stmts, TREE_TYPE (guard_init), enddiff);
   if (POINTER_TYPE_P (TREE_TYPE (guard_init)))
     {
       enddiff = gimple_convert (stmts, sizetype, enddiff);
@@ -481,8 +475,11 @@ compute_new_first_bound (gimple_seq *stmts, class 
tree_niter_desc *niter,
                               guard_init, enddiff);
     }
   else
-    newbound = gimple_build (stmts, PLUS_EXPR, TREE_TYPE (guard_init),
-                            guard_init, enddiff);
+    {
+      enddiff = gimple_convert (stmts, TREE_TYPE (guard_init), enddiff);
+      newbound = gimple_build (stmts, PLUS_EXPR, TREE_TYPE (guard_init),
+                              guard_init, enddiff);
+    }
 
   /* Depending on the direction of the IVs the new bound for the first
      loop is the minimum or maximum of old bound and border.

Reply via email to