This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PR tree-optimization/19903
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: Sebastian Pop <sebastian dot pop at cri dot ensmp dot fr>
- Cc: gcc-patches at gcc dot gnu dot org,Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>,dnovillo at redhat dot com
- Date: Mon, 4 Apr 2005 12:29:44 +0200
- Subject: Re: PR tree-optimization/19903
- References: <200503301407.30045.ebotcazou@libertysurf.fr> <20050330123322.GA7543@atrey.karlin.mff.cuni.cz> <20050330133208.GA8240@napoca.cri.ensmp.fr>
> It seems to me that failing in chrec_convert and returning a
> chrec_dont_know is the best solution.
Something like that (untested except on cxa4006.adb)?
* tree-chrec.c (chrec_convert): Return chrec_dont_know for constants
that don't fit in their type after conversion.
Wrong code is generated because number_of_iterations_cond computes a niter of
0 for the loop at stake:
<L1>:;
D.2370_191 = line_88 - 1;
if (D.2370_191 > 3) goto <L2>; else goto <L45>;
(set_scalar_evolution
(scalar = D.2370_191)
(scalar_evolution = {2, +, 4294967295}_1))
)
The problem comes from the overflow test:
/* Condition in shape a + s * i <= b
We must know that b + s does not overflow and a <= b + s and then we
can compute number of iterations as (b + s - a) / s. (It might
seem that we in fact could be more clever about testing the b + s
overflow condition using some information about b - a mod s,
but it was already taken into account during LE -> NE transform). */
{
if (mmax)
{
bound = fold_binary_to_constant (MINUS_EXPR, type, mmax, step0);
assumption = fold (build2 (LE_EXPR, boolean_type_node,
base1, bound));
assumptions = fold (build2 (TRUTH_AND_EXPR, boolean_type_node,
assumptions, assumption));
}
I think it implicitly assumes that step0 <= mmax but we have:
(gdb) p debug_tree(base0)
<integer_cst 0x2a9644c0c0 type <integer_type 0x2a959079c0
natural___XDLU_0__2147483647> constant invariant 2>
(gdb) p debug_tree(step0)
<integer_cst 0x2a959704b0 type <integer_type 0x2a959079c0
natural___XDLU_0__2147483647> constant invariant 4294967295>
(gdb) p debug_tree(base1)
<integer_cst 0x2a95e4a780 type <integer_type 0x2a959079c0
natural___XDLU_0__2147483647> constant invariant 3>
(gdb) p debug_tree(mmax)
<integer_cst 0x2a958909f0 type <integer_type 0x2a95896a90 integer> constant
invariant visited 2147483647>
So the crux of the matter appears to be the step of ivs, which is probably a
constant in most cases, so I think a check on constants may be good enough.
--
Eric Botcazou
Index: tree-chrec.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-chrec.c,v
retrieving revision 2.12.12.1
diff -u -p -r2.12.12.1 tree-chrec.c
--- tree-chrec.c 1 Mar 2005 16:27:48 -0000 2.12.12.1
+++ tree-chrec.c 4 Apr 2005 10:13:06 -0000
@@ -1037,6 +1037,20 @@ chrec_convert (tree type,
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 to 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)
+ {
+ if (!int_fits_type_p (res, type))
+ res = chrec_dont_know;
+ }
+
return res;
}
}