This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix optimization regression in constant folder
On 10/15/07, Richard Kenner <kenner@vlsi1.ultra.nyu.edu> wrote:
> > we know that sizetypes _definitely_ are a problem for the middle-end
> > because of their peculiar semantics.
>
> That may be, but those are the properties and semantics that they such
> objects DO have from a conceptual point of view and any other way we
> do it they would have the same semantics! (I'm not saying this very
> well, but what I'm trying to say is that those semantics are intrinsic
> to the type of calculations that need to be done.)
>
> One can argue that it's too hard to implement them properly, so we ought
> to do some subsetting. But if we do that, then we CERTAINLY should leave
> the flag the way it is so that if somebody later wants to do it properly,
> they at least have the data to do so.
Let's say it this way - every simplification to the middle-end helps avoiding
(and fixing) obscure bugs in fold-const. For an example, as exercise for the
reader try to fix PR33779 which we just produced by looking at the
conversion handling from extract_muldiv (which is one "heavy" user of
TYPE_IS_SIZETYPE). The condition above the transformation that goes
wrong is not exactly easy to understand (nor to fix without
essentially disabling
all of the transformation):
<quote>
case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR:
/* If op0 is an expression ... */
if ((COMPARISON_CLASS_P (op0)
|| UNARY_CLASS_P (op0)
|| BINARY_CLASS_P (op0)
|| VL_EXP_CLASS_P (op0)
|| EXPRESSION_CLASS_P (op0))
/* ... and is unsigned, and its type is smaller than ctype,
then we cannot pass through as widening. */
&& ((TYPE_UNSIGNED (TREE_TYPE (op0))
&& ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
&& (GET_MODE_SIZE (TYPE_MODE (ctype))
> GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
/* ... or this is a truncation (t is narrower than op0),
then we cannot pass through this narrowing. */
|| (GET_MODE_SIZE (TYPE_MODE (type))
< GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
/* ... or signedness changes for division or modulus,
then we cannot pass through this conversion. */
|| (code != MULT_EXPR
&& (TYPE_UNSIGNED (ctype)
!= TYPE_UNSIGNED (TREE_TYPE (op0))))))
break;
/* Pass the constant down and see if we can make a simplification. If
we can, replace this expression with the inner simplification for
possible later conversion to our or some other type. */
if ((t2 = fold_convert (TREE_TYPE (op0), c)) != 0
&& TREE_CODE (t2) == INTEGER_CST
&& !TREE_OVERFLOW (t2)
&& (0 != (t1 = extract_muldiv (op0, t2, code,
code == MULT_EXPR
? ctype : NULL_TREE,
strict_overflow_p))))
return t1;
break;
Richard.