From: Ilya Enkovich Date: Mon, 11 Jan 2016 10:27:17 +0000 (+0000) Subject: re PR target/69010 (Boolean vector constant with a scalar mode is expanded incorrectly) X-Git-Tag: basepoints/gcc-7~1737 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=83834c094206928ec7a3c43850f5e04889da640e;p=thirdparty%2Fgcc.git re PR target/69010 (Boolean vector constant with a scalar mode is expanded incorrectly) 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. From-SVN: r232216 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f28cf448312a..bfdefb91ce50 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-01-11 Ilya Enkovich + + 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 PR ipa/69044 diff --git a/gcc/expr.c b/gcc/expr.c index 0c5dff8be97a..0a1c4259bb54 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 d9c118369bb5..e1ba61504732 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 69f589f281c5..cabef26023e8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-11 Ilya Enkovich + + PR target/69010 + * gcc.target/i386/pr69010.c: New test. + 2016-01-11 Martin Jambor 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 000000000000..29f66f499749 --- /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 (); + } + } +}