Add a build_real_truncate helper function
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 5 Oct 2015 13:37:15 +0000 (13:37 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 5 Oct 2015 13:37:15 +0000 (13:37 +0000)
...which simplifies the match.pd patterns I'm about to add.

Bootstrapped & regression-tested on x86_64-linux-gnu.

gcc/
* real.h (build_real_truncate): Declare.
* tree.c (build_real_truncate): New function.
(strip_float_extensions): Use it.
* builtins.c (fold_builtin_cabs, fold_builtin_sqrt, fold_builtin_cbrt)
(fold_builtin_hypot, fold_builtin_pow): Likewise.
* match.pd: Likewise.

From-SVN: r228483

gcc/ChangeLog
gcc/builtins.c
gcc/match.pd
gcc/real.h
gcc/tree.c

index bd7626f59981814420fed48e00623607b7b259a4..5c782900fd3e0a3d7bf0ec1ba942d450f35b1d8e 100644 (file)
@@ -1,3 +1,12 @@
+2015-10-05  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * real.h (build_real_truncate): Declare.
+       * tree.c (build_real_truncate): New function.
+       (strip_float_extensions): Use it.
+       * builtins.c (fold_builtin_cabs, fold_builtin_sqrt, fold_builtin_cbrt)
+       (fold_builtin_hypot, fold_builtin_pow): Likewise.
+       * match.pd: Likewise.
+
 2015-10-05 James Greenhalgh <james.greenhalgh@arm.com>
           Jiong Wang  <jiong.wang@arm.com>
 
index 9a81a182de48e5e9ec3f8ece4d25660390c09a26..89bea60a09df38f5872933168a7200e33f6efbe6 100644 (file)
@@ -7592,12 +7592,10 @@ fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
       if (flag_unsafe_math_optimizations
          && operand_equal_p (real, imag, OEP_PURE_SAME))
         {
-         const REAL_VALUE_TYPE sqrt2_trunc
-           = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
          STRIP_NOPS (real);
          return fold_build2_loc (loc, MULT_EXPR, type,
-                             fold_build1_loc (loc, ABS_EXPR, type, real),
-                             build_real (type, sqrt2_trunc));
+                                 fold_build1_loc (loc, ABS_EXPR, type, real),
+                                 build_real_truncate (type, dconst_sqrt2 ()));
        }
     }
 
@@ -7756,8 +7754,7 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
 
          /* Adjust for the outer root.  */
          SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
-         dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
-         tree_root = build_real (type, dconstroot);
+         tree_root = build_real_truncate (type, dconstroot);
          return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
        }
     }
@@ -7804,11 +7801,9 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
       if (BUILTIN_EXPONENT_P (fcode))
        {
          tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
-         const REAL_VALUE_TYPE third_trunc =
-           real_value_truncate (TYPE_MODE (type), dconst_third ());
          arg = fold_build2_loc (loc, MULT_EXPR, type,
-                            CALL_EXPR_ARG (arg, 0),
-                            build_real (type, third_trunc));
+                                CALL_EXPR_ARG (arg, 0),
+                                build_real_truncate (type, dconst_third ()));
          return build_call_expr_loc (loc, expfn, 1, arg);
        }
 
@@ -7824,8 +7819,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
              REAL_VALUE_TYPE dconstroot = dconst_third ();
 
              SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
-             dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
-             tree_root = build_real (type, dconstroot);
+             tree_root = build_real_truncate (type, dconstroot);
              return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
            }
        }
@@ -7845,8 +7839,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
 
                  real_arithmetic (&dconstroot, MULT_EXPR,
                                    dconst_third_ptr (), dconst_third_ptr ());
-                 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
-                 tree_root = build_real (type, dconstroot);
+                 tree_root = build_real_truncate (type, dconstroot);
                  return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
                }
            }
@@ -7862,10 +7855,8 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
          if (tree_expr_nonnegative_p (arg00))
            {
              tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
-             const REAL_VALUE_TYPE dconstroot
-               = real_value_truncate (TYPE_MODE (type), dconst_third ());
-             tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
-                                        build_real (type, dconstroot));
+             tree c = build_real_truncate (type, dconst_third ());
+             tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01, c);
              return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
            }
        }
@@ -8391,13 +8382,9 @@ fold_builtin_hypot (location_t loc, tree fndecl,
   /* hypot(x,x) -> fabs(x)*sqrt(2).  */
   if (flag_unsafe_math_optimizations
       && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
-    {
-      const REAL_VALUE_TYPE sqrt2_trunc
-       = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
-      return fold_build2_loc (loc, MULT_EXPR, type,
-                         fold_build1_loc (loc, ABS_EXPR, type, arg0),
-                         build_real (type, sqrt2_trunc));
-    }
+    return fold_build2_loc (loc, MULT_EXPR, type,
+                           fold_build1_loc (loc, ABS_EXPR, type, arg0),
+                           build_real_truncate (type, dconst_sqrt2 ()));
 
   return NULL_TREE;
 }
@@ -8529,10 +8516,8 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
          tree arg = CALL_EXPR_ARG (arg0, 0);
          if (tree_expr_nonnegative_p (arg))
            {
-             const REAL_VALUE_TYPE dconstroot
-               = real_value_truncate (TYPE_MODE (type), dconst_third ());
-             tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
-                                       build_real (type, dconstroot));
+             tree c = build_real_truncate (type, dconst_third ());
+             tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, c);
              return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
            }
        }
index 8842e047d50c0ec865f2e99926c32844a22a3a25..9962b0ae3559d99f99ccedc2877753b13c190161 100644 (file)
@@ -2189,8 +2189,7 @@ along with GCC; see the file COPYING3.  If not see
        {
        CASE_FLT_FN (BUILT_IN_EXP):
          /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
-        x = build_real (type, real_value_truncate (TYPE_MODE (type),
-                                                   dconst_e ()));
+        x = build_real_truncate (type, dconst_e ());
          break;
        CASE_FLT_FN (BUILT_IN_EXP2):
          /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
@@ -2226,8 +2225,7 @@ along with GCC; see the file COPYING3.  If not see
          break;
        CASE_FLT_FN (BUILT_IN_CBRT):
         /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
-         x = build_real (type, real_value_truncate (TYPE_MODE (type),
-                                                   dconst_third ()));
+         x = build_real_truncate (type, dconst_third ());
          break;
        default:
         gcc_unreachable ();
index ecbe563abd6302bc6636418551e700acf66fa5ed..149727953de33f89f13b7fe1b07178e93cd8f3b2 100644 (file)
@@ -440,6 +440,9 @@ bool real_can_shorten_arithmetic (machine_mode, machine_mode);
 /* In tree.c: wrap up a REAL_VALUE_TYPE in a tree node.  */
 extern tree build_real (tree, REAL_VALUE_TYPE);
 
+/* Likewise, but first truncate the value to the type.  */
+extern tree build_real_truncate (tree, REAL_VALUE_TYPE);
+
 /* Calculate R as X raised to the integer exponent N in mode MODE.  */
 extern bool real_powi (REAL_VALUE_TYPE *, machine_mode,
                       const REAL_VALUE_TYPE *, HOST_WIDE_INT);
index bfcf3746da2b56766ac8c06f58af52eee4ad4283..f78a2c26cd7e00a0b1c6c680ae2d9f598a6477ba 100644 (file)
@@ -1877,6 +1877,14 @@ build_real (tree type, REAL_VALUE_TYPE d)
   return v;
 }
 
+/* Like build_real, but first truncate D to the type.  */
+
+tree
+build_real_truncate (tree type, REAL_VALUE_TYPE d)
+{
+  return build_real (type, real_value_truncate (TYPE_MODE (type), d));
+}
+
 /* Return a new REAL_CST node whose type is TYPE
    and whose value is the integer value of the INTEGER_CST node I.  */
 
@@ -12093,7 +12101,7 @@ strip_float_extensions (tree exp)
               && 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));
+       return build_real_truncate (type, orig);
     }
 
   if (!CONVERT_EXPR_P (exp))