[gcc r12-3347] Implement POINTER_DIFF_EXPR entry in range-op.

Aldy Hernandez aldyh@gcc.gnu.org
Fri Sep 3 16:40:42 GMT 2021


https://gcc.gnu.org/g:8af8abfbbace49e6e5e9413d4e661533437106a0

commit r12-3347-g8af8abfbbace49e6e5e9413d4e661533437106a0
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Fri Sep 3 10:01:25 2021 +0200

    Implement POINTER_DIFF_EXPR entry in range-op.
    
    I've seen cases in the upcoming jump threader enhancements where we see
    a difference of two pointers that are known to be equivalent, and yet we
    fail to return 0 for the range.  This is because we have no working
    range-op entry for POINTER_DIFF_EXPR.  The entry we currently have is
    a mere placeholder to avoid ignoring POINTER_DIFF_EXPR's so
    adjust_pointer_diff_expr() could get a whack at it here:
    
    //      def = __builtin_memchr (arg, 0, sz)
    //      n = def - arg
    //
    // The range for N can be narrowed to [0, PTRDIFF_MAX - 1].
    
    This patch adds the relational magic to range-op, which we can just
    steal from the minus_expr code.
    
    gcc/ChangeLog:
    
            * range-op.cc (operator_minus::op1_op2_relation_effect): Abstract
            out to...
            (minus_op1_op2_relation_effect): ...here.
            (class operator_pointer_diff): New.
            (operator_pointer_diff::op1_op2_relation_effect): Call
            minus_op1_op2_relation_effect.
            (integral_table::integral_table): Add entry for POINTER_DIFF_EXPR.

Diff:
---
 gcc/range-op.cc | 45 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 38 insertions(+), 7 deletions(-)

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index fee0e834c23..5e37133026d 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1372,13 +1372,14 @@ operator_minus::wi_fold (irange &r, tree type,
 }
 
 // Check to see if the relation REL between OP1 and OP2 has any effect on the
-// LHS of the expression.  If so, apply it to LHS_RANGE.
+// LHS of the expression.  If so, apply it to LHS_RANGE.  This is a helper
+// function for both MINUS_EXPR and POINTER_DIFF_EXPR.
 
-bool
-operator_minus::op1_op2_relation_effect (irange &lhs_range, tree type,
-				      const irange &op1_range ATTRIBUTE_UNUSED,
-				      const irange &op2_range ATTRIBUTE_UNUSED,
-				      relation_kind rel) const
+static bool
+minus_op1_op2_relation_effect (irange &lhs_range, tree type,
+			       const irange &op1_range ATTRIBUTE_UNUSED,
+			       const irange &op2_range ATTRIBUTE_UNUSED,
+			       relation_kind rel)
 {
   if (rel == VREL_NONE)
     return false;
@@ -1440,6 +1441,16 @@ operator_minus::op1_op2_relation_effect (irange &lhs_range, tree type,
   return true;
 }
 
+bool
+operator_minus::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_minus::op1_range (irange &r, tree type,
 			   const irange &lhs,
@@ -1459,6 +1470,26 @@ operator_minus::op2_range (irange &r, tree type,
 }
 
 
+class operator_pointer_diff : public range_operator
+{
+  virtual bool op1_op2_relation_effect (irange &lhs_range,
+					tree type,
+					const irange &op1_range,
+					const irange &op2_range,
+					relation_kind rel) const;
+} op_pointer_diff;
+
+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);
+}
+
+
 class operator_min : public range_operator
 {
 public:
@@ -4018,7 +4049,7 @@ integral_table::integral_table ()
   set (OBJ_TYPE_REF, op_identity);
   set (IMAGPART_EXPR, op_unknown);
   set (REALPART_EXPR, op_unknown);
-  set (POINTER_DIFF_EXPR, op_unknown);
+  set (POINTER_DIFF_EXPR, op_pointer_diff);
   set (ABS_EXPR, op_abs);
   set (ABSU_EXPR, op_absu);
   set (NEGATE_EXPR, op_negate);


More information about the Gcc-cvs mailing list