diff options
author | Richard Biener <rguenther@suse.de> | 2013-01-16 13:57:48 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-01-16 13:57:48 +0000 |
commit | c25a0c60a5893ae7f4ba309b5b3bb2f336873683 (patch) | |
tree | bf26002dab1b0a5d65c7eb332ee9ec6f9b197e26 /gcc/tree-vrp.c | |
parent | 04b535af39f1c081d95961e4a7b0a0818182a7a6 (diff) | |
download | gcc-c25a0c60a5893ae7f4ba309b5b3bb2f336873683.zip gcc-c25a0c60a5893ae7f4ba309b5b3bb2f336873683.tar.gz gcc-c25a0c60a5893ae7f4ba309b5b3bb2f336873683.tar.bz2 |
re PR tree-optimization/54767 (Incorrect code generated with "-O2 -fcheck=bounds")
2013-01-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/54767
PR tree-optimization/53465
* tree-vrp.c (vrp_meet_1): Revert original fix for PR53465.
(vrp_visit_phi_node): For PHI arguments coming via backedges
drop all symbolical range information.
(execute_vrp): Compute backedges.
* gfortran.fortran-torture/execute/pr54767.f90: New testcase.
From-SVN: r195238
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index e902f6e..0efac60 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -7877,17 +7877,13 @@ vrp_meet_1 (value_range_t *vr0, value_range_t *vr1) if (vr0->type == VR_UNDEFINED) { - /* Drop equivalences. See PR53465. */ - set_value_range (vr0, vr1->type, vr1->min, vr1->max, NULL); + set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr1->equiv); return; } if (vr1->type == VR_UNDEFINED) { - /* VR0 already has the resulting range, just drop equivalences. - See PR53465. */ - if (vr0->equiv) - bitmap_clear (vr0->equiv); + /* VR0 already has the resulting range. */ return; } @@ -8012,6 +8008,21 @@ vrp_visit_phi_node (gimple phi) if (TREE_CODE (arg) == SSA_NAME) { vr_arg = *(get_value_range (arg)); + /* Do not allow equivalences or symbolic ranges to leak in from + backedges. That creates invalid equivalencies. + See PR53465 and PR54767. */ + if (e->flags & EDGE_DFS_BACK + && (vr_arg.type == VR_RANGE + || vr_arg.type == VR_ANTI_RANGE)) + { + vr_arg.equiv = NULL; + if (symbolic_range_p (&vr_arg)) + { + vr_arg.type = VR_VARYING; + vr_arg.min = NULL_TREE; + vr_arg.max = NULL_TREE; + } + } } else { @@ -9260,12 +9271,18 @@ execute_vrp (void) rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); scev_initialize (); + /* ??? This ends up using stale EDGE_DFS_BACK for liveness computation. + Inserting assertions may split edges which will invalidate + EDGE_DFS_BACK. */ insert_range_assertions (); to_remove_edges.create (10); to_update_switch_stmts.create (5); threadedge_initialize_values (); + /* For visiting PHI nodes we need EDGE_DFS_BACK computed. */ + mark_dfs_back_edges (); + vrp_initialize (); ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node); vrp_finalize (); |