[This is an old discussion about useless integral conversions introduced
behind the back of the front-end by the routines in convert.c]
> I don't like re-introducing that inconsistency.
OK.
> Maybe instead make convert.c do if (!TYPE_UNSIGNED) unsigned_type_for ()
> instead? I notice that all callers of [un]signed_type_for are in
> "premature" optimizations convert.c performs (that better should be done
> in fold-const.c).
Yes, that works for me too, patch attached, it makes sure convert_to_integer
only fiddles with the type when strictly necessary. Tested on x86-64/Linux.
2014-10-02 Eric Botcazou <ebotca...@adacore.com>
* convert.c (convert_to_integer): Do not introduce useless conversions
between integral types.
--
Eric Botcazou
Index: convert.c
===================================================================
--- convert.c (revision 215656)
+++ convert.c (working copy)
@@ -746,8 +746,9 @@ convert_to_integer (tree type, tree expr
/* Can't do arithmetic in enumeral types
so use an integer type that will hold the values. */
if (TREE_CODE (typex) == ENUMERAL_TYPE)
- typex = lang_hooks.types.type_for_size
- (TYPE_PRECISION (typex), TYPE_UNSIGNED (typex));
+ typex
+ = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
+ TYPE_UNSIGNED (typex));
/* But now perhaps TYPEX is as wide as INPREC.
In that case, do nothing special here.
@@ -788,9 +789,15 @@ convert_to_integer (tree type, tree expr
&& (ex_form == PLUS_EXPR
|| ex_form == MINUS_EXPR
|| ex_form == MULT_EXPR)))
- typex = unsigned_type_for (typex);
+ {
+ if (!TYPE_UNSIGNED (typex))
+ typex = unsigned_type_for (typex);
+ }
else
- typex = signed_type_for (typex);
+ {
+ if (TYPE_UNSIGNED (typex))
+ typex = signed_type_for (typex);
+ }
return convert (type,
fold_build2 (ex_form, typex,
convert (typex, arg0),
@@ -805,7 +812,19 @@ convert_to_integer (tree type, tree expr
/* This is not correct for ABS_EXPR,
since we must test the sign before truncation. */
{
- tree typex = unsigned_type_for (type);
+ /* Do the arithmetic in type TYPEX,
+ then convert result to TYPE. */
+ tree typex = type;
+
+ /* Can't do arithmetic in enumeral types
+ so use an integer type that will hold the values. */
+ if (TREE_CODE (typex) == ENUMERAL_TYPE)
+ typex
+ = lang_hooks.types.type_for_size (TYPE_PRECISION (typex),
+ TYPE_UNSIGNED (typex));
+
+ if (!TYPE_UNSIGNED (typex))
+ typex = unsigned_type_for (typex);
return convert (type,
fold_build1 (ex_form, typex,
convert (typex,