aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2019-05-20 16:53:29 +0200
committerMarc Glisse <glisse@gcc.gnu.org>2019-05-20 14:53:29 +0000
commit4d508751f421491052bc1d83150344e6cba30b3b (patch)
tree3baf2dcee3cdad82c9d4fc8e0013557025c3f32d /gcc
parent7f67becc9854ac159c6970951108e5d3e2afa6e8 (diff)
downloadgcc-4d508751f421491052bc1d83150344e6cba30b3b.zip
gcc-4d508751f421491052bc1d83150344e6cba30b3b.tar.gz
gcc-4d508751f421491052bc1d83150344e6cba30b3b.tar.bz2
[i386] Fold __builtin_ia32_shufpd to VEC_PERM_EXPR
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c28
2 files changed, 33 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1cefccf..5d300ca 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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 ...
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 647d17d..5460774 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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;
}