From 9a5ee941a2cc525811748f78d42a36d1100c12d7 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 17 Feb 2026 11:05:45 +0100 Subject: [PATCH] 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. --- gcc/testsuite/gcc.dg/torture/pr124132.c | 16 ++++++++++++++++ gcc/tree-ssa-loop-split.cc | 19 ++++++++----------- 2 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr124132.c diff --git a/gcc/testsuite/gcc.dg/torture/pr124132.c b/gcc/testsuite/gcc.dg/torture/pr124132.c new file mode 100644 index 00000000000..8d14fc0346d --- /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 ba6cc45d7f0..722383a420a 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. -- 2.47.3