convert.c (strip_float_extensions): Look for narrowest type handling FP constants.
authorJan Hubicka <jh@suse.cz>
Tue, 14 Jan 2003 13:03:47 +0000 (14:03 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 14 Jan 2003 13:03:47 +0000 (13:03 +0000)
* 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.

From-SVN: r61279

gcc/ChangeLog
gcc/Makefile.in
gcc/convert.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/i386-fpcvt-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/i386-fpcvt-2.c [new file with mode: 0644]
gcc/tree.h

index 83bdae6..86ce412 100644 (file)
@@ -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.
index 8039bac..98ee7c1 100644 (file)
@@ -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
index 1ed70b5..26fb676 100644 (file)
@@ -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;
 
index 3847fc0..726e845 100644 (file)
@@ -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)
index 2ea83b8..b1608da 100644 (file)
@@ -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 (file)
index 0000000..716073e
--- /dev/null
@@ -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 (file)
index 0000000..12d149b
--- /dev/null
@@ -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;
+}
index d8bc1a8..269d05e 100644 (file)
@@ -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));