OSDN Git Service

Move LTO build option description to correct subheading.
[pf3gnuchains/gcc-fork.git] / gcc / convert.c
index 453f5ed..5c46766 100644 (file)
@@ -1,6 +1,6 @@
 /* Utility routines for data type conversion for GCC.
    Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1997, 1998,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -434,7 +434,7 @@ convert_to_integer (tree type, tree expr)
       tree s_intype = TREE_TYPE (s_expr);
       const enum built_in_function fcode = builtin_mathfn_code (s_expr);
       tree fn = 0;
-      
+
       switch (fcode)
         {
        CASE_FLT_FN (BUILT_IN_CEIL):
@@ -494,7 +494,7 @@ convert_to_integer (tree type, tree expr)
        default:
          break;
        }
-      
+
       if (fn)
         {
          tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
@@ -515,7 +515,7 @@ convert_to_integer (tree type, tree expr)
       tree s_intype = TREE_TYPE (s_expr);
       const enum built_in_function fcode = builtin_mathfn_code (s_expr);
       tree fn = 0;
-       
+
       switch (fcode)
        {
        CASE_FLT_FN (BUILT_IN_LOGB):
@@ -673,6 +673,31 @@ convert_to_integer (tree type, tree expr)
            }
          break;
 
+       case TRUNC_DIV_EXPR:
+         {
+           tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
+           tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
+
+           /* Don't distribute unless the output precision is at least as big
+              as the actual inputs and it has the same signedness.  */
+           if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
+               && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
+               /* If signedness of arg0 and arg1 don't match,
+                  we can't necessarily find a type to compare them in.  */
+               && (TYPE_UNSIGNED (TREE_TYPE (arg0))
+                   == TYPE_UNSIGNED (TREE_TYPE (arg1)))
+               /* Do not change the sign of the division.  */
+               && (TYPE_UNSIGNED (TREE_TYPE (expr))
+                   == TYPE_UNSIGNED (TREE_TYPE (arg0)))
+               /* Either require unsigned division or a division by
+                  a constant that is not -1.  */
+               && (TYPE_UNSIGNED (TREE_TYPE (arg0))
+                   || (TREE_CODE (arg1) == INTEGER_CST
+                       && !integer_all_onesp (arg1))))
+             goto trunc1;
+           break;
+         }
+
        case MAX_EXPR:
        case MIN_EXPR:
        case MULT_EXPR: