The following adds POINTER_DIFF_EXPR handling to SCEV stmt analysis,
mapping to conversions and MINUS_EXPR.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
PR tree-optimization/122653
* tree-scalar-evolution.cc (interpret_rhs_expr): Handle
POINTER_DIFF_EXPR.
* gcc.dg/tree-ssa/scev-16.c: New testcase.
---
gcc/testsuite/gcc.dg/tree-ssa/scev-16.c | 19 +++++++++++++++++++
gcc/tree-scalar-evolution.cc | 14 ++++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/scev-16.c
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-16.c
b/gcc/testsuite/gcc.dg/tree-ssa/scev-16.c
new file mode 100644
index 00000000000..0cc7f703c53
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-16.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-sccp" } */
+
+extern char a[];
+int foo ()
+{
+ int cnt = 0;
+ char *aend = a + 32;
+ char *a0 = a;
+ do
+ {
+ a0 = a0 + 16;
+ cnt++;
+ }
+ while (aend - a0 > 12);
+ return cnt;
+}
+
+/* { dg-final { scan-tree-dump "return 2" "sccp" } } */
diff --git a/gcc/tree-scalar-evolution.cc b/gcc/tree-scalar-evolution.cc
index 180df75311f..626c201df5e 100644
--- a/gcc/tree-scalar-evolution.cc
+++ b/gcc/tree-scalar-evolution.cc
@@ -1753,6 +1753,20 @@ interpret_rhs_expr (class loop *loop, gimple *at_stmt,
res = chrec_fold_plus (type, chrec1, chrec2);
break;
+ case POINTER_DIFF_EXPR:
+ {
+ tree utype = unsigned_type_for (type);
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec2 = analyze_scalar_evolution (loop, rhs2);
+ chrec1 = chrec_convert (utype, chrec1, at_stmt);
+ chrec2 = chrec_convert (utype, chrec2, at_stmt);
+ chrec1 = instantiate_parameters (loop, chrec1);
+ chrec2 = instantiate_parameters (loop, chrec2);
+ res = chrec_fold_minus (utype, chrec1, chrec2);
+ res = chrec_convert (type, res, at_stmt);
+ break;
+ }
+
case PLUS_EXPR:
chrec1 = analyze_scalar_evolution (loop, rhs1);
chrec2 = analyze_scalar_evolution (loop, rhs2);
--
2.51.0