From 774ad67fba458dd1beaa0f2d3e389aac46ca18b5 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Mon, 21 Oct 2024 16:32:00 -0400
Subject: [PATCH] Implement operator_pointer_diff::fold_range
prange has no default fold_range processing like irange does, so each
pointer specific operator needs to implement its own fold routine.
PR tree-optimization/117222
gcc/
* range-op-ptr.cc (operator_pointer_diff::fold_range): New.
(operator_pointer_diff::op1_op2_relation_effect): Remove irange
variant.
(operator_pointer_diff::update_bitmask): Likewise.
gcc/testsuite
* g++.dg/pr117222.C: New.
---
gcc/range-op-ptr.cc | 37 ++++++++++++++++++---------------
gcc/testsuite/g++.dg/pr117222.C | 16 ++++++++++++++
2 files changed, 36 insertions(+), 17 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/pr117222.C
@@ -567,25 +567,38 @@ pointer_or_operator::wi_fold (irange &r, tree type,
class operator_pointer_diff : public range_operator
{
+ using range_operator::fold_range;
using range_operator::update_bitmask;
using range_operator::op1_op2_relation_effect;
- virtual bool op1_op2_relation_effect (irange &lhs_range,
- tree type,
- const irange &op1_range,
- const irange &op2_range,
- relation_kind rel) const;
+ virtual bool fold_range (irange &r, tree type,
+ const prange &op1,
+ const prange &op2,
+ relation_trio trio) const final override;
virtual bool op1_op2_relation_effect (irange &lhs_range,
tree type,
const prange &op1_range,
const prange &op2_range,
relation_kind rel) const final override;
- void update_bitmask (irange &r, const irange &lh, const irange &rh) const
- { update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); }
void update_bitmask (irange &r,
const prange &lh, const prange &rh) const final override
{ update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); }
} op_pointer_diff;
+bool
+operator_pointer_diff::fold_range (irange &r, tree type,
+ const prange &op1,
+ const prange &op2,
+ relation_trio trio) const
+{
+ gcc_checking_assert (r.supports_type_p (type));
+
+ r.set_varying (type);
+ relation_kind rel = trio.op1_op2 ();
+ op1_op2_relation_effect (r, type, op1, op2, rel);
+ update_bitmask (r, op1, op2);
+ return true;
+}
+
bool
operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
const prange &op1_range,
@@ -602,16 +615,6 @@ operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
return minus_op1_op2_relation_effect (lhs_range, type, op1, op2, rel);
}
-bool
-operator_pointer_diff::op1_op2_relation_effect (irange &lhs_range, tree type,
- const irange &op1_range,
- const irange &op2_range,
- relation_kind rel) const
-{
- return minus_op1_op2_relation_effect (lhs_range, type, op1_range, op2_range,
- rel);
-}
-
bool
operator_identity::fold_range (prange &r, tree type ATTRIBUTE_UNUSED,
const prange &lh ATTRIBUTE_UNUSED,
new file mode 100644
@@ -0,0 +1,16 @@
+// { dg-do compile }
+// { dg-require-effective-target c++11 }
+// { dg-options "-O3 -fdump-tree-evrp" }
+
+#include <vector>
+int main()
+{
+ std::vector<int> c {1,2,3,0};
+ while(c.size() > 0 && c.back() == 0)
+ {
+ auto sz = c.size() -1;
+ c.resize(sz);
+ }
+ return 0;
+}
+/* { dg-final { scan-tree-dump "Global Exported.*\[-INF, -1\]\[1, +INF\]" "evrp" } } */
--
2.45.0