Prototyped in tree.h, called from the middle-end but implemented in convert.c. That looks wrong.
Now, convert.c is used from all frontends to implement convert () (that looks backwards - the language convert should be a langhook, called from convert implemented in convert.c). But well, I aint not touching this beast ;) At least with this patch convert.c functions are all convert_to_*, only called directly by frontends (while they should be all static to convert.c, called from convert () only(?)). Queued for bootstrap / regtest. Richard. 2012-03-07 Richard Guenther <rguent...@suse.de> * convert.c (strip_float_extensions): Move ... * tree.c (strip_float_extensions): ... here. Index: gcc/convert.c =================================================================== *** gcc/convert.c (revision 185029) --- gcc/convert.c (working copy) *************** convert_to_pointer (tree type, tree expr *** 90,141 **** } } - /* Avoid any floating point extensions from EXP. */ - tree - strip_float_extensions (tree exp) - { - tree sub, expt, subt; - - /* For floating point constant look up the narrowest type that can hold - it properly and handle it like (type)(narrowest_type)constant. - This way we can optimize for instance a=a*2.0 where "a" is float - but 2.0 is double constant. */ - if (TREE_CODE (exp) == REAL_CST && !DECIMAL_FLOAT_TYPE_P (TREE_TYPE (exp))) - { - REAL_VALUE_TYPE orig; - tree type = NULL; - - orig = TREE_REAL_CST (exp); - if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node) - && exact_real_truncate (TYPE_MODE (float_type_node), &orig)) - type = float_type_node; - else if (TYPE_PRECISION (TREE_TYPE (exp)) - > TYPE_PRECISION (double_type_node) - && exact_real_truncate (TYPE_MODE (double_type_node), &orig)) - type = double_type_node; - if (type) - return build_real (type, real_value_truncate (TYPE_MODE (type), orig)); - } - - if (!CONVERT_EXPR_P (exp)) - return exp; - - sub = TREE_OPERAND (exp, 0); - subt = TREE_TYPE (sub); - expt = TREE_TYPE (exp); - - if (!FLOAT_TYPE_P (subt)) - return exp; - - if (DECIMAL_FLOAT_TYPE_P (expt) != DECIMAL_FLOAT_TYPE_P (subt)) - return exp; - - if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt)) - return exp; - - return strip_float_extensions (sub); - } - /* Convert EXPR to some floating-point type TYPE. --- 90,95 ---- Index: gcc/tree.c =================================================================== *** gcc/tree.c (revision 185029) --- gcc/tree.c (working copy) *************** tree_strip_sign_nop_conversions (tree ex *** 11213,11218 **** --- 11209,11260 ---- return exp; } + /* Avoid any floating point extensions from EXP. */ + tree + strip_float_extensions (tree exp) + { + tree sub, expt, subt; + + /* For floating point constant look up the narrowest type that can hold + it properly and handle it like (type)(narrowest_type)constant. + This way we can optimize for instance a=a*2.0 where "a" is float + but 2.0 is double constant. */ + if (TREE_CODE (exp) == REAL_CST && !DECIMAL_FLOAT_TYPE_P (TREE_TYPE (exp))) + { + REAL_VALUE_TYPE orig; + tree type = NULL; + + orig = TREE_REAL_CST (exp); + if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node) + && exact_real_truncate (TYPE_MODE (float_type_node), &orig)) + type = float_type_node; + else if (TYPE_PRECISION (TREE_TYPE (exp)) + > TYPE_PRECISION (double_type_node) + && exact_real_truncate (TYPE_MODE (double_type_node), &orig)) + type = double_type_node; + if (type) + return build_real (type, real_value_truncate (TYPE_MODE (type), orig)); + } + + if (!CONVERT_EXPR_P (exp)) + return exp; + + sub = TREE_OPERAND (exp, 0); + subt = TREE_TYPE (sub); + expt = TREE_TYPE (exp); + + if (!FLOAT_TYPE_P (subt)) + return exp; + + if (DECIMAL_FLOAT_TYPE_P (expt) != DECIMAL_FLOAT_TYPE_P (subt)) + return exp; + + if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt)) + return exp; + + return strip_float_extensions (sub); + } + /* Strip out all handled components that produce invariant offsets. */