aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Macleod <amacleod@gcc.gnu.org>2019-05-08 03:05:30 +0000
committerAndrew Macleod <amacleod@gcc.gnu.org>2019-05-08 03:05:30 +0000
commite40abc4dda1d22500d9e2e99fab413c60d99dfb1 (patch)
tree8bfcfa9fb6b392839bb92e275e331c182ed2b7c9 /gcc
parent4c2213aafd61054eceb71cb631bd5cb8d48f5963 (diff)
downloadgcc-e40abc4dda1d22500d9e2e99fab413c60d99dfb1.zip
gcc-e40abc4dda1d22500d9e2e99fab413c60d99dfb1.tar.gz
gcc-e40abc4dda1d22500d9e2e99fab413c60d99dfb1.tar.bz2
Fix rvrp-abs-3 which recognizes that the IMAGPART_EXPR result of an builtin ADD/SUB overflow call is actully a boolean flag.. so its range is [0,1].
tweaked the op_cast routine to handle this better by FIRSt trying the cast rhs to lhs and back trick if that fails,then we look at the weird masking of -1. obscure enough? lookit the code. p-This line, and those below, will be ignored-- M gcc/range-op.c M gcc/ssa-range-gori.h M gcc/ssa-range.cc M gcc/ssa-range.h M gcc/testsuite/gcc.dg/tree-ssa/rvrp-abs-3.c From-SVN: r270998
Diffstat (limited to 'gcc')
-rw-r--r--gcc/range-op.c63
-rw-r--r--gcc/ssa-range-gori.h1
-rw-r--r--gcc/ssa-range.cc9
-rw-r--r--gcc/ssa-range.h1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/rvrp-abs-3.c5
5 files changed, 34 insertions, 45 deletions
diff --git a/gcc/range-op.c b/gcc/range-op.c
index 106d92b..8671c7d 100644
--- a/gcc/range-op.c
+++ b/gcc/range-op.c
@@ -1548,51 +1548,52 @@ operator_cast::op1_range (irange& r, const irange& lhs,
tree op2_type = op2.type ();
irange op_type;
- /* Special case if the LHS is a boolean. A 0 means the RHS is zero, and a 1
- means the RHS is non-zero. */
- if (TREE_CODE (lhs_type) == BOOLEAN_TYPE)
- {
- /* If the LHS is unknown, the result is whatever op2 already is. */
- if (!lhs.singleton_p ())
- {
- r = op2;
- return true;
- }
- /* Boolean casts are weird in GCC. ITs actually an implied mask with 0x01,
- so all that is known is whther the rightmost bit is 0 or 1, which
- implies the only known value *not* in the RHS is 0 or -1. */
- unsigned prec = TYPE_PRECISION (op2_type);
- if (lhs.zero_p ())
- r = irange (op2_type, wi::minus_one (prec), wi::minus_one (prec),
- irange::INVERSE);
- else
- r = irange (op2_type, wi::zero (prec), wi::zero (prec),
- irange::INVERSE);
- /* And intersect it with what we know about op2. */
- r.intersect (op2);
- return true;
- }
-
+
/* If the precision of the LHS is smaller than the precision of the RHS,
then there would be truncation of the value on the RHS, and so we can tell
nothing about it. */
if (TYPE_PRECISION (lhs_type) < TYPE_PRECISION (op2_type))
{
- // If we've been passed an actual value for the RHS rather than the type
- // see if it fits the LHS, and if so, then we can allow it.
+ /* If we've been passed an actual value for the RHS rather than the type
+ see if it fits the LHS, and if so, then we can allow it. */
r = op2;
r.cast (lhs_type);
r.cast (op2_type);
if (r == op2)
{
- // we know the value of the RHS fits in the LHS type, so convert the
- // left hand side and remove any values that arent in OP2.
+ /* We know the value of the RHS fits in the LHS type, so convert the
+ left hand side and remove any values that arent in OP2. */
r = lhs;
r.cast (op2_type);
r.intersect (op2);
+ return true;
}
- else
- r = op2;
+ /* Special case if the LHS is a boolean. A 0 means the RHS is zero,
+ and a 1 means the RHS is non-zero. */
+ else if (TREE_CODE (lhs_type) == BOOLEAN_TYPE)
+ {
+ /* If the LHS is unknown, the result is whatever op2 already is. */
+ if (!lhs.singleton_p ())
+ {
+ r = op2;
+ return true;
+ }
+ /* Boolean casts are weird in GCC. ITs actually an implied mask with
+ 0x01, so all that is known is whether the rightmost bit is 0 or 1,
+ which implies the only value *not* in the RHS is 0 or -1. */
+ unsigned prec = TYPE_PRECISION (op2_type);
+ if (lhs.zero_p ())
+ r = irange (op2_type, wi::minus_one (prec), wi::minus_one (prec),
+ irange::INVERSE);
+ else
+ r = irange (op2_type, wi::zero (prec), wi::zero (prec),
+ irange::INVERSE);
+ /* And intersect it with what we know about op2. */
+ r.intersect (op2);
+ return true;
+ }
+ /* Otherwise we'll have to assume it's whatever we know about op2. */
+ r = op2;
return true;
}
diff --git a/gcc/ssa-range-gori.h b/gcc/ssa-range-gori.h
index be57cee..e98b309 100644
--- a/gcc/ssa-range-gori.h
+++ b/gcc/ssa-range-gori.h
@@ -157,6 +157,7 @@ public:
bool has_edge_range_p (edge e, tree name);
bool outgoing_edge_range_p (irange &r, edge e, tree name,
irange *name_range = NULL);
+protected:
bool range_from_import (irange &r, tree name, irange &import_range);
private:
// Evaluate the range for NAME on stmt S if the lhs has range LHS.
diff --git a/gcc/ssa-range.cc b/gcc/ssa-range.cc
index 07bae5e3..8868315 100644
--- a/gcc/ssa-range.cc
+++ b/gcc/ssa-range.cc
@@ -920,15 +920,6 @@ global_ranger::terminal_name (tree name)
return m_gori.terminal_name (name);
}
-// Calculate a range for NAME via it's def chain using IMPORT_RANGE as the
-// range of the terminal name.
-
-bool
-global_ranger::range_from_import (irange &r, tree name, irange &import_range)
-{
- return m_gori.range_from_import (r, name, import_range);
-}
-
// This routine will export whatever global ranges are known to GCC
// SSA_RANGE_NAME_INFO fields.
diff --git a/gcc/ssa-range.h b/gcc/ssa-range.h
index 5c9dfb7..0b1b3d9 100644
--- a/gcc/ssa-range.h
+++ b/gcc/ssa-range.h
@@ -131,7 +131,6 @@ public:
virtual bool outgoing_edge_range_p (irange &r, edge e, tree name,
irange *name_range = NULL);
tree terminal_name (tree name);
- bool range_from_import (irange &r, tree name, irange &import_range);
void export_global_ranges ();
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/rvrp-abs-3.c b/gcc/testsuite/gcc.dg/tree-ssa/rvrp-abs-3.c
index 4671884..3db66d5 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/rvrp-abs-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/rvrp-abs-3.c
@@ -4,7 +4,4 @@
#define ADD_NW(A,B) (__extension__({ __typeof(A+B) R; if(__builtin_add_overflow(A,B,&R)) __builtin_unreachable(); R ;}))
_Bool a_b2(unsigned A, unsigned B) { return ADD_NW(A,B) >= B; }
-/* { dg-final { scan-tree-dump "return 1;" "rvrp" { xfail *-*-* } } } */
-
-/* FIXME: We need to handle IMAGPART_EXPR going back to the
- .ADD_OVERFLOW. and returning a range of [0, 1]. */
+/* { dg-final { scan-tree-dump "return 1;" "rvrp" } } */