Commit 7e139075 by Richard Kenner

(fold, case CONVERT_EXPR): Don't remove an integer conversion when outer is FP…

(fold, case CONVERT_EXPR): Don't remove an integer conversion when outer is FP unless it doesn't change signedness...

(fold, case CONVERT_EXPR): Don't remove an integer conversion when
outer is FP unless it doesn't change signedness; rework code in this
area to be clearer.

From-SVN: r8724
parent c47decad
/* Fold a constant sub-tree into a single node for C-compiler /* Fold a constant sub-tree into a single node for C-compiler
Copyright (C) 1987, 1988, 1992, 1993, 1994 Free Software Foundation, Inc. Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -3358,59 +3358,69 @@ fold (expr) ...@@ -3358,59 +3358,69 @@ fold (expr)
if (TREE_TYPE (TREE_OPERAND (t, 0)) == TREE_TYPE (t)) if (TREE_TYPE (TREE_OPERAND (t, 0)) == TREE_TYPE (t))
return TREE_OPERAND (t, 0); return TREE_OPERAND (t, 0);
/* Handle cases of two conversions in a row. */
if (TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
|| TREE_CODE (TREE_OPERAND (t, 0)) == CONVERT_EXPR)
{
tree inside_type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
tree inter_type = TREE_TYPE (TREE_OPERAND (t, 0));
tree final_type = TREE_TYPE (t);
int inside_int = INTEGRAL_TYPE_P (inside_type);
int inside_ptr = TREE_CODE (inside_type) == POINTER_TYPE;
int inside_float = FLOAT_TYPE_P (inside_type);
int inside_prec = TYPE_PRECISION (inside_type);
int inside_unsignedp = TREE_UNSIGNED (inside_type);
int inter_int = INTEGRAL_TYPE_P (inter_type);
int inter_ptr = TREE_CODE (inter_type) == POINTER_TYPE;
int inter_float = FLOAT_TYPE_P (inter_type);
int inter_prec = TYPE_PRECISION (inter_type);
int inter_unsignedp = TREE_UNSIGNED (inter_type);
int final_int = INTEGRAL_TYPE_P (final_type);
int final_ptr = TREE_CODE (final_type) == POINTER_TYPE;
int final_float = FLOAT_TYPE_P (final_type);
int final_prec = TYPE_PRECISION (final_type);
int final_unsignedp = TREE_UNSIGNED (final_type);
/* In addition to the cases of two conversions in a row /* In addition to the cases of two conversions in a row
handled below, if we are converting something to its own handled below, if we are converting something to its own
type via an object of identical or wider precision, neither type via an object of identical or wider precision, neither
conversion is needed. */ conversion is needed. */
if ((TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR if (inside_type == final_type
|| TREE_CODE (TREE_OPERAND (t, 0)) == CONVERT_EXPR) && ((inter_int && final_int) || (inter_float && final_float))
&& TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)) == TREE_TYPE (t) && inter_prec >= final_prec)
&& ((INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))
&& INTEGRAL_TYPE_P (TREE_TYPE (t)))
|| (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))
&& FLOAT_TYPE_P (TREE_TYPE (t))))
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0)))
>= TYPE_PRECISION (TREE_TYPE (t))))
return TREE_OPERAND (TREE_OPERAND (t, 0), 0); return TREE_OPERAND (TREE_OPERAND (t, 0), 0);
/* Likewise, if the intermediate and final types are either both
float or both integer, we don't need the middle conversion if
it is wider than the final type and doesn't change the signedness
(for integers). */
if ((((inter_int || inter_ptr) && (inside_int || inside_ptr))
|| (inter_float && inside_float))
&& inter_prec >= inside_prec
&& (inter_float || inter_unsignedp == inside_unsignedp))
return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
/* Two conversions in a row are not needed unless: /* Two conversions in a row are not needed unless:
- the intermediate type is narrower than both initial and final, or - some conversion is floating-point (overstrict for now), or
- the intermediate type is narrower than both initial and
final, or
- the intermediate type and innermost type differ in signedness, - the intermediate type and innermost type differ in signedness,
and the outermost type is wider than the intermediate, or and the outermost type is wider than the intermediate, or
- the initial type is a pointer type and the precisions of the - the initial type is a pointer type and the precisions of the
intermediate and final types differ, or intermediate and final types differ, or
- the final type is a pointer type and the precisions of the - the final type is a pointer type and the precisions of the
initial and intermediate types differ. */ initial and intermediate types differ. */
if ((TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR if (! inside_float && ! inter_float && ! final_float
|| TREE_CODE (TREE_OPERAND (t, 0)) == CONVERT_EXPR) && (inter_prec > inside_prec || inter_prec > final_prec)
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0))) && ! (inside_int && inter_int
> TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0))) && inter_unsignedp != inside_unsignedp
|| && inter_prec < final_prec)
TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0))) && ((inter_unsignedp && inter_prec > inside_prec)
> TYPE_PRECISION (TREE_TYPE (t))) == (final_unsignedp && final_prec > inter_prec))
&& ! ((TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0))) && ! (inside_ptr && inter_prec != final_prec)
== INTEGER_TYPE) && ! (final_ptr && inside_prec != inter_prec))
&& (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
== INTEGER_TYPE) }
&& (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (t, 0)))
!= TREE_UNSIGNED (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0)))
< TYPE_PRECISION (TREE_TYPE (t))))
&& ((TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (t, 0)))
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0)))
> TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))))
==
(TREE_UNSIGNED (TREE_TYPE (t))
&& (TYPE_PRECISION (TREE_TYPE (t))
> TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0))))))
&& ! ((TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
== POINTER_TYPE)
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0)))
!= TYPE_PRECISION (TREE_TYPE (t))))
&& ! (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
&& (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
!= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0))))))
return convert (TREE_TYPE (t), TREE_OPERAND (TREE_OPERAND (t, 0), 0));
if (TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR if (TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR
&& TREE_CONSTANT (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) && TREE_CONSTANT (TREE_OPERAND (TREE_OPERAND (t, 0), 1))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment