aboutsummaryrefslogtreecommitdiff
path: root/gcc/range-op-float.cc
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2023-08-01 14:33:09 -0400
committerAndrew MacLeod <amacleod@redhat.com>2023-08-03 14:19:54 -0400
commit9fedc3c010ff81f290e4e97cbcd0847ca803dcc4 (patch)
tree5992855c966e51ac98a42c5c064ed986f1619191 /gcc/range-op-float.cc
parent33f080a7f1d70440d02de70af8f08eca21714abb (diff)
downloadgcc-9fedc3c010ff81f290e4e97cbcd0847ca803dcc4.zip
gcc-9fedc3c010ff81f290e4e97cbcd0847ca803dcc4.tar.gz
gcc-9fedc3c010ff81f290e4e97cbcd0847ca803dcc4.tar.bz2
Add operand ranges to op1_op2_relation API.
With additional floating point relations in the pipeline, we can no longer tell based on the LHS what the relation of X < Y is without knowing the type of X and Y. * gimple-range-fold.cc (fold_using_range::range_of_range_op): Add ranges to the call to relation_fold_and_or. (fold_using_range::relation_fold_and_or): Add op1 and op2 ranges. (fur_source::register_outgoing_edges): Add op1 and op2 ranges. * gimple-range-fold.h (relation_fold_and_or): Adjust params. * gimple-range-gori.cc (gori_compute::compute_operand_range): Add a varying op1 and op2 to call. * range-op-float.cc (range_operator::op1_op2_relation): New dafaults. (operator_equal::op1_op2_relation): New float version. (operator_not_equal::op1_op2_relation): Ditto. (operator_lt::op1_op2_relation): Ditto. (operator_le::op1_op2_relation): Ditto. (operator_gt::op1_op2_relation): Ditto. (operator_ge::op1_op2_relation) Ditto. * range-op-mixed.h (operator_equal::op1_op2_relation): New float prototype. (operator_not_equal::op1_op2_relation): Ditto. (operator_lt::op1_op2_relation): Ditto. (operator_le::op1_op2_relation): Ditto. (operator_gt::op1_op2_relation): Ditto. (operator_ge::op1_op2_relation): Ditto. * range-op.cc (range_op_handler::op1_op2_relation): Dispatch new variations. (range_operator::op1_op2_relation): Add extra params. (operator_equal::op1_op2_relation): Ditto. (operator_not_equal::op1_op2_relation): Ditto. (operator_lt::op1_op2_relation): Ditto. (operator_le::op1_op2_relation): Ditto. (operator_gt::op1_op2_relation): Ditto. (operator_ge::op1_op2_relation): Ditto. * range-op.h (range_operator): New prototypes. (range_op_handler): Ditto.
Diffstat (limited to 'gcc/range-op-float.cc')
-rw-r--r--gcc/range-op-float.cc129
1 files changed, 128 insertions, 1 deletions
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index a8d39cf..e30b489 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -244,7 +244,18 @@ range_operator::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
}
relation_kind
-range_operator::op1_op2_relation (const frange &lhs ATTRIBUTE_UNUSED) const
+range_operator::op1_op2_relation (const irange &,
+ const frange &,
+ const frange &) const
+{
+ return VREL_VARYING;
+}
+
+
+relation_kind
+range_operator::op1_op2_relation (const frange &,
+ const frange &,
+ const frange &) const
{
return VREL_VARYING;
}
@@ -705,6 +716,25 @@ operator_equal::op1_range (frange &r, tree type,
return true;
}
+// Check if the LHS range indicates a relation between OP1 and OP2.
+
+relation_kind
+operator_equal::op1_op2_relation (const irange &lhs, const frange &,
+ const frange &) const
+{
+ if (lhs.undefined_p ())
+ return VREL_UNDEFINED;
+
+ // FALSE = op1 == op2 indicates NE_EXPR.
+ if (lhs.zero_p ())
+ return VREL_NE;
+
+ // TRUE = op1 == op2 indicates EQ_EXPR.
+ if (lhs.undefined_p () || !contains_zero_p (lhs))
+ return VREL_EQ;
+ return VREL_VARYING;
+}
+
bool
operator_not_equal::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -809,6 +839,26 @@ operator_not_equal::op1_range (frange &r, tree type,
return true;
}
+
+// Check if the LHS range indicates a relation between OP1 and OP2.
+
+relation_kind
+operator_not_equal::op1_op2_relation (const irange &lhs, const frange &,
+ const frange &) const
+{
+ if (lhs.undefined_p ())
+ return VREL_UNDEFINED;
+
+ // FALSE = op1 != op2 indicates EQ_EXPR.
+ if (lhs.zero_p ())
+ return VREL_EQ;
+
+ // TRUE = op1 != op2 indicates NE_EXPR.
+ if (lhs.undefined_p () || !contains_zero_p (lhs))
+ return VREL_NE;
+ return VREL_VARYING;
+}
+
bool
operator_lt::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -903,6 +953,26 @@ operator_lt::op2_range (frange &r,
return true;
}
+
+// Check if the LHS range indicates a relation between OP1 and OP2.
+
+relation_kind
+operator_lt::op1_op2_relation (const irange &lhs, const frange &,
+ const frange &) const
+{
+ if (lhs.undefined_p ())
+ return VREL_UNDEFINED;
+
+ // FALSE = op1 < op2 indicates GE_EXPR.
+ if (lhs.zero_p ())
+ return VREL_GE;
+
+ // TRUE = op1 < op2 indicates LT_EXPR.
+ if (lhs.undefined_p () || !contains_zero_p (lhs))
+ return VREL_LT;
+ return VREL_VARYING;
+}
+
bool
operator_le::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -991,6 +1061,25 @@ operator_le::op2_range (frange &r,
return true;
}
+// Check if the LHS range indicates a relation between OP1 and OP2.
+
+relation_kind
+operator_le::op1_op2_relation (const irange &lhs, const frange &,
+ const frange &) const
+{
+ if (lhs.undefined_p ())
+ return VREL_UNDEFINED;
+
+ // FALSE = op1 <= op2 indicates GT_EXPR.
+ if (lhs.zero_p ())
+ return VREL_GT;
+
+ // TRUE = op1 <= op2 indicates LE_EXPR.
+ if (lhs.undefined_p () || !contains_zero_p (lhs))
+ return VREL_LE;
+ return VREL_VARYING;
+}
+
bool
operator_gt::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1089,6 +1178,25 @@ operator_gt::op2_range (frange &r,
return true;
}
+// Check if the LHS range indicates a relation between OP1 and OP2.
+
+relation_kind
+operator_gt::op1_op2_relation (const irange &lhs, const frange &,
+ const frange &) const
+{
+ if (lhs.undefined_p ())
+ return VREL_UNDEFINED;
+
+ // FALSE = op1 > op2 indicates LE_EXPR.
+ if (lhs.zero_p ())
+ return VREL_LE;
+
+ // TRUE = op1 > op2 indicates GT_EXPR.
+ if (!contains_zero_p (lhs))
+ return VREL_GT;
+ return VREL_VARYING;
+}
+
bool
operator_ge::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
@@ -1178,6 +1286,25 @@ operator_ge::op2_range (frange &r, tree type,
return true;
}
+// Check if the LHS range indicates a relation between OP1 and OP2.
+
+relation_kind
+operator_ge::op1_op2_relation (const irange &lhs, const frange &,
+ const frange &) const
+{
+ if (lhs.undefined_p ())
+ return VREL_UNDEFINED;
+
+ // FALSE = op1 >= op2 indicates LT_EXPR.
+ if (lhs.zero_p ())
+ return VREL_LT;
+
+ // TRUE = op1 >= op2 indicates GE_EXPR.
+ if (!contains_zero_p (lhs))
+ return VREL_GE;
+ return VREL_VARYING;
+}
+
// UNORDERED_EXPR comparison.
class foperator_unordered : public range_operator