aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Macleod <amacleod@gcc.gnu.org>2019-05-14 20:45:44 +0000
committerAndrew Macleod <amacleod@gcc.gnu.org>2019-05-14 20:45:44 +0000
commitf93950a6a13e95fcb3ce6d985bfdd41527075b3f (patch)
treed435f0ae2d9ea12ecb61b7096bc2824abbc2357b /gcc
parentf0aab60ce401de986eb18ddadf67f459bb0cbbf6 (diff)
downloadgcc-f93950a6a13e95fcb3ce6d985bfdd41527075b3f.zip
gcc-f93950a6a13e95fcb3ce6d985bfdd41527075b3f.tar.gz
gcc-f93950a6a13e95fcb3ce6d985bfdd41527075b3f.tar.bz2
Fix Jeff's veusz bug, and adjust the trace output to be more useful.
From-SVN: r271191
Diffstat (limited to 'gcc')
-rw-r--r--gcc/range-op.c9
-rw-r--r--gcc/ssa-range.cc92
-rw-r--r--gcc/ssa-range.h7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/rvrp-and-1.c44
4 files changed, 105 insertions, 47 deletions
diff --git a/gcc/range-op.c b/gcc/range-op.c
index 8671c7d..465eafe 100644
--- a/gcc/range-op.c
+++ b/gcc/range-op.c
@@ -562,8 +562,13 @@ op_wi (enum tree_code code, irange &r, tree rh_type,
must_be_nonzero_rh,
may_be_nonzero_rh))
{
- accumulate_range (r, new_lb, new_ub);
- irange_adjust_bit_and_mask (r, s, lh_lb, lh_ub, rh_lb, rh_ub);
+ // For AND, calculate each subrange separately, and then union
+ // the results.
+ irange tmp;
+ tmp.set_undefined (r.type ());
+ accumulate_range (tmp, new_lb, new_ub);
+ irange_adjust_bit_and_mask (tmp, s, lh_lb, lh_ub, rh_lb, rh_ub);
+ r.union_ (tmp);
return true;
}
r.set_varying (type);
diff --git a/gcc/ssa-range.cc b/gcc/ssa-range.cc
index a9f27aa..4512f3f 100644
--- a/gcc/ssa-range.cc
+++ b/gcc/ssa-range.cc
@@ -800,8 +800,7 @@ global_ranger::~global_ranger ()
{
}
-// Return the range of NAME on entry to block BB in R. Return false if there
-// is no range other than varying.
+// Return the range of NAME on entry to block BB in R.
void
global_ranger::range_on_entry (irange &r, basic_block bb, tree name)
@@ -946,24 +945,23 @@ global_ranger::export_global_ranges ()
irange old_range = range_from_ssa (name);
gcc_checking_assert (old_range.intersect (r) == r);
- if (dump_file)
- {
- print_generic_expr (dump_file, name , TDF_SLIM);
- fprintf (dump_file, " --> ");
- r.dump (dump_file);
- fprintf (dump_file, "\n");
- }
-
// WTF? Can't write non-null pointer ranges?? stupid set_range_info!
- if (POINTER_TYPE_P (TREE_TYPE (name)))
- continue;
- if (r.undefined_p ())
- continue;
-
- if (!dbg_cnt (ranger_export_count))
- return;
+ if (!POINTER_TYPE_P (TREE_TYPE (name)) && !r.undefined_p ())
+ {
+ if (!dbg_cnt (ranger_export_count))
+ return;
- set_range_info (name, irange_to_value_range (r));
+ value_range_base vr = irange_to_value_range (r);
+ set_range_info (name, vr);
+ if (dump_file)
+ {
+ print_generic_expr (dump_file, name , TDF_SLIM);
+ fprintf (dump_file, " --> ");
+ vr.dump (dump_file);
+ fprintf (dump_file, " irange : ");
+ r.dump (dump_file);
+ }
+ }
}
}
}
@@ -1155,19 +1153,21 @@ loop_ranger::range_of_phi (irange &r, gphi *phi, tree name,
trace_ranger::trace_ranger ()
{
indent = 0;
- counter = 0;
+ trace_count = 0;
}
// If dumping, return true and print the prefix for the next output line.
inline bool
-trace_ranger::dumping ()
+trace_ranger::dumping (unsigned counter, bool trailing)
{
- counter++;
if (dump_file && (dump_flags & TDF_DETAILS))
{
// Print counter index as well as INDENT spaces.
- fprintf (dump_file, " %-7u", counter);
+ if (!trailing)
+ fprintf (dump_file, " %-7u ", counter);
+ else
+ fprintf (dump_file, " ");
unsigned x;
for (x = 0; x< indent; x++)
fputc (' ', dump_file);
@@ -1180,13 +1180,14 @@ trace_ranger::dumping ()
// returning RESULT.
bool
-trace_ranger::trailer (const char *caller, bool result, tree name,
- const irange &r)
+trace_ranger::trailer (unsigned counter, const char *caller, bool result,
+ tree name, const irange &r)
{
indent -= bump;
- if (dumping ())
+ if (dumping (counter, true))
{
fputs(result ? "TRUE : " : "FALSE : ", dump_file);
+ fprintf (dump_file, "(%u) ", counter);
fputs (caller, dump_file);
fputs (" (",dump_file);
if (name)
@@ -1209,7 +1210,8 @@ bool
trace_ranger::range_of_expr (irange &r, tree expr, gimple *s)
{
bool res;
- if (dumping ())
+ unsigned idx = ++trace_count;
+ if (dumping (idx))
{
fprintf (dump_file, "range_of_expr (");
print_generic_expr (dump_file, expr, TDF_SLIM);
@@ -1221,9 +1223,9 @@ trace_ranger::range_of_expr (irange &r, tree expr, gimple *s)
indent += bump;
}
- res = super::range_of_expr (r, expr, s);
+ res = super::range_of_expr (r, expr, s);
- return trailer ("range_of_expr", res, expr, r);
+ return trailer (idx, "range_of_expr", res, expr, r);
}
// Tracing version of edge range_of_expr. Call it with printing wrappers.
@@ -1232,7 +1234,8 @@ bool
trace_ranger::range_of_expr (irange &r, tree expr, edge e)
{
bool res;
- if (dumping ())
+ unsigned idx = ++trace_count;
+ if (dumping (idx))
{
fprintf (dump_file, "range_of_expr (");
print_generic_expr (dump_file, expr, TDF_SLIM);
@@ -1242,7 +1245,7 @@ trace_ranger::range_of_expr (irange &r, tree expr, edge e)
res = super::range_of_expr (r, expr, e);
- return trailer ("range_of_expr", res, expr, r);
+ return trailer (idx, "range_of_expr", res, expr, r);
}
// Tracing version of range_on_edge. Call it with printing wrappers.
@@ -1250,7 +1253,8 @@ trace_ranger::range_of_expr (irange &r, tree expr, edge e)
void
trace_ranger::range_on_edge (irange &r, edge e, tree name)
{
- if (dumping ())
+ unsigned idx = ++trace_count;
+ if (dumping (idx))
{
fprintf (dump_file, "range_on_edge (");
print_generic_expr (dump_file, name, TDF_SLIM);
@@ -1260,7 +1264,7 @@ trace_ranger::range_on_edge (irange &r, edge e, tree name)
super::range_on_edge (r, e, name);
- trailer ("range_on_edge", true, name, r);
+ trailer (idx, "range_on_edge", true, name, r);
}
// Tracing version of range_on_entry. Call it with printing wrappers.
@@ -1268,7 +1272,8 @@ trace_ranger::range_on_edge (irange &r, edge e, tree name)
void
trace_ranger::range_on_entry (irange &r, basic_block bb, tree name)
{
- if (dumping ())
+ unsigned idx = ++trace_count;
+ if (dumping (idx))
{
fprintf (dump_file, "range_on_entry (");
print_generic_expr (dump_file, name, TDF_SLIM);
@@ -1278,7 +1283,7 @@ trace_ranger::range_on_entry (irange &r, basic_block bb, tree name)
super::range_on_entry (r, bb, name);
- trailer ("range_on_entry", true, name, r);
+ trailer (idx, "range_on_entry", true, name, r);
}
// Tracing version of range_on_exit. Call it with printing wrappers.
@@ -1286,7 +1291,8 @@ trace_ranger::range_on_entry (irange &r, basic_block bb, tree name)
void
trace_ranger::range_on_exit (irange &r, basic_block bb, tree name)
{
- if (dumping ())
+ unsigned idx = ++trace_count;
+ if (dumping (idx))
{
fprintf (dump_file, "range_on_exit (");
print_generic_expr (dump_file, name, TDF_SLIM);
@@ -1296,7 +1302,7 @@ trace_ranger::range_on_exit (irange &r, basic_block bb, tree name)
super::range_on_exit (r, bb, name);
- trailer ("range_on_exit", true, name, r);
+ trailer (idx, "range_on_exit", true, name, r);
}
// Tracing version of range_of_stmt. Call it with printing wrappers.
@@ -1305,7 +1311,8 @@ bool
trace_ranger::range_of_stmt (irange &r, gimple *s, tree name)
{
bool res;
- if (dumping ())
+ unsigned idx = ++trace_count;
+ if (dumping (idx))
{
fprintf (dump_file, "range_of_stmt (");
if (name)
@@ -1315,9 +1322,9 @@ trace_ranger::range_of_stmt (irange &r, gimple *s, tree name)
indent += bump;
}
- res = super::range_of_stmt (r, s, name);
+ res = super::range_of_stmt (r, s, name);
- return trailer ("range_of_stmt", res, name, r);
+ return trailer (idx, "range_of_stmt", res, name, r);
}
// Tracing version of outgoing_edge_range_p. Call it with printing wrappers.
@@ -1327,7 +1334,8 @@ trace_ranger::outgoing_edge_range_p (irange &r, edge e, tree name,
irange *name_range)
{
bool res;
- if (dumping ())
+ unsigned idx = ++trace_count;
+ if (dumping (idx))
{
fprintf (dump_file, "outgoing_edge_range_p (");
print_generic_expr (dump_file, name, TDF_SLIM);
@@ -1340,7 +1348,7 @@ trace_ranger::outgoing_edge_range_p (irange &r, edge e, tree name,
indent += bump;
}
- res = super::outgoing_edge_range_p (r, e, name, name_range);
+ res = super::outgoing_edge_range_p (r, e, name, name_range);
- return trailer ("outgoing_edge_range_p", res, name, r);
+ return trailer (idx, "outgoing_edge_range_p", res, name, r);
}
diff --git a/gcc/ssa-range.h b/gcc/ssa-range.h
index 0b1b3d9..44201a0 100644
--- a/gcc/ssa-range.h
+++ b/gcc/ssa-range.h
@@ -179,10 +179,11 @@ private:
typedef global_ranger super; // Inherited from class for easy changing.
static const unsigned bump = 2;
unsigned indent;
- unsigned counter;
+ unsigned trace_count; // Current trace index count.
- bool dumping ();
- bool trailer (const char *caller, bool result, tree name, const irange &r);
+ bool dumping (unsigned counter, bool trailing = false);
+ bool trailer (unsigned counter, const char *caller, bool result, tree name,
+ const irange &r);
};
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/rvrp-and-1.c b/gcc/testsuite/gcc.dg/tree-ssa/rvrp-and-1.c
new file mode 100644
index 0000000..0f88d47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/rvrp-and-1.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-options "-O2 " } */
+
+extern void abort(void);
+
+/* Distilled from fedora package veusz where we were not combining bitwise
+ * AND's properly.
+ * The test adds lots fo conditions so that if the range is not accurate,
+ * it will shortcut the result and not get to the return 1 checks. */
+
+int
+foo(int a, int i)
+{
+ if (i == 32 || i == 64 || i == 128)
+ {
+ int r = a & i;
+ if (r < 32 || r > 128)
+ return 0;
+ if (r >32 && r < 64)
+ return 0;
+ if (r > 64 && r < 128)
+ return 0;
+ if (r == 32)
+ return 1;
+ if (r == 64)
+ return 1;
+ if (r == 128)
+ return 1;
+ }
+ return 0;
+}
+
+
+int main()
+{
+ int x;
+ int count = 0;
+ for (x = 0; x < 255; x++)
+ if (foo (255, x))
+ count++;
+
+ if (count != 3)
+ abort();
+}