diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/convert.c | 46 | ||||
-rw-r--r-- | gcc/tree.c | 46 |
3 files changed, 51 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c71f8efb095..2a059a381f1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2012-03-07 Richard Guenther <rguenther@suse.de> + + * convert.c (strip_float_extensions): Move ... + * tree.c (strip_float_extensions): ... here. + 2012-03-07 Georg-Johann Lay <avr@gjlay.de> PR target/52484 diff --git a/gcc/convert.c b/gcc/convert.c index dbe2c7eb32e..dc9b7f29ea4 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -90,52 +90,6 @@ convert_to_pointer (tree type, tree expr) } } -/* 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. diff --git a/gcc/tree.c b/gcc/tree.c index 3b8f6785a12..c5d10f99bdc 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -11213,6 +11213,52 @@ tree_strip_sign_nop_conversions (tree exp) 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. */ |