diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2023-08-01 14:33:09 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2023-08-03 14:19:54 -0400 |
commit | 9fedc3c010ff81f290e4e97cbcd0847ca803dcc4 (patch) | |
tree | 5992855c966e51ac98a42c5c064ed986f1619191 /gcc/range-op-float.cc | |
parent | 33f080a7f1d70440d02de70af8f08eca21714abb (diff) | |
download | gcc-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.cc | 129 |
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 |