summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/convert.c26
-rw-r--r--gcc/fold-const.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/i386-fpcvt-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/i386-fpcvt-2.c8
-rw-r--r--gcc/tree.h3
8 files changed, 70 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 83bdae65730..86ce412aced 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+Tue Jan 14 00:45:33 CET 2003 Jan Hubicka <jh@suse.cz>
+
+ * 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.
+
2003-01-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
* timevar.def: define TV_NAME_LOOKUP.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 8039bac7911..98ee7c18d51 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1215,7 +1215,7 @@ c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(
c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) flags.h toplev.h
c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- flags.h toplev.h $(C_COMMON_H)
+ flags.h toplev.h $(C_COMMON_H) real.h
c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
function.h c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H) gt-c-pragma.h
mbchar.o: mbchar.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) mbchar.h
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;
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 3847fc00041..726e84551f5 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -6041,6 +6041,18 @@ fold (expr)
if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
{
+ tree targ0 = strip_float_extensions (arg0);
+ tree targ1 = strip_float_extensions (arg1);
+ tree newtype = TREE_TYPE (targ0);
+
+ if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
+ newtype = TREE_TYPE (targ1);
+
+ /* Fold (double)float1 CMP (double)float2 into float1 CMP float2. */
+ if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
+ return fold (build (code, type, convert (newtype, targ0),
+ convert (newtype, targ1)));
+
/* (-a) CMP (-b) -> b CMP a */
if (TREE_CODE (arg0) == NEGATE_EXPR
&& TREE_CODE (arg1) == NEGATE_EXPR)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2ea83b8ca9d..b1608daa1f7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+Tue Jan 14 00:45:03 CET 2003 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/i386-fpcvt-1.c: New test.
+ * gcc.dg/i386-fpcvt-2.c: New test.
+
2003-01-14 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/i386-mmx-3.c: New test.
diff --git a/gcc/testsuite/gcc.dg/i386-fpcvt-1.c b/gcc/testsuite/gcc.dg/i386-fpcvt-1.c
new file mode 100644
index 00000000000..716073eeeb3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/i386-fpcvt-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -msse2 -march=athlon" } */
+/* { dg-final { scan-assembler-not "cvtss2sd" } } */
+float a,b;
+main()
+{
+ a=b*3.0;
+}
diff --git a/gcc/testsuite/gcc.dg/i386-fpcvt-2.c b/gcc/testsuite/gcc.dg/i386-fpcvt-2.c
new file mode 100644
index 00000000000..12d149b1399
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/i386-fpcvt-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -msse2 -march=athlon" } */
+/* { dg-final { scan-assembler-not "cvtss2sd" } } */
+float a,b;
+main()
+{
+ return a<0.0;
+}
diff --git a/gcc/tree.h b/gcc/tree.h
index d8bc1a8c72a..269d05e8305 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2929,6 +2929,9 @@ extern tree fold_builtin PARAMS ((tree));
extern enum built_in_function builtin_mathfn_code PARAMS ((tree));
extern tree build_function_call_expr PARAMS ((tree, tree));
+/* In convert.c */
+extern tree strip_float_extensions PARAMS ((tree));
+
/* In alias.c */
extern void record_component_aliases PARAMS ((tree));
extern HOST_WIDE_INT get_alias_set PARAMS ((tree));