This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, PR target/69010] Fix expand for constant boolean vectors with a scalar mode
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Ilya Enkovich <enkovich dot gnu at gmail dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 8 Jan 2016 10:46:24 +0100
- Subject: Re: [PATCH, PR target/69010] Fix expand for constant boolean vectors with a scalar mode
- Authentication-results: sourceware.org; auth=none
- References: <20151223091424 dot GA35713 at msticlxl57 dot ims dot intel dot com>
On Wed, Dec 23, 2015 at 10:14 AM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
> Hi,
>
> Currently boolean vector constant is expanded incorrectly when
> it has a scalar mode. Generated constant is incorrect and also
> its mode (which is VOIDmode) is used for roce_reg which causes
> ICE. This patch fixes both problems. Bootstrapped and tested
> on x86_64-pc-linux-gnu. OK for trunk?
Ok.
Thanks,
Richard.
> Thanks,
> Ilya
> --
> gcc/
>
> 2015-12-23 Ilya Enkovich <enkovich.gnu@gmail.com>
>
> * 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/
>
> 2015-12-23 Ilya Enkovich <enkovich.gnu@gmail.com>
>
> * gcc.target/i386/pr69010.c: New test.
>
>
> diff --git a/gcc/expr.c b/gcc/expr.c
> index bd43dc4..2183ef2 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);
>
> @@ -9745,9 +9746,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)
> {
> @@ -11458,6 +11465,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 8cc4802..ae675fb 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/gcc.target/i386/pr69010.c b/gcc/testsuite/gcc.target/i386/pr69010.c
> new file mode 100644
> index 0000000..29f66f4
> --- /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 ();
> + }
> + }
> +}