csets___elabb gets miscompiled in stage2, such that stage3 enters and endless loop compiling ada.ads. Unfortunately, vrp seldom kicks in, so it's a bit difficult to duplicate the problem. Perhaps it would make sense to add a command-line option to force vrp on, and add that to torture, just to see how it goes?
Subject: Re: New: vrp miscompiles Ada front-end, drops loop exit test in well-defined wrap-around circumstances On Thu, Apr 14, 2005 at 08:16:09PM -0000, aoliva at gcc dot gnu dot org wrote: > Unfortunately, vrp seldom kicks in, so it's a bit difficult to > duplicate the problem. > Hmm? VRP is automatically enabled at -O2 and higher. Diego.
Created attachment 8632 [details] C testcase that triggers the bug The problem is that (from the vrp dump): Simulating statement (from ssa_edges): jD.1487_6 = (intD.0) iD.1486_1; Visiting statement: jD.1487_6 = (intD.0) iD.1486_1; (analyze_scalar_evolution (loop_nb = 1) (scalar = j_6) (get_scalar_evolution (scalar = j_6) (scalar_evolution = {123, +, 1}_1)) (set_scalar_evolution (scalar = j_6) (scalar_evolution = {123, +, 1}_1)) ) Found new range [123, 2147483647] for j_6 [...] Visiting statement: if (jD.1487_6 < 0) goto <L2>; else goto <L1>; Visiting conditional with predicate: j_6 < 0 With known ranges j_6: [123, 2147483647] Predicate evaluates to: 0
The other thing is that signed integer wrapping is defined if we add -fwrapv which means we now miss compile some java programs too. Confirmed.
(In reply to comment #3) > The other thing is that signed integer wrapping is defined if we add -fwrapv which means we now miss > compile some java programs too. Actually I tried basically the same program with the casts removed and it worked, it has to do with the casts.
> Hmm? VRP is automatically enabled at -O2 and higher. But it doesn't run unless we find some ASSERT_EXPR, and if all we have is a simple loop, no such ASSERT_EXPR is introduced.
Subject: [PR tree-optimization/21029, RFC] harmful chrec type conversions I started out by handling the specific case that the Ada front-end triggers, reduced to function f() in the attached testcase. Later on, as I understood the failure more, I figured I'd exercise some other cases, and painted myself into a corner in which each combination of widening-or-narrowing signedness-changing-or-not conversion that chrec_convert() might be asked to handle would be harmed by simply converting CHREC_LEFT and CHREC_RIGHT to the requested type, and the strategy we already used for widening conversions gave us correct results. Are there good reasons to try to perform the conversions in place and try to work around the loss of information elsewhere, or is this approach reasonable? 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. Meanwhile, I'm bootstrapping this on amd64-linux-gnu. Comments? 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. Index: gcc/tree-chrec.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-chrec.c,v retrieving revision 2.14 diff -u -p -r2.14 tree-chrec.c --- gcc/tree-chrec.c 5 Apr 2005 07:06:23 -0000 2.14 +++ gcc/tree-chrec.c 15 Apr 2005 05:40:27 -0000 @@ -1033,7 +1033,16 @@ chrec_convert (tree type, if (ct == type) return chrec; - if (TYPE_PRECISION (ct) < TYPE_PRECISION (type)) + if (1 /* Even truncations need to carry information about + well-defined overflows in narrowing conversions that might + have invoked undefined behavior should the operations be + performed directly in the narrow type. */ + || TYPE_PRECISION (ct) < TYPE_PRECISION (type) + /* Sign changes may involve well-defined overflows; avoid + silently dropping the signedness change. + ??? Should we limit ourselves to same-precision types here? */ + || (INTEGRAL_TYPE_P (ct) && INTEGRAL_TYPE_P (type) + && TYPE_UNSIGNED (ct) != TYPE_UNSIGNED (type))) return count_ev_in_wider_type (type, chrec); switch (TREE_CODE (chrec)) Index: gcc/testsuite/ChangeLog from Alexandre Oliva <aoliva@redhat.com> PR tree-optimization/21029 * gcc.dg/tree-ssa/pr21029.c: New. Index: gcc/testsuite/gcc.dg/tree-ssa/pr21029.c =================================================================== RCS file: gcc/testsuite/gcc.dg/tree-ssa/pr21029.c diff -N gcc/testsuite/gcc.dg/tree-ssa/pr21029.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gcc/testsuite/gcc.dg/tree-ssa/pr21029.c 15 Apr 2005 05:40:41 -0000 @@ -0,0 +1,176 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +/* PR tree-optimization/21029 + + f() used to get optimized to an infinite loop by tree-vrp, because + j is assumed to be non-negative. Even though the conversion from + unsigned to signed has unspecified results if the expression value + is not representable in the signed type, the compiler itself (e.g., + the Ada front end) depends on wrap-around behavior. */ + +unsigned int g(void) { + return (unsigned int)g; +} + +unsigned int f(void) { + unsigned int k = g (); + + unsigned char i = 123; + signed char j; + + do + if ((j = (signed char) i) < 0) + break; + else + i++; + while (1); + + /* This is here just so that the compiler introduces ASSERT_EXPR so + as to run the vrp pass. Yuck. */ + if (i <= k) + k = i - 2; + else + k = k + 3; + + return k; +} + +/* Now let's torture it a bit further. Narrowing conversions need + similar treatment. */ + +unsigned int f1 (void) { + unsigned int k = g (); + + unsigned short i = 123; + signed char j; + + do + if ((j = (signed char) i) < 0) + break; + else + i++; + while (1); + + /* This is here just so that the compiler introduces ASSERT_EXPR so + as to run the vrp pass. Yuck. */ + if (i <= k) + k = i - 2; + else + k = k + 3; + + return k; +} + +/* And so do widening conversions. */ + +unsigned int f2 (void) { + unsigned int k = g (); + + unsigned char i = 123; + signed short j; + + do + if ((j = (signed short) (signed char) i) < 0) + break; + else + i++; + while (1); + + /* This is here just so that the compiler introduces ASSERT_EXPR so + as to run the vrp pass. Yuck. */ + if (i <= k) + k = i - 2; + else + k = k + 3; + + return k; +} + +/* Check same-sign truncations with an increment that turns into + decrements. */ + +unsigned int f3 (void) { + unsigned int k = g (); + + signed short i = 5; + signed char j; + + do + if ((j = (signed char) i) < 0) + break; + else + i += 255; + while (1); + + /* This is here just so that the compiler introduces ASSERT_EXPR so + as to run the vrp pass. Yuck. */ + if (i <= k) + k = i - 2; + else + k = k + 3; + + return k; +} + +/* Check that the truncation above doesn't confuse the result of the + test after a widening conversion. */ + +unsigned int f4 (void) { + unsigned int k = g (); + + signed short i = -123; + signed int j; + + do + if ((j = (signed int) (signed char) i) > 0) + break; + else + i += 255; + while (1); + + /* This is here just so that the compiler introduces ASSERT_EXPR so + as to run the vrp pass. Yuck. */ + if (i <= k) + k = i - 2; + else + k = k + 3; + + return k; +} + +/* Even if we omit the widening truncation, the narrowing truncation + is implementation-defined. */ + +unsigned int f5 (void) { + unsigned int k = g (); + + signed long i = -123; + signed char j; + + do + if ((j = (signed char) i) > 0) + break; + else + i += 255; + while (1); + + /* This is here just so that the compiler introduces ASSERT_EXPR so + as to run the vrp pass. Yuck. */ + if (i <= k) + k = i - 2; + else + k = k + 3; + + return k; +} + +int main (void) { + f (); + f1 (); + f2 (); + f3 (); + f4 (); + f5 (); + return 0; +} -- Alexandre Oliva http://www.ic.unicamp.br/~oliva/ Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org} Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}
Then, shouldn't your patch check -fwrapv somehow? And if Ada relies on wrap around, does it enable -fwrapv?
(In reply to comment #7) > Then, shouldn't your patch check -fwrapv somehow? And if Ada relies on wrap > around, does it enable -fwrapv? Huh, the testcase is still defined C even though signed overflow is undefined since it is overflowing while in unsigned.
With your patch I'm able to bootstrap but I get a few ACATS FAIL: FAIL: c41203a FAIL: c41203b FAIL: c52102b FAIL: c52102d FAIL: c52103x FAIL: c62002a FAIL: cdd2a02 FAIL: cxa5012 FAIL: cxg2009 FAIL: cxh1001 The first 8 are wrong code, cxa5012 will be fixed by my patch soon and the two last are ICEs, here is cxg2009: /home/guerby/work/gcc/build/build-20050415T203732/gcc/xgcc -c -B/home/guerby/work/gcc/build/build-20050415T203732/gcc/ -gnatws -O2 -I/home/guerby/work/gcc/build/build-20050415T203732/gcc/testsuite/ada/acats/support cxg2009.adb +===========================GNAT BUG DETECTED==============================+ | 4.1.0 20050415 (experimental) (x86_64-unknown-linux-gnu) GCC error: | | in set_value_range, at tree-vrp.c:124 | | Error detected at cxg2009.adb:421:5 |
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2005-04/msg01691.html>.
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 ----
Subject: Re: [PR tree-optimization/21029, RFC] harmful chrec type conversions Hello, > 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? no. There is one major bug -- > ! 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))); > ! this is completely bogus -- you will always convert the POLYNOMIAL_CHREC with nonconstant step, regardless of the correctness. There are also a few minor changes that would be recommendable for the final patch: 1) The can_count_ev_in_wider_type should be renamed to more appropriate name, given that it is now used even for shortening the value. 2) This function should be extended to really handle such conversions efficiently. I.e. to always allow shortening to unsigned types, and to always allow shortening to arbitrary types with -fwrapv. Also, I am not quite sure at the moment that the current code of can_count_ev_in_wider_type really works if the required conversion is not extending, this should be checked. Zdenek > > 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 ----
Sebastian, would you mind taking a look at this? It's assigned to me but it's likely that you will be able to figure out what's going on in chrec more quickly. And I won't have time to look at this for a few more days. Thanks. Diego.
*** Bug 21773 has been marked as a duplicate of this bug. ***
Subject: Bug 21029 CVSROOT: /cvs/gcc Module name: gcc Changes by: dnovillo@gcc.gnu.org 2005-06-02 02:57:15 Modified files: gcc : ChangeLog fold-const.c tree-flow.h tree-ssa-ccp.c tree-ssa-copy.c tree-ssa-propagate.c tree-ssa-propagate.h tree-vrp.c tree.h gcc/testsuite : ChangeLog gcc/testsuite/gcc.dg/tree-ssa: pr14841.c pr21658.c Added files: gcc/testsuite/gcc.dg/tree-ssa: pr14341.c pr20701.c pr21029.c pr21086.c pr21090.c pr21332.c pr21458.c vrp01.c vrp02.c vrp03.c vrp04.c vrp05.c vrp06.c vrp07.c vrp08.c vrp09.c vrp10.c vrp11.c vrp12.c vrp13.c Log message: 2005-06-01 Diego Novillo <dnovillo@redhat.com> PR 14341, PR 21332, PR 20701, PR 21029, PR 21086, PR 21090 PR 21289, PR 21348, PR 21367, PR 21368, PR 21458. * fold-const.c (invert_tree_comparison): Make extern. * tree-flow.h (enum value_range_type): Move to tree-ssa-propagate. (struct value_range_def): Limewise. (get_value_range): Remove. (dump_value_range): Remove. (dump_all_value_ranges): Remove. (debug_all_value_ranges): Remove. (vrp_evaluate_conditional): Declare. * tree-ssa-propagate.c (struct prop_stats_d): Add field num_pred_folded. (substitute_and_fold): Add argument use_ranges_p. Update all callers. If use_ranges_p is true, call fold_predicate_in to fold predicates using range information. Ignore ASSERT_EXPRs. Change debugging output to only show statements that have been folded. (replace_phi_args_in): Move debugging output code from substitute and fold. (fold_predicate_in): New local function. * tree-ssa-propagate.h (enum value_range_type): Move from tree-flow.h. (struct value_range_d): Likewise. Add field 'equiv'. (value_range_t): Rename from value_range. * tree-vrp.c (found_in_subgraph): Rename from found. (get_opposite_operand): Remove. (struct assert_locus_d): Declare. (assert_locus_t): Declare. (need_assert_for): Declare. (asserts_for): Declare. (blocks_visited): Declare. (vr_value): Declare. (set_value_range): Add argument 'equiv'. Don't drop to VARYING ranges that cover all values in the type. Make deep copy of equivalence set 'equiv'. (copy_value_range): New local function. (set_value_range_to_undefined): New local function. (compare_values): Return -2 if either value has overflowed. (range_includes_zero_p): New local function. (extract_range_from_assert): Flip the predicate code if the name being asserted is on the RHS of the predicate. Avoid creating unnecessary symbolic ranges if the comparison includes another name with a known numeric range. Update the equivalnce set of the new range when asserting EQ_EXPR predicates. (extract_range_from_ssa_name): Update the equivalence set of the new range with VAR. (extract_range_from_binary_expr): Also handle TRUTH_*_EXPR. If -fwrapv is used, set the resulting range to VARYING if the operation overflows. Otherwise, use TYPE_MIN_VALUE and TYPE_MAX_VALUE to represent -INF and +INF. Fix handling of *_DIV_EXPR. (extract_range_from_unary_expr): Handle MINUS_EXPR and ABS_EXPR properly by switching the range around if necessary. (extract_range_from_comparison): New local function. (extract_range_from_expr): Call it. (adjust_range_with_scev): Do not adjust the range if using wrapping arithmetic (-fwrapv). (dump_value_range): Also show equivalence set. Show -INF and +INF for TYPE_MIN_VALUE and TYPE_MAX_VALUE. (build_assert_expr_for): Also build ASSERT_EXPR for EQ_EXPR. (infer_value_range): Change return value to bool. Add arguments 'comp_code_p' and 'val_p'. Do not attempt to infer ranges from statements that may throw. Store the comparison code in comp_code_p. Store the other operand to be used in the predicate in val_p. (dump_asserts_for): New. (debug_asserts_for): New. (dump_all_asserts): New. (debug_all_asserts): New. (register_new_assert_for): New. (register_edge_assert_for): New. (find_conditional_asserts): New. (find_assert_locations): New. (process_assert_insertions_for): New. (process_assert_insertions): New. (insert_range_assertions): Initialize found_in_subgraph, blocks_visited, need_assert_for and asserts_for. Call find_assert_locations and process_assert_insertions. (remove_range_assertions): Add more documentation. (vrp_initialize): Change return type to void. Do not try to guess if running VRP is worth it. (compare_name_with_value): New. (compare_names): New. (vrp_evaluate_conditional): Add argument 'use_equiv_p'. If use_equiv_p is true, call compare_names and compare_name_with_value to compare all the ranges for every name in the equivalence set of the predicate operands. Update all callers. (vrp_meet): Try harder not to derive a VARYING range. If two values meet, the resulting equivalence set is the intersection of the two equivalence sets. (vrp_visit_phi_node): Call copy_value_range to get the current range information of the LHS. (vrp_finalize): Create a value vector representing all the names that ended up with exactly one value in their range. Call substitute_and_fold. (execute_vrp): Document equivalence sets in ranges. * tree.h (SSA_NAME_VALUE_RANGE): Remove. (struct tree_ssa_name): Remove field value_range. (invert_tree_comparison): Declare. testsuite/ChangeLog 2005-06-01 Diego Novillo <dnovillo@redhat.com> PR 14341, PR 21332, PR 20701, PR 21086, PR 21090 PR 21289, PR 21348, PR 21367, PR 21368, PR 21458. * gcc.dg/tree-ssa/pr14341.c: New test. * gcc.dg/tree-ssa/pr14841.c: New test. * gcc.dg/tree-ssa/pr20701.c: New test. * gcc.dg/tree-ssa/pr21086.c: New test. * gcc.dg/tree-ssa/pr21090.c: New test. * gcc.dg/tree-ssa/pr21332.c: New test. * gcc.dg/tree-ssa/pr21458.c: New test. * gcc.dg/tree-ssa/pr21658.c: New test. * gcc.dg/tree-ssa/vrp01.c: New test. * gcc.dg/tree-ssa/vrp02.c: New test. * gcc.dg/tree-ssa/vrp03.c: New test. * gcc.dg/tree-ssa/vrp04.c: New test. * gcc.dg/tree-ssa/vrp05.c: New test. * gcc.dg/tree-ssa/vrp06.c: New test. * gcc.dg/tree-ssa/vrp07.c: New test. * gcc.dg/tree-ssa/vrp08.c: New test. * gcc.dg/tree-ssa/vrp09.c: New test. * gcc.dg/tree-ssa/vrp10.c: New test. * gcc.dg/tree-ssa/vrp11.c: New test. * gcc.dg/tree-ssa/vrp12.c: New test. * gcc.dg/tree-ssa/vrp13.c: New test. 2005-06-01 Alexandre Oliva <aoliva@redhat.com> PR 21029 * gcc.dg/tree-ssa/pr21029.c: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.8989&r2=2.8990 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fold-const.c.diff?cvsroot=gcc&r1=1.589&r2=1.590 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-flow.h.diff?cvsroot=gcc&r1=2.114&r2=2.115 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa-ccp.c.diff?cvsroot=gcc&r1=2.77&r2=2.78 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa-copy.c.diff?cvsroot=gcc&r1=2.32&r2=2.33 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa-propagate.c.diff?cvsroot=gcc&r1=2.22&r2=2.23 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa-propagate.h.diff?cvsroot=gcc&r1=2.3&r2=2.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-vrp.c.diff?cvsroot=gcc&r1=2.18&r2=2.19 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree.h.diff?cvsroot=gcc&r1=1.732&r2=1.733 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5574&r2=1.5575 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr14341.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr21029.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr21086.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr21090.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr21332.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr21458.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp01.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp02.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp03.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp04.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp05.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp06.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp08.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp10.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp11.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp12.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/vrp13.c.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr14841.c.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr21658.c.diff?cvsroot=gcc&r1=1.1&r2=1.2
Fixed. http://gcc.gnu.org/ml/gcc-patches/2005-06/msg00127.html
Not. http://gcc.gnu.org/ml/gcc-patches/2005-06/msg00128.html
(In reply to comment #17) > Not. http://gcc.gnu.org/ml/gcc-patches/2005-06/msg00128.html Open a new PR. This is a completely different and not related to VRP. Closing.
This is still not fixed.
(In reply to comment #19) > This is still not fixed. But this time it is not VRP which is causing the problem but the Ada front-end, I will file a new bug.