This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/68021] [6 Regression] ice in rewrite_use_nonlinear_expr with -O3
- From: "jakub at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 04 Feb 2016 17:51:46 +0000
- Subject: [Bug tree-optimization/68021] [6 Regression] ice in rewrite_use_nonlinear_expr with -O3
- Auto-submitted: auto-generated
- References: <bug-68021-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68021
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |amker at gcc dot gnu.org
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Seems the problem is that we have use->iv->step
(_2 - (sizetype) ((unsigned int) p3_11(D) + 4294967295)) +
18446744073709551615;
and cand->iv->step
(_2 - (sizetype) ((unsigned int) p3_11(D) + 4294967295)) - 1;
Both are really equivalent, but when constant_multiple_of is called on these,
it calls operand_equal_p and that will return they are not equal and thus not
multiple of each other.
This boils down to the canonicalization we do on MINUS_EXPR:
/* A - B -> A + (-B) if B is easily negatable. */
if (negate_expr_p (op1)
&& ! TYPE_OVERFLOW_SANITIZED (type)
&& ((FLOAT_TYPE_P (type)
/* Avoid this transformation if B is a positive REAL_CST. */
&& (TREE_CODE (op1) != REAL_CST
|| REAL_VALUE_NEGATIVE (TREE_REAL_CST (op1))))
|| INTEGRAL_TYPE_P (type)))
return fold_build2_loc (loc, PLUS_EXPR, type,
fold_convert_loc (loc, type, arg0),
negate_expr (op1));
but don't really do it in associate_trees.
The caller of associate_trees has worrying comments on that though:
/* Preserve the MINUS_EXPR if the negative part of the literal is
greater than the positive part. Otherwise, the multiplicative
folding code (i.e extract_muldiv) may be fooled in case
unsigned constants are subtracted, like in the following
example: ((X*2 + 4) - 8U)/2. */
which is pretty much the case here, - 1 constant is smaller than + (-1UL).
So, are we ok that this isn't really canonicalized always the same?
Shall operand_equal_p be treating those two cases as equal (perhaps under some
flag)? Or shall constant_multiple_of be using some different comparison?
Or shall something much earlier in the IVOPTS code just give up if the steps
aren't really equal/multiples of each other?