diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/convert.c | 26 | ||||
-rw-r--r-- | gcc/fold-const.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/i386-fpcvt-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/i386-fpcvt-2.c | 8 | ||||
-rw-r--r-- | gcc/tree.h | 3 |
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)); |