This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/21029] [4.1 Regression] vrp miscompiles Ada front-end, drops loop exit test in well-defined wrap-around circumstances
- From: "sebastian dot pop at cri dot ensmp dot fr" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 29 Apr 2005 19:51:48 -0000
- Subject: [Bug tree-optimization/21029] [4.1 Regression] vrp miscompiles Ada front-end, drops loop exit test in well-defined wrap-around circumstances
- References: <20050414201608.21029.aoliva@gcc.gnu.org>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From sebastian dot pop at cri dot ensmp dot fr 2005-04-29 19:51 -------
Subject: Re: [PR tree-optimization/21029, RFC] harmful chrec type conversions
Thanks to Roger Sayle for pointing me at this PR.
Alexandre Oliva wrote:
>
> This is not a final patch; if the idea is considered sound, I'd simply
> remove the if and the then-dead remaining code in chrec_convert.
The code following the if is not dead, at least it still is used in
some cases after hand inlining count_ev_in_wider_type. I would
propose this patch that is about the same as yours
> Index: gcc/ChangeLog
> from Alexandre Oliva <aoliva@redhat.com>
>
> PR tree-optimization/21029
> * tree-chrec.c (chrec_convert): Handle same-precision integral
> types that differ in signedness like widening conversions.
>
with some more changes as follow:
* tree-chrec.c (chrec_convert): Handle same-precision integral
types that differ in signedness like widening conversions.
Inline count_ev_in_wider_type.
* tree-chrec.h (count_ev_in_wider_type): Remove declaration.
* tree-scalar-evolution.c (count_ev_in_wider_type): Removed.
Zdenek, does this change look right to you?
Index: tree-chrec.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-chrec.c,v
retrieving revision 2.15
diff -c -3 -p -r2.15 tree-chrec.c
*** tree-chrec.c 21 Apr 2005 08:48:51 -0000 2.15
--- tree-chrec.c 29 Apr 2005 19:31:51 -0000
*************** tree
*** 1036,1085 ****
chrec_convert (tree type,
tree chrec)
{
! tree ct;
!
if (automatically_generated_chrec_p (chrec))
return chrec;
!
ct = chrec_type (chrec);
if (ct == type)
return chrec;
! if (TYPE_PRECISION (ct) < TYPE_PRECISION (type))
! return count_ev_in_wider_type (type, chrec);
!
! switch (TREE_CODE (chrec))
{
! case POLYNOMIAL_CHREC:
! return build_polynomial_chrec (CHREC_VARIABLE (chrec),
! chrec_convert (type,
! CHREC_LEFT (chrec)),
! chrec_convert (type,
! CHREC_RIGHT (chrec)));
!
! default:
! {
! tree res = fold_convert (type, chrec);
!
! /* Don't propagate overflows. */
! TREE_OVERFLOW (res) = 0;
! if (CONSTANT_CLASS_P (res))
! TREE_CONSTANT_OVERFLOW (res) = 0;
!
! /* But reject constants that don't fit in their type after conversion.
! This can happen if TYPE_MIN_VALUE or TYPE_MAX_VALUE are not the
! natural values associated with TYPE_PRECISION and TYPE_UNSIGNED,
! and can cause problems later when computing niters of loops. Note
! that we don't do the check before converting because we don't want
! to reject conversions of negative chrecs to unsigned types. */
! if (TREE_CODE (res) == INTEGER_CST
! && TREE_CODE (type) == INTEGER_TYPE
! && !int_fits_type_p (res, type))
! res = chrec_dont_know;
!
! return res;
! }
}
}
/* Returns the type of the chrec. */
--- 1036,1104 ----
chrec_convert (tree type,
tree chrec)
{
! tree ct, base, step;
! struct loop *loop;
!
if (automatically_generated_chrec_p (chrec))
return chrec;
!
ct = chrec_type (chrec);
if (ct == type)
return chrec;
! if (!evolution_function_is_affine_p (chrec))
{
! switch (TREE_CODE (chrec))
! {
! case POLYNOMIAL_CHREC:
! return build_polynomial_chrec (CHREC_VARIABLE (chrec),
! chrec_convert (type,
! CHREC_LEFT (chrec)),
! chrec_convert (type,
! CHREC_RIGHT (chrec)));
!
! default:
! {
! tree res = fold_convert (type, chrec);
!
! /* Don't propagate overflows. */
! TREE_OVERFLOW (res) = 0;
! if (CONSTANT_CLASS_P (res))
! TREE_CONSTANT_OVERFLOW (res) = 0;
!
! /* But reject constants that don't fit in their type after
! conversion. This can happen if TYPE_MIN_VALUE or
! TYPE_MAX_VALUE are not the natural values associated
! with TYPE_PRECISION and TYPE_UNSIGNED, and can cause
! problems later when computing niters of loops. Note
! that we don't do the check before converting because we
! don't want to reject conversions of negative chrecs to
! unsigned types. */
! if (TREE_CODE (res) == INTEGER_CST
! && TREE_CODE (type) == INTEGER_TYPE
! && !int_fits_type_p (res, type))
! res = chrec_dont_know;
!
! return res;
! }
! }
}
+
+ /* BASE and STEP are INTEGER_CSTs. */
+ base = CHREC_LEFT (chrec);
+ step = CHREC_RIGHT (chrec);
+ loop = current_loops->parray[CHREC_VARIABLE (chrec)];
+
+ /* TODO -- if we knew the statement at that the conversion occurs,
+ we could pass it to can_count_iv_in_wider_type and get a better
+ result. */
+ step = can_count_iv_in_wider_type (loop, type, base, step, NULL_TREE);
+ if (!step)
+ return fold_convert (type, chrec);
+
+ base = chrec_convert (type, base);
+
+ return build_polynomial_chrec (CHREC_VARIABLE (chrec), base, step);
}
/* Returns the type of the chrec. */
Index: tree-chrec.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-chrec.h,v
retrieving revision 2.8
diff -c -3 -p -r2.8 tree-chrec.h
*** tree-chrec.h 28 Apr 2005 05:38:34 -0000 2.8
--- tree-chrec.h 29 Apr 2005 19:31:51 -0000
*************** extern tree chrec_fold_plus (tree, tree,
*** 68,74 ****
extern tree chrec_fold_minus (tree, tree, tree);
extern tree chrec_fold_multiply (tree, tree, tree);
extern tree chrec_convert (tree, tree);
- extern tree count_ev_in_wider_type (tree, tree);
extern tree chrec_type (tree);
/* Operations. */
--- 68,73 ----
Index: tree-scalar-evolution.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-scalar-evolution.c,v
retrieving revision 2.21
diff -c -3 -p -r2.21 tree-scalar-evolution.c
*** tree-scalar-evolution.c 21 Apr 2005 08:48:53 -0000 2.21
--- tree-scalar-evolution.c 29 Apr 2005 19:31:52 -0000
*************** find_var_scev_info (tree var)
*** 350,382 ****
return &res->chrec;
}
- /* Tries to express CHREC in wider type TYPE. */
-
- tree
- count_ev_in_wider_type (tree type, tree chrec)
- {
- tree base, step;
- struct loop *loop;
-
- if (!evolution_function_is_affine_p (chrec))
- return fold_convert (type, chrec);
-
- base = CHREC_LEFT (chrec);
- step = CHREC_RIGHT (chrec);
- loop = current_loops->parray[CHREC_VARIABLE (chrec)];
-
- /* TODO -- if we knew the statement at that the conversion occurs,
- we could pass it to can_count_iv_in_wider_type and get a better
- result. */
- step = can_count_iv_in_wider_type (loop, type, base, step, NULL_TREE);
- if (!step)
- return fold_convert (type, chrec);
- base = chrec_convert (type, base);
-
- return build_polynomial_chrec (CHREC_VARIABLE (chrec),
- base, step);
- }
-
/* Return true when CHREC contains symbolic names defined in
LOOP_NB. */
--- 350,355 ----
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21029