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.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
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.51.0