This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR43627
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 2 Apr 2010 18:56:09 +0200 (CEST)
- Subject: [PATCH] Fix PR43627
This is a patch to address a missed-optimization fallout of no longer
querying SCEV for each and every SSA name during VRP. And also
another fallout of the -Wstrict-overflow code.
The patch re-surrects one simple propagation, a widening operation
of a range with overflow infinity bound. We can widen such
range to the wider range with its overflow infinity as bound (if
such is available). That retains warnings and the optimization
in this case.
I made the patch as conservative as possible, but 2nd eyes
can help. The regression itself looks serious enough, but
being not wrong-code but simply a missed-optimization issue
we can defer it to 4.5.1 as well.
Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for
4.5.0?
Thanks,
Richard.
2010-04-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43627
* tree-vrp.c (extract_range_from_unary_expr): Widenings
of [1, +INF(OVF)] go to [1, +INF(OVF)] of the wider type,
not varying.
* gcc.dg/tree-ssa/vrp49.c: New testcase.
Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c (revision 157942)
--- gcc/tree-vrp.c (working copy)
*************** extract_range_from_unary_expr (value_ran
*** 2714,2721 ****
|| vr0.type == VR_ANTI_RANGE)
&& TREE_CODE (vr0.min) == INTEGER_CST
&& TREE_CODE (vr0.max) == INTEGER_CST
! && !is_overflow_infinity (vr0.min)
! && !is_overflow_infinity (vr0.max)
&& (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
|| (vr0.type == VR_RANGE
&& integer_zerop (int_const_binop (RSHIFT_EXPR,
--- 2714,2729 ----
|| vr0.type == VR_ANTI_RANGE)
&& TREE_CODE (vr0.min) == INTEGER_CST
&& TREE_CODE (vr0.max) == INTEGER_CST
! && (!is_overflow_infinity (vr0.min)
! || (vr0.type == VR_RANGE
! && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)
! && needs_overflow_infinity (outer_type)
! && supports_overflow_infinity (outer_type)))
! && (!is_overflow_infinity (vr0.max)
! || (vr0.type == VR_RANGE
! && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)
! && needs_overflow_infinity (outer_type)
! && supports_overflow_infinity (outer_type)))
&& (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
|| (vr0.type == VR_RANGE
&& integer_zerop (int_const_binop (RSHIFT_EXPR,
*************** extract_range_from_unary_expr (value_ran
*** 2729,2734 ****
--- 2737,2746 ----
new_max = force_fit_type_double (outer_type,
TREE_INT_CST_LOW (vr0.max),
TREE_INT_CST_HIGH (vr0.max), 0, 0);
+ if (is_overflow_infinity (vr0.min))
+ new_min = negative_overflow_infinity (outer_type);
+ if (is_overflow_infinity (vr0.max))
+ new_max = positive_overflow_infinity (outer_type);
set_and_canonicalize_value_range (vr, vr0.type,
new_min, new_max, NULL);
return;
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp49.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/vrp49.c (revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/vrp49.c (revision 0)
***************
*** 0 ****
--- 1,28 ----
+ /* { dg-do link } */
+ /* { dg-options "-O2" } */
+
+ extern void link_error (void) __attribute__((noreturn));
+ int n;
+ float *x;
+ int main()
+ {
+ if (n > 0)
+ {
+ int i = 0;
+ do
+ {
+ long long index;
+ i = i + 1;
+ index = i;
+ if (index <= 0)
+ link_error ();
+ x[index] = 0;
+ i = i + 1;
+ index = i;
+ if (index <= 0)
+ link_error ();
+ x[index] = 0;
+ }
+ while (i < n);
+ }
+ }