summaryrefslogtreecommitdiff
path: root/gcc/convert.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2003-01-14 13:03:47 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2003-01-14 13:03:47 +0000
commit8cce4b411c4918a7e75f06022353fafa5456a238 (patch)
treec3eb54b4346a9236a335d6192b4c3fb9db3e36ae /gcc/convert.c
parent12c2d9731e15f73431979fcf292e7d7652a49dc6 (diff)
downloadgcc-8cce4b411c4918a7e75f06022353fafa5456a238.tar.gz
* convert.c (strip_float_extensions): Look for narrowest type handling
FP constants. * fold-const.c (fold): Fold (double)float1 CMP (double)float2 into float1 CMP float2. * convert.c (strip_float_extensions): Make global. * tree.h (strip_float_extensions): Declare. * gcc.dg/i386-fpcvt-1.c: New test. * gcc.dg/i386-fpcvt-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@61279 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/convert.c')
-rw-r--r--gcc/convert.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/gcc/convert.c b/gcc/convert.c
index 1ed70b53091..26fb6766937 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -32,8 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "convert.h"
#include "toplev.h"
#include "langhooks.h"
-static tree strip_float_extensions PARAMS ((tree));
-
+#include "real.h"
/* Convert EXPR to some pointer or reference type TYPE.
EXPR must be pointer, reference, integer, enumeral, or literal zero;
@@ -75,12 +74,33 @@ convert_to_pointer (type, expr)
}
/* Avoid any floating point extensions from EXP. */
-static tree
+tree
strip_float_extensions (exp)
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)
+ {
+ 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 (TREE_CODE (exp) != NOP_EXPR)
return exp;