[i386] Fold __builtin_ia32_shufpd to VEC_PERM_EXPR
authorMarc Glisse <marc.glisse@inria.fr>
Mon, 20 May 2019 14:53:29 +0000 (16:53 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Mon, 20 May 2019 14:53:29 +0000 (14:53 +0000)
2019-05-20  Marc Glisse  <marc.glisse@inria.fr>

PR rtl-optimization/43147
* config/i386/i386.c (ix86_gimple_fold_builtin): Handle
IX86_BUILTIN_SHUFPD.

From-SVN: r271422

gcc/ChangeLog
gcc/config/i386/i386.c

index 1cefccff4a62866fd18cb4ed43820cdfb9dd8406..5d300cab81662b75222f80f80cb5c3da78164951 100644 (file)
@@ -1,3 +1,9 @@
+2019-05-20  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR rtl-optimization/43147
+       * config/i386/i386.c (ix86_gimple_fold_builtin): Handle
+       IX86_BUILTIN_SHUFPD.
+
 2019-05-20  Jan Hubicka  <hubicka@ucw.cz>
 
        * tree-ssa-alias.c (refs_may_alias_p_2): Break out from ...
index 647d17d0a68f144ce73fbdedc3acc8a980088b82..54607748b0baac01b200eb66a9f2a689d2cc1e25 100644 (file)
@@ -17297,7 +17297,7 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
   int n_args = gimple_call_num_args (stmt);
   enum ix86_builtins fn_code = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl);
   tree decl = NULL_TREE;
-  tree arg0, arg1;
+  tree arg0, arg1, arg2;
   enum rtx_code rcode;
   unsigned HOST_WIDE_INT count;
   bool is_vshift;
@@ -17601,6 +17601,32 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
        }
       break;
 
+    case IX86_BUILTIN_SHUFPD:
+      arg2 = gimple_call_arg (stmt, 2);
+      if (TREE_CODE (arg2) == INTEGER_CST)
+       {
+         location_t loc = gimple_location (stmt);
+         unsigned HOST_WIDE_INT imask = TREE_INT_CST_LOW (arg2);
+         arg0 = gimple_call_arg (stmt, 0);
+         arg1 = gimple_call_arg (stmt, 1);
+         tree itype = long_long_integer_type_node;
+         tree vtype = build_vector_type (itype, 2); /* V2DI */
+         tree_vector_builder elts (vtype, 2, 1);
+         /* Ignore bits other than the lowest 2.  */
+         elts.quick_push (build_int_cst (itype, imask & 1));
+         imask >>= 1;
+         elts.quick_push (build_int_cst (itype, 2 + (imask & 1)));
+         tree omask = elts.build ();
+         gimple *g = gimple_build_assign (gimple_call_lhs (stmt),
+                                          VEC_PERM_EXPR,
+                                          arg0, arg1, omask);
+         gimple_set_location (g, loc);
+         gsi_replace (gsi, g, false);
+         return true;
+       }
+      // Do not error yet, the constant could be propagated later?
+      break;
+
     default:
       break;
     }