diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2020-10-19 19:04:40 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2020-10-19 19:11:17 -0400 |
commit | 6e02de946125c36871bd4d8eff21f7f88f01a8aa (patch) | |
tree | d56c07a37e03501257e2682ecccc234d5a29cdff /gcc/gimple-range-gori.cc | |
parent | f000b7c436e62c52798187d8150216569eef17b5 (diff) | |
download | gcc-6e02de946125c36871bd4d8eff21f7f88f01a8aa.zip gcc-6e02de946125c36871bd4d8eff21f7f88f01a8aa.tar.gz gcc-6e02de946125c36871bd4d8eff21f7f88f01a8aa.tar.bz2 |
Use precision and sign to compare types for ranges
Sanity check ranges by comparing just SIGN and PRECISION.
gcc/
PR tree-optimization/97360
* gimple-range.h (range_compatible_p): New.
* gimple-range-gori.cc (is_gimple_logical_p): Use range_compatible_p.
(range_is_either_true_or_false): Ditto.
(gori_compute::outgoing_edge_range_p): Cast result to the correct
type if necessary.
(logical_stmt_cache::cacheable_p): Use range_compatible_p.
* gimple-range.cc (gimple_ranger::calc_stmt): Check range_compatible_p
before casting the range.
(gimple_ranger::range_on_exit): Use range_compatible_p.
(gimple_ranger::range_on_edge): Ditto.
gcc/testsuite/
* gcc.dg/pr97360-2.c: New test.
Diffstat (limited to 'gcc/gimple-range-gori.cc')
-rw-r--r-- | gcc/gimple-range-gori.cc | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index c4bfc65..983f4c9 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -552,7 +552,7 @@ is_gimple_logical_p (const gimple *gs) case BIT_AND_EXPR: case BIT_IOR_EXPR: // Bitwise operations on single bits are logical too. - if (types_compatible_p (TREE_TYPE (gimple_assign_rhs1 (gs)), + if (range_compatible_p (TREE_TYPE (gimple_assign_rhs1 (gs)), boolean_type_node)) return true; break; @@ -618,7 +618,7 @@ range_is_either_true_or_false (const irange &r) // This is complicated by the fact that Ada has multi-bit booleans, // so true can be ~[0, 0] (i.e. [1,MAX]). tree type = r.type (); - gcc_checking_assert (types_compatible_p (type, boolean_type_node)); + gcc_checking_assert (range_compatible_p (type, boolean_type_node)); return (r.singleton_p () || !r.contains_p (build_zero_cst (type))); } @@ -999,11 +999,20 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name) // If NAME can be calculated on the edge, use that. if (m_gori_map->is_export_p (name, e->src)) - return compute_operand_range (r, stmt, lhs, name); - - // Otherwise see if NAME is derived from something that can be - // calculated. This performs no dynamic lookups whatsover, so it is - // low cost. + { + if (compute_operand_range (r, stmt, lhs, name)) + { + // Sometimes compatible types get interchanged. See PR97360. + // Make sure we are returning the type of the thing we asked for. + if (!r.undefined_p () && r.type () != TREE_TYPE (name)) + { + gcc_checking_assert (range_compatible_p (r.type (), + TREE_TYPE (name))); + range_cast (r, TREE_TYPE (name)); + } + return true; + } + } return false; } @@ -1156,7 +1165,7 @@ bool logical_stmt_cache::cacheable_p (gimple *stmt, const irange *lhs_range) const { if (gimple_code (stmt) == GIMPLE_ASSIGN - && types_compatible_p (TREE_TYPE (gimple_assign_lhs (stmt)), + && range_compatible_p (TREE_TYPE (gimple_assign_lhs (stmt)), boolean_type_node) && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME) { |