re PR tree-optimization/68501 (sqrt builtin is not used anymore)
authorJakub Jelinek <jakub@redhat.com>
Mon, 30 Nov 2015 14:56:08 +0000 (15:56 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 30 Nov 2015 14:56:08 +0000 (15:56 +0100)
PR tree-optimization/68501
* target.def (builtin_reciprocal): Replace the 3 arguments with
a gcall * one, adjust description.
* targhooks.h (default_builtin_reciprocal): Replace the 3 arguments
with a gcall * one.
* targhooks.c (default_builtin_reciprocal): Likewise.
* tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Use
targetm.builtin_reciprocal even on internal functions, adjust
the arguments and allow replacing an internal function with normal
built-in.
* config/i386/i386.c (ix86_builtin_reciprocal): Replace the 3 arguments
with a gcall * one.  Handle internal fns too.
* config/rs6000/rs6000.c (rs6000_builtin_reciprocal): Likewise.
* config/aarch64/aarch64.c (aarch64_builtin_reciprocal): Likewise.
* doc/tm.texi (builtin_reciprocal): Document.

From-SVN: r231075

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/i386/i386.c
gcc/config/rs6000/rs6000.c
gcc/doc/tm.texi
gcc/target.def
gcc/targhooks.c
gcc/targhooks.h
gcc/tree-ssa-math-opts.c

index 94ce1a4c241a37369b1ed41fbf2f462d92c7b124..735fbd9964c207b3cb7b8c4485eb665302abca2f 100644 (file)
@@ -1,3 +1,21 @@
+2015-11-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/68501
+       * target.def (builtin_reciprocal): Replace the 3 arguments with
+       a gcall * one, adjust description.
+       * targhooks.h (default_builtin_reciprocal): Replace the 3 arguments
+       with a gcall * one.
+       * targhooks.c (default_builtin_reciprocal): Likewise.
+       * tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Use
+       targetm.builtin_reciprocal even on internal functions, adjust
+       the arguments and allow replacing an internal function with normal
+       built-in.
+       * config/i386/i386.c (ix86_builtin_reciprocal): Replace the 3 arguments
+       with a gcall * one.  Handle internal fns too.
+       * config/rs6000/rs6000.c (rs6000_builtin_reciprocal): Likewise.
+       * config/aarch64/aarch64.c (aarch64_builtin_reciprocal): Likewise.
+       * doc/tm.texi (builtin_reciprocal): Document.
+
 2015-11-30  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/68592
index 3fe2f0f180d1119bcd0f71ab2ffe38d8371ec325..b150283569d785a5cca2b747c26ab4196f704dc9 100644 (file)
@@ -7103,19 +7103,21 @@ aarch64_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
    reciprocal square root builtins.  */
 
 static tree
-aarch64_builtin_reciprocal (unsigned int fn,
-                           bool md_fn,
-                           bool)
+aarch64_builtin_reciprocal (gcall *call)
 {
   if (flag_trapping_math
       || !flag_unsafe_math_optimizations
       || optimize_size
       || ! (aarch64_tune_params.extra_tuning_flags
           & AARCH64_EXTRA_TUNE_RECIP_SQRT))
-  {
     return NULL_TREE;
-  }
 
+  if (gimple_call_internal_p (call)
+    return NULL_TREE;
+
+  tree fndecl = gimple_call_fndecl (call);
+  enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
+  bool md_fn = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
   return aarch64_builtin_rsqrt (fn, md_fn);
 }
 
index 2ac6c259f415d894e4c60eb29c7c280af36c9b0a..23a4273400779d79a243b1b04c9e79eb3d7a3227 100644 (file)
@@ -42680,16 +42680,40 @@ ix86_vectorize_builtin_scatter (const_tree vectype,
    reciprocal of the function, or NULL_TREE if not available.  */
 
 static tree
-ix86_builtin_reciprocal (unsigned int fn, bool md_fn, bool)
+ix86_builtin_reciprocal (gcall *call)
 {
   if (! (TARGET_SSE_MATH && !optimize_insn_for_size_p ()
         && flag_finite_math_only && !flag_trapping_math
         && flag_unsafe_math_optimizations))
     return NULL_TREE;
 
-  if (md_fn)
+  if (gimple_call_internal_p (call))
+    switch (gimple_call_internal_fn (call))
+      {
+       tree type;
+      case IFN_SQRT:
+       type = TREE_TYPE (gimple_call_lhs (call));
+       switch (TYPE_MODE (type))
+         {
+           /* Vectorized version of sqrt to rsqrt conversion.  */
+         case V4SFmode:
+           return ix86_get_builtin (IX86_BUILTIN_RSQRTPS_NR);
+
+         case V8SFmode:
+           return ix86_get_builtin (IX86_BUILTIN_RSQRTPS_NR256);
+
+         default:
+           return NULL_TREE;
+         }
+
+      default:
+       return NULL_TREE;
+      }
+
+  tree fndecl = gimple_call_fndecl (call);
+  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
     /* Machine dependent builtins.  */
-    switch (fn)
+    switch (DECL_FUNCTION_CODE (fndecl))
       {
        /* Vectorized version of sqrt to rsqrt conversion.  */
       case IX86_BUILTIN_SQRTPS_NR:
@@ -42703,7 +42727,7 @@ ix86_builtin_reciprocal (unsigned int fn, bool md_fn, bool)
       }
   else
     /* Normal builtins.  */
-    switch (fn)
+    switch (DECL_FUNCTION_CODE (fndecl))
       {
        /* Sqrt to rsqrt conversion.  */
       case BUILT_IN_SQRTF:
index a38e70d2c332a09f22fe1c3158e3ef37392ddceb..c4e3f2fb5385f482aeb3de1a60b83b7ee7c23119 100644 (file)
@@ -32643,14 +32643,42 @@ rs6000_memory_move_cost (machine_mode mode, reg_class_t rclass,
    reciprocal of the function, or NULL_TREE if not available.  */
 
 static tree
-rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
-                          bool sqrt ATTRIBUTE_UNUSED)
+rs6000_builtin_reciprocal (gcall *call)
 {
   if (optimize_insn_for_size_p ())
     return NULL_TREE;
 
-  if (md_fn)
-    switch (fn)
+  if (gimple_call_internal_p (call))
+    switch (gimple_call_internal_fn (call))
+      {
+       tree type;
+      case IFN_SQRT:
+       type = TREE_TYPE (gimple_call_lhs (call));
+       switch (TYPE_MODE (type))
+         {
+         case V2DFmode:
+           if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
+             return NULL_TREE;
+
+           return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_2DF];
+
+         case V4SFmode:
+           if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
+             return NULL_TREE;
+
+           return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_4SF];
+
+         default:
+           return NULL_TREE;
+         }
+
+      default:
+       return NULL_TREE;
+      }
+
+  tree fndecl = gimple_call_fndecl (call);
+  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
+    switch (DECL_FUNCTION_CODE (fndecl))
       {
       case VSX_BUILTIN_XVSQRTDP:
        if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
@@ -32669,7 +32697,7 @@ rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
       }
 
   else
-    switch (fn)
+    switch (DECL_FUNCTION_CODE (fndecl))
       {
       case BUILT_IN_SQRT:
        if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
index bde808b6180abd930a8af6363e0dac5a2c2d31ec..7146ec558365f3e8c1f0dc98bb474086d8d35a05 100644 (file)
@@ -5608,14 +5608,10 @@ be placed in an @code{object_block} structure.
 The default version returns true for all decls.
 @end deftypefn
 
-@deftypefn {Target Hook} tree TARGET_BUILTIN_RECIPROCAL (unsigned @var{fn}, bool @var{md_fn}, bool @var{sqrt})
+@deftypefn {Target Hook} tree TARGET_BUILTIN_RECIPROCAL (gcall *@var{call})
 This hook should return the DECL of a function that implements reciprocal of
-the builtin function with builtin function code @var{fn}, or
-@code{NULL_TREE} if such a function is not available.  @var{md_fn} is true
-when @var{fn} is a code of a machine-dependent builtin function.  When
-@var{sqrt} is true, additional optimizations that apply only to the reciprocal
-of a square root function are performed, and only reciprocals of @code{sqrt}
-function are valid.
+the builtin or internal function call @var{call}, or
+@code{NULL_TREE} if such a function is not available.
 @end deftypefn
 
 @deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD (void)
index b0ad09e0fed6a069d9d4b9cee85abb0a901ac959..1d40012c5a2f6c90ea7a9c0a44b7b38b5d2da925 100644 (file)
@@ -2463,13 +2463,9 @@ identical versions.",
 DEFHOOK
 (builtin_reciprocal,
  "This hook should return the DECL of a function that implements reciprocal of\n\
-the builtin function with builtin function code @var{fn}, or\n\
-@code{NULL_TREE} if such a function is not available.  @var{md_fn} is true\n\
-when @var{fn} is a code of a machine-dependent builtin function.  When\n\
-@var{sqrt} is true, additional optimizations that apply only to the reciprocal\n\
-of a square root function are performed, and only reciprocals of @code{sqrt}\n\
-function are valid.",
- tree, (unsigned fn, bool md_fn, bool sqrt),
+the builtin or internal function call @var{call}, or\n\
+@code{NULL_TREE} if such a function is not available.",
+ tree, (gcall *call),
  default_builtin_reciprocal)
 
 /* For a vendor-specific TYPE, return a pointer to a statically-allocated
index 01d3686299b5d1aa4fe8ff82f29d9b6a4cb2d08a..3868230c6624305c67408d45e3796a48b8ea1b03 100644 (file)
@@ -600,9 +600,7 @@ default_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
 /* Reciprocal.  */
 
 tree
-default_builtin_reciprocal (unsigned int fn ATTRIBUTE_UNUSED,
-                           bool md_fn ATTRIBUTE_UNUSED,
-                           bool sqrt ATTRIBUTE_UNUSED)
+default_builtin_reciprocal (gcall *)
 {
   return NULL_TREE;
 }
index f5d04e6c91494dc5ae3e50bf9348c3ef69fa6e63..c8094704c0946595fbe6420022e7fc181f5ece6b 100644 (file)
@@ -90,7 +90,7 @@ extern tree default_builtin_vectorized_conversion (unsigned int, tree, tree);
 
 extern int default_builtin_vectorization_cost (enum vect_cost_for_stmt, tree, int);
 
-extern tree default_builtin_reciprocal (unsigned int, bool, bool);
+extern tree default_builtin_reciprocal (gcall *);
 
 extern HOST_WIDE_INT default_vector_alignment (const_tree);
 
index 8376eab746d88d276ae1efaf6cfdb8f528fc885d..66d750138a09f85d1c082e8b4ba95e29ff0f5c0b 100644 (file)
@@ -601,19 +601,17 @@ pass_cse_reciprocals::execute (function *fun)
 
              if (is_gimple_call (stmt1)
                  && gimple_call_lhs (stmt1)
-                 && (fndecl = gimple_call_fndecl (stmt1))
-                 && (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
-                     || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD))
+                 && (gimple_call_internal_p (stmt1)
+                     || ((fndecl = gimple_call_fndecl (stmt1))
+                         && (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+                             || (DECL_BUILT_IN_CLASS (fndecl)
+                                 == BUILT_IN_MD)))))
                {
-                 enum built_in_function code;
-                 bool md_code, fail;
+                 bool fail;
                  imm_use_iterator ui;
                  use_operand_p use_p;
 
-                 code = DECL_FUNCTION_CODE (fndecl);
-                 md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
-
-                 fndecl = targetm.builtin_reciprocal (code, md_code, false);
+                 fndecl = targetm.builtin_reciprocal (as_a <gcall *> (stmt1));
                  if (!fndecl)
                    continue;
 
@@ -639,8 +637,28 @@ pass_cse_reciprocals::execute (function *fun)
                    continue;
 
                  gimple_replace_ssa_lhs (stmt1, arg1);
-                 gimple_call_set_fndecl (stmt1, fndecl);
-                 update_stmt (stmt1);
+                 if (gimple_call_internal_p (stmt1))
+                   {
+                     auto_vec<tree, 4> args;
+                     for (unsigned int i = 0;
+                          i < gimple_call_num_args (stmt1); i++)
+                       args.safe_push (gimple_call_arg (stmt1, i));
+                     gcall *stmt2 = gimple_build_call_vec (fndecl, args);
+                     gimple_call_set_lhs (stmt2, arg1);
+                     if (gimple_vdef (stmt1))
+                       {
+                         gimple_set_vdef (stmt2, gimple_vdef (stmt1));
+                         SSA_NAME_DEF_STMT (gimple_vdef (stmt2)) = stmt2;
+                       }
+                     gimple_set_vuse (stmt2, gimple_vuse (stmt1));
+                     gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt1);
+                     gsi_replace (&gsi2, stmt2, true);
+                   }
+                 else
+                   {
+                     gimple_call_set_fndecl (stmt1, fndecl);
+                     update_stmt (stmt1);
+                   }
                  reciprocal_stats.rfuncs_inserted++;
 
                  FOR_EACH_IMM_USE_STMT (stmt, ui, arg1)