From: Richard Biener <rguenther@suse.de>
To: gcc-patches@gcc.gnu.org
Cc: aldyh@redhat.com
Subject: Re: [PATCH] Fix some EVRP stupidness
Date: Thu, 18 Oct 2018 13:09:00 -0000 [thread overview]
Message-ID: <alpine.LSU.2.20.1810181359190.4374@zhemvz.fhfr.qr> (raw)
In-Reply-To: <alpine.LSU.2.20.1810181248510.4374@zhemvz.fhfr.qr>
[-- Attachment #1: Type: text/plain, Size: 14777 bytes --]
On Thu, 18 Oct 2018, Richard Biener wrote:
>
> At some point we decided to not simply intersect all ranges we get
> via register_edge_assert_for. Instead we simply register them
> in-order. That causes things like replacing [64, +INF] with ~[0, 0].
>
> The following patch avoids replacing a range with a larger one
> as obvious improvement.
>
> Compared to assert_expr based VRP we lack the ability to put down
> actual assert_exprs and thus multiple SSA names with ranges we
> could link via equivalences. In the end we need sth similar,
> for example by keeping a stack of active ranges for each SSA name.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Actually not. Needed to update to the new value_range class and after
that (and its introduction of ->check()) we now ICE during bootstrap
with
during GIMPLE pass: evrp
/space/rguenther/src/svn/trunk/libgcc/config/libbid/bid128_div.c: In
function Β‘get_BID128Β’:
/space/rguenther/src/svn/trunk/libgcc/config/libbid/bid128_div.c:1851:1:
internal compiler error: in check, at tree-vrp.c:155
1851 | }
| ^
0xf3a8b5 value_range::check()
/space/rguenther/src/svn/trunk/gcc/tree-vrp.c:155
0xf42424 value_range::value_range(value_range_kind, tree_node*,
tree_node*, bitmap_head*)
/space/rguenther/src/svn/trunk/gcc/tree-vrp.c:110
0xf42424 set_value_range_with_overflow
/space/rguenther/src/svn/trunk/gcc/tree-vrp.c:1422
0xf42424 extract_range_from_binary_expr_1(value_range*, tree_code,
tree_node*, value_range const*, value_range const*)
/space/rguenther/src/svn/trunk/gcc/tree-vrp.c:1679
for a PLUS_EXPR of [12254, expon_43] and [-1, -1] yielding
(temporarily!) [12254, -1] before supposed to be adjusted by the
symbolic bound:
/* Adjust the range for possible overflow. */
set_value_range_with_overflow (*vr, expr_type,
wmin, wmax, min_ovf, max_ovf);
^^^ ICE
if (vr->varying_p ())
return;
/* Build the symbolic bounds if needed. */
min = vr->min ();
max = vr->max ();
adjust_symbolic_bound (min, code, expr_type,
sym_min_op0, sym_min_op1,
neg_min_op0, neg_min_op1);
adjust_symbolic_bound (max, code, expr_type,
sym_max_op0, sym_max_op1,
neg_max_op0, neg_max_op1);
type = vr->kind ();
I think the refactoring that was applied here is simply not suitable
because *vr is _not_ necessarily a valid range before the symbolic
bounds have been adjusted. A fix would be sth like the following
which I am going to test now.
Richard.
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 40d40e5e2fe..c5748a43246 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1328,7 +1328,7 @@ combine_bound (enum tree_code code, wide_int &wi,
wi::overflow_type &ovf,
underflow. +1 indicates overflow. 0 indicates neither. */
static void
-set_value_range_with_overflow (value_range &vr,
+set_value_range_with_overflow (value_range_kind &kind, tree &min, tree
&max,
tree type,
const wide_int &wmin, const wide_int &wmax,
wi::overflow_type min_ovf,
@@ -1341,7 +1341,7 @@ set_value_range_with_overflow (value_range &vr,
range covers all values. */
if (prec == 1 && wi::lt_p (wmax, wmin, sgn))
{
- set_value_range_to_varying (&vr);
+ kind = VR_VARYING;
return;
}
@@ -1357,13 +1357,15 @@ set_value_range_with_overflow (value_range &vr,
the entire range. We have a similar check at the end of
extract_range_from_binary_expr_1. */
if (wi::gt_p (tmin, tmax, sgn))
- vr.set_varying ();
+ kind = VR_VARYING;
else
- /* No overflow or both overflow or underflow. The
- range kind stays VR_RANGE. */
- vr = value_range (VR_RANGE,
- wide_int_to_tree (type, tmin),
- wide_int_to_tree (type, tmax));
+ {
+ kind = VR_RANGE;
+ /* No overflow or both overflow or underflow. The
+ range kind stays VR_RANGE. */
+ min = wide_int_to_tree (type, tmin);
+ max = wide_int_to_tree (type, tmax);
+ }
return;
}
else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
@@ -1384,18 +1386,18 @@ set_value_range_with_overflow (value_range &vr,
types values. */
if (covers || wi::cmp (tmin, tmax, sgn) > 0)
{
- set_value_range_to_varying (&vr);
+ kind = VR_VARYING;
return;
}
- vr = value_range (VR_ANTI_RANGE,
- wide_int_to_tree (type, tmin),
- wide_int_to_tree (type, tmax));
+ kind = VR_ANTI_RANGE;
+ min = wide_int_to_tree (type, tmin);
+ max = wide_int_to_tree (type, tmax);
return;
}
else
{
/* Other underflow and/or overflow, drop to VR_VARYING. */
- set_value_range_to_varying (&vr);
+ kind = VR_VARYING;
return;
}
}
@@ -1405,7 +1407,7 @@ set_value_range_with_overflow (value_range &vr,
value. */
wide_int type_min = wi::min_value (prec, sgn);
wide_int type_max = wi::max_value (prec, sgn);
- tree min, max;
+ kind = VR_RANGE;
if (min_ovf == wi::OVF_UNDERFLOW)
min = wide_int_to_tree (type, type_min);
else if (min_ovf == wi::OVF_OVERFLOW)
@@ -1419,7 +1421,6 @@ set_value_range_with_overflow (value_range &vr,
max = wide_int_to_tree (type, type_max);
else
max = wide_int_to_tree (type, wmax);
- vr = value_range (VR_RANGE, min, max);
}
}
@@ -1676,21 +1677,20 @@ extract_range_from_binary_expr_1 (value_range *vr,
}
/* Adjust the range for possible overflow. */
- set_value_range_with_overflow (*vr, expr_type,
+ min = NULL_TREE;
+ max = NULL_TREE;
+ set_value_range_with_overflow (type, min, max, expr_type,
wmin, wmax, min_ovf, max_ovf);
- if (vr->varying_p ())
+ if (type == VR_VARYING)
return;
/* Build the symbolic bounds if needed. */
- min = vr->min ();
- max = vr->max ();
adjust_symbolic_bound (min, code, expr_type,
sym_min_op0, sym_min_op1,
neg_min_op0, neg_min_op1);
adjust_symbolic_bound (max, code, expr_type,
sym_max_op0, sym_max_op1,
neg_max_op0, neg_max_op1);
- type = vr->kind ();
}
else
{
> Richard.
>
> 2018-10-18 Richard Biener <rguenther@suse.de>
>
> * gimple-ssa-evrp-analyze.c
> (evrp_range_analyzer::record_ranges_from_incoming_edge): Be
> smarter about what ranges to use.
> * tree-vrp.c (add_assert_info): Dump here.
> (register_edge_assert_for_2): Instead of here at multiple but
> not all places.
>
> * gcc.dg/tree-ssa/evrp12.c: New testcase.
> * gcc.dg/predict-6.c: Adjust.
> * gcc.dg/tree-ssa/vrp33.c: Disable EVRP.
> * gcc.dg/tree-ssa/vrp02.c: Likewise.
> * gcc.dg/tree-ssa/cunroll-9.c: Likewise.
>
> diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
> index e9afa80e191..0748a53cdb8 100644
> --- a/gcc/gimple-ssa-evrp-analyze.c
> +++ b/gcc/gimple-ssa-evrp-analyze.c
> @@ -206,6 +206,17 @@ evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
> ordering issues that can lead to worse ranges. */
> for (unsigned i = 0; i < vrs.length (); ++i)
> {
> + /* But make sure we do not weaken ranges like when
> + getting first [64, +INF] and then ~[0, 0] from
> + conditions like (s & 0x3cc0) == 0). */
> + value_range *old_vr = get_value_range (vrs[i].first);
> + value_range tem = *old_vr;
> + tem.equiv = NULL;
> + vrp_intersect_ranges (&tem, vrs[i].second);
> + if (tem.type == old_vr->type
> + && tem.min == old_vr->min
> + && tem.max == old_vr->max)
> + continue;
> push_value_range (vrs[i].first, vrs[i].second);
> if (is_fallthru
> && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt))
> diff --git a/gcc/testsuite/gcc.dg/predict-6.c b/gcc/testsuite/gcc.dg/predict-6.c
> index 5d6fbf158f2..08ce5cdb81d 100644
> --- a/gcc/testsuite/gcc.dg/predict-6.c
> +++ b/gcc/testsuite/gcc.dg/predict-6.c
> @@ -10,9 +10,9 @@ void foo (int base, int bound)
> int i, ret = 0;
> for (i = base; i <= bound; i++)
> {
> - if (i < base)
> + if (i <= base)
> global += bar (i);
> - if (i < base + 1)
> + if (i < base + 2)
> global += bar (i);
> if (i <= base + 3)
> global += bar (i);
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-9.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-9.c
> index 0e4407dcbd7..886dc147ad1 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-9.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-9.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-cunrolli-details" } */
> +/* { dg-options "-O2 -fdump-tree-cunrolli-details -fdisable-tree-evrp" } */
> void abort (void);
> int q (void);
> int a[10];
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp12.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp12.c
> new file mode 100644
> index 00000000000..b3906c23465
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp12.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-evrp" } */
> +
> +extern void link_error ();
> +
> +void
> +f3 (unsigned int s)
> +{
> + if ((s & 0x3cc0) == 0)
> + {
> + if (s >= -15552U)
> + link_error ();
> + }
> + else
> + {
> + if (s <= 0x3f)
> + link_error ();
> + }
> +}
> +
> +/* { dg-final { scan-tree-dump-not "link_error" "evrp" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c
> index 8d14feadb6a..4be538f5944 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-vrp1 -fdelete-null-pointer-checks" } */
> +/* { dg-options "-O2 -fdump-tree-vrp1 -fdelete-null-pointer-checks -fdisable-tree-evrp" } */
>
> struct A
> {
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
> index 75fefa49925..f1d3863943e 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
> @@ -1,5 +1,5 @@
> /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-fre" } */
> +/* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-fre -fdisable-tree-evrp" } */
>
> /* This is from PR14052. */
>
> diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
> index cbc2ea2f26b..6f5ec43670e 100644
> --- a/gcc/tree-vrp.c
> +++ b/gcc/tree-vrp.c
> @@ -2133,6 +2133,17 @@ add_assert_info (vec<assert_info> &asserts,
> info.val = val;
> info.expr = expr;
> asserts.safe_push (info);
> +
> + if (dump_file && (dump_flags & TDF_DETAILS))
> + {
> + fprintf (dump_file, "Adding assert for ");
> + print_generic_expr (dump_file, name);
> + fprintf (dump_file, " from ");
> + print_generic_expr (dump_file, expr);
> + fprintf (dump_file, " %s ", op_symbol_code (comp_code));
> + print_generic_expr (dump_file, val);
> + fprintf (dump_file, "\n");
> + }
> }
>
> /* If NAME doesn't have an ASSERT_EXPR registered for asserting
> @@ -2532,16 +2543,6 @@ register_edge_assert_for_2 (tree name, edge e,
> tmp = build1 (NOP_EXPR, TREE_TYPE (name), name3);
> if (cst2 != NULL_TREE)
> tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
> -
> - if (dump_file)
> - {
> - fprintf (dump_file, "Adding assert for ");
> - print_generic_expr (dump_file, name3);
> - fprintf (dump_file, " from ");
> - print_generic_expr (dump_file, tmp);
> - fprintf (dump_file, "\n");
> - }
> -
> add_assert_info (asserts, name3, tmp, comp_code, val);
> }
>
> @@ -2559,16 +2560,6 @@ register_edge_assert_for_2 (tree name, edge e,
> tmp = build1 (NOP_EXPR, TREE_TYPE (name), tmp);
> if (cst2 != NULL_TREE)
> tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
> -
> - if (dump_file)
> - {
> - fprintf (dump_file, "Adding assert for ");
> - print_generic_expr (dump_file, name2);
> - fprintf (dump_file, " from ");
> - print_generic_expr (dump_file, tmp);
> - fprintf (dump_file, "\n");
> - }
> -
> add_assert_info (asserts, name2, tmp, comp_code, val);
> }
> }
> @@ -2691,16 +2682,6 @@ register_edge_assert_for_2 (tree name, edge e,
> cst = fold_build2 (MINUS_EXPR, TREE_TYPE (name2), cst,
> build_int_cst (TREE_TYPE (name2), 1));
> }
> -
> - if (dump_file)
> - {
> - fprintf (dump_file, "Adding assert for ");
> - print_generic_expr (dump_file, name2);
> - fprintf (dump_file, " from ");
> - print_generic_expr (dump_file, tmp);
> - fprintf (dump_file, "\n");
> - }
> -
> add_assert_info (asserts, name2, tmp, new_comp_code, cst);
> }
> }
> @@ -2765,18 +2746,7 @@ register_edge_assert_for_2 (tree name, edge e,
> }
>
> if (new_val)
> - {
> - if (dump_file)
> - {
> - fprintf (dump_file, "Adding assert for ");
> - print_generic_expr (dump_file, name2);
> - fprintf (dump_file, " from ");
> - print_generic_expr (dump_file, tmp);
> - fprintf (dump_file, "\n");
> - }
> -
> - add_assert_info (asserts, name2, tmp, new_comp_code, new_val);
> - }
> + add_assert_info (asserts, name2, tmp, new_comp_code, new_val);
> }
>
> /* Add asserts for NAME cmp CST and NAME being defined as
> @@ -3004,16 +2974,6 @@ register_edge_assert_for_2 (tree name, edge e,
> maxv2 = maxv - minv;
> }
> new_val = wide_int_to_tree (type, maxv2);
> -
> - if (dump_file)
> - {
> - fprintf (dump_file, "Adding assert for ");
> - print_generic_expr (dump_file, names[i]);
> - fprintf (dump_file, " from ");
> - print_generic_expr (dump_file, tmp);
> - fprintf (dump_file, "\n");
> - }
> -
> add_assert_info (asserts, names[i], tmp, LE_EXPR, new_val);
> }
> }
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)
next prev parent reply other threads:[~2018-10-18 12:11 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-18 11:27 Richard Biener
2018-10-18 13:09 ` Richard Biener [this message]
2018-10-18 16:15 ` Aldy Hernandez
2018-10-18 16:52 ` Richard Biener
2018-10-22 14:08 ` Richard Biener
2018-10-22 14:22 ` David Malcolm
2018-10-22 14:25 ` Richard Biener
2018-11-11 2:10 ` [PATCH] Ensure that dump calls are guarded with dump_enabled_p David Malcolm
2018-11-11 19:10 ` Martin Sebor
2018-11-11 21:01 ` David Malcolm
2018-11-11 21:46 ` Segher Boessenkool
2018-11-12 8:12 ` Richard Biener
2018-10-23 8:50 ` [PATCH] Fix some EVRP stupidness Aldy Hernandez
2018-10-23 8:52 ` Richard Biener
2018-10-23 12:35 ` Richard Biener
2018-10-23 12:45 ` Aldy Hernandez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LSU.2.20.1810181359190.4374@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=aldyh@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).