This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR41043
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 16 Feb 2010 17:00:08 +0100 (CET)
- Subject: [PATCH] Fix PR41043
This fixes PR41043 by pushing the inefficiency of SCEV towards more
artificial testcases. The problem is that VRP asks SCEV on way
too much variables where it IMHO only makes sense to ask SCEV
for loop PHI node results (everything else VRP should figure out
by propagating). Now, VRP calls SCEV for everything _but_ PHI
nodes for some odd reason (and there isn't a single testcase
that tests SCEV helping VRP ...).
So, the patch moves asking SCEV from assignments to loop PHI nodes,
also skipping the root of the loop tree.
We also ask SCEV for avoiding overflow warnings, I didn't touch
that code but Wstrict-overflow-18.c now fails, so it's obviously
called from the wrong spot. Also the testcase looks bogus as
p->a - p->b, both unsigned, can very well be larger than INT_MAX
and thus i can very well wrap.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
Thanks,
Richard.
2010-02-16 Richard Guenther <rguenther@suse.de>
PR tree-optimization/41043
* tree-vrp.c (vrp_var_may_overflow): Only ask SCEV for
real loops.
(vrp_visit_assignment_or_call): Do not ask SCEV for regular
statements ...
(vrp_visit_phi_node): ... but only for loop PHI nodes.
* gfortran.dg/pr41043.f90: New testcase.
* gcc.dg/Wstrict-overflow-18.c: XFAIL.
Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c (revision 156802)
--- gcc/tree-vrp.c (working copy)
*************** vrp_var_may_overflow (tree var, gimple s
*** 3280,3286 ****
return true;
l = loop_containing_stmt (stmt);
! if (l == NULL)
return true;
chrec = instantiate_parameters (l, analyze_scalar_evolution (l, var));
--- 3280,3287 ----
return true;
l = loop_containing_stmt (stmt);
! if (l == NULL
! || !loop_outer (l))
return true;
chrec = instantiate_parameters (l, analyze_scalar_evolution (l, var));
*************** vrp_visit_assignment_or_call (gimple stm
*** 5342,5348 ****
&& TYPE_MAX_VALUE (TREE_TYPE (lhs)))
|| POINTER_TYPE_P (TREE_TYPE (lhs))))
{
- struct loop *l;
value_range_t new_vr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
if (code == GIMPLE_CALL)
--- 5343,5348 ----
*************** vrp_visit_assignment_or_call (gimple stm
*** 5350,5361 ****
else
extract_range_from_assignment (&new_vr, stmt);
- /* If STMT is inside a loop, we may be able to know something
- else about the range of LHS by examining scalar evolution
- information. */
- if (current_loops && (l = loop_containing_stmt (stmt)))
- adjust_range_with_scev (&new_vr, l, stmt, lhs);
-
if (update_value_range (lhs, &new_vr))
{
*output_p = lhs;
--- 5350,5355 ----
*************** vrp_visit_phi_node (gimple phi)
*** 6259,6264 ****
--- 6253,6259 ----
value_range_t *lhs_vr = get_value_range (lhs);
value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
int edges, old_edges;
+ struct loop *l;
copy_value_range (&vr_result, lhs_vr);
*************** vrp_visit_phi_node (gimple phi)
*** 6322,6327 ****
--- 6317,6330 ----
}
}
+ /* If this is a loop PHI node SCEV may known more about its
+ value-range.
+ ??? Identify loop PHI nodes properly. */
+ if (current_loops
+ && (l = loop_containing_stmt (phi))
+ && loop_outer (l))
+ adjust_range_with_scev (&vr_result, l, phi, lhs);
+
if (vr_result.type == VR_VARYING)
goto varying;
Index: gcc/testsuite/gfortran.dg/pr41043.f90
===================================================================
*** gcc/testsuite/gfortran.dg/pr41043.f90 (revision 0)
--- gcc/testsuite/gfortran.dg/pr41043.f90 (revision 0)
***************
*** 0 ****
--- 1,11 ----
+ ! { dg-do compile }
+ ! { dg-options "-O2" }
+ subroutine foo
+ implicit none
+
+ integer :: i
+
+ call gee_i(int(i**huge(0_8),kind=kind(i)))
+
+ end subroutine foo
+
Index: gcc/testsuite/gcc.dg/Wstrict-overflow-18.c
===================================================================
*** gcc/testsuite/gcc.dg/Wstrict-overflow-18.c (revision 156802)
--- gcc/testsuite/gcc.dg/Wstrict-overflow-18.c (working copy)
***************
*** 2,8 ****
/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow" } */
/* Don't warn about an overflow when folding i > 0. The loop analysis
! should determine that i does not wrap. */
struct c { unsigned int a; unsigned int b; };
extern void bar (struct c *);
--- 2,11 ----
/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow" } */
/* Don't warn about an overflow when folding i > 0. The loop analysis
! should determine that i does not wrap.
!
! The test is really bogus, p->a - p->b can be larger than INT_MAX
! and thus i can very well wrap. */
struct c { unsigned int a; unsigned int b; };
extern void bar (struct c *);
*************** foo (struct c *p)
*** 14,20 ****
for (i = 0; i < p->a - p->b; ++i)
{
! if (i > 0)
sum += 2;
bar (p);
}
--- 17,23 ----
for (i = 0; i < p->a - p->b; ++i)
{
! if (i > 0) /* { dg-bogus "warning" "" { xfail *-*-* } } */
sum += 2;
bar (p);
}