diff options
author | ienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-11 10:27:17 +0000 |
---|---|---|
committer | ienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-01-11 10:27:17 +0000 |
commit | 7a15835238aed3842a71cb00605881f053679452 (patch) | |
tree | ae811e2413e2fbf7ab3c5f0df5dc2cf1b1af4dc4 | |
parent | ff375d11bfdf9c36d679967652e80efd6a597a25 (diff) | |
download | gcc-7a15835238aed3842a71cb00605881f053679452.tar.gz |
gcc/
PR target/69010
* expr.c (expand_expr_real_1): For boolean vector constants
with a scalar mode use const_scalar_mask_from_tree.
(const_scalar_mask_from_tree): New.
* optabs.c (expand_vec_cond_mask_expr): Use mask mode
assigned to a mask type to handle constants.
gcc/testsuite/
PR target/69010
* gcc.target/i386/pr69010.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232216 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/expr.c | 36 | ||||
-rw-r--r-- | gcc/optabs.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr69010.c | 49 |
5 files changed, 97 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f28cf448312..bfdefb91ce5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-01-11 Ilya Enkovich <enkovich.gnu@gmail.com> + + PR target/69010 + * expr.c (expand_expr_real_1): For boolean vector constants + with a scalar mode use const_scalar_mask_from_tree. + (const_scalar_mask_from_tree): New. + * optabs.c (expand_vec_cond_mask_expr): Use mask mode + assigned to a mask type to handle constants. + 2016-01-11 Martin Jambor <mjambor@suse.cz> PR ipa/69044 diff --git a/gcc/expr.c b/gcc/expr.c index 0c5dff8be97..0a1c4259bb5 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -137,6 +137,7 @@ static void emit_single_push_insn (machine_mode, rtx, tree); #endif static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx, int); static rtx const_vector_from_tree (tree); +static rtx const_scalar_mask_from_tree (tree); static tree tree_expr_size (const_tree); static HOST_WIDE_INT int_expr_size (tree); @@ -9742,9 +9743,15 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, return const_vector_from_tree (exp); if (GET_MODE_CLASS (mode) == MODE_INT) { - tree type_for_mode = lang_hooks.types.type_for_mode (mode, 1); - if (type_for_mode) - tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR, type_for_mode, exp); + if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp))) + return const_scalar_mask_from_tree (exp); + else + { + tree type_for_mode = lang_hooks.types.type_for_mode (mode, 1); + if (type_for_mode) + tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR, + type_for_mode, exp); + } } if (!tmp) { @@ -11455,6 +11462,29 @@ const_vector_mask_from_tree (tree exp) return gen_rtx_CONST_VECTOR (mode, v); } +/* Return a CONST_INT rtx representing vector mask for + a VECTOR_CST of booleans. */ +static rtx +const_scalar_mask_from_tree (tree exp) +{ + machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); + wide_int res = wi::zero (GET_MODE_PRECISION (mode)); + tree elt; + unsigned i; + + for (i = 0; i < VECTOR_CST_NELTS (exp); ++i) + { + elt = VECTOR_CST_ELT (exp, i); + gcc_assert (TREE_CODE (elt) == INTEGER_CST); + if (integer_all_onesp (elt)) + res = wi::set_bit (res, i); + else + gcc_assert (integer_zerop (elt)); + } + + return immed_wide_int_const (res, mode); +} + /* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */ static rtx const_vector_from_tree (tree exp) diff --git a/gcc/optabs.c b/gcc/optabs.c index d9c118369bb..e1ba6150473 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -5547,7 +5547,7 @@ expand_vec_cond_mask_expr (tree vec_cond_type, tree op0, tree op1, tree op2, rtx_op1 = expand_normal (op1); rtx_op2 = expand_normal (op2); - mask = force_reg (GET_MODE (mask), mask); + mask = force_reg (mask_mode, mask); rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1); create_output_operand (&ops[0], target, mode); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 69f589f281c..cabef26023e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-11 Ilya Enkovich <enkovich.gnu@gmail.com> + + PR target/69010 + * gcc.target/i386/pr69010.c: New test. + 2016-01-11 Martin Jambor <mjambor@suse.cz> PR ipa/69044 diff --git a/gcc/testsuite/gcc.target/i386/pr69010.c b/gcc/testsuite/gcc.target/i386/pr69010.c new file mode 100644 index 00000000000..29f66f49974 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr69010.c @@ -0,0 +1,49 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -ftree-vectorize -mavx512bw" } */ +/* { dg-require-effective-target avx512bw } */ + +#define AVX512BW +#include "avx512f-helper.h" + +extern void abort (void); + +void __attribute__((noinline,noclone)) +test1 (int *a, int *b, int *c) +{ + int i; + for (i = 0; i < 16; i++) + { + if ((i == 0) || (i == 3)) + a[i] = b[i]; + else + a[i] = c[i]; + } +} + +void +TEST () +{ + int a[16], b[16], c[16], i; + + for (i = 0; i < 16; i++) + { + a[i] = i; + b[i] = -i; + } + + test1 (a, b, c); + + for (i = 0; i < 16; i++) + { + if ((i == 0) || (i == 3)) + { + if (a[i] != b[i]) + abort (); + } + else + { + if (a[i] != c[i]) + abort (); + } + } +} |