From 605c2a393d3a2db86454a70fd7c9467db434060c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 23 Oct 2020 08:40:15 +0200 Subject: [PATCH] middle-end/97521 - always use single-bit bools in mask vector types This makes us always use a single-bit boolean type component type for integer mode mask VECTOR_BOOLEAN_TYPE_P to match the RTL and target representation. This aovids the need for magic translation and the inconsistencies from the translation requirement now that we expose temporaries of those types on the GIMPLE level. 2020-10-23 Richard Biener PR middle-end/97521 * expr.c (const_scalar_mask_from_tree): Remove. (expand_expr_real_1): Always VIEW_CONVERT integer mode vector constants to an integer type. * tree.c (build_truth_vector_type_for_mode): Use a single-bit boolean component type for non-vector-mode mask_mode. * gcc.target/i386/pr97521.c: New testcase. --- gcc/expr.c | 39 +++---------------------- gcc/testsuite/gcc.target/i386/pr97521.c | 27 +++++++++++++++++ gcc/tree.c | 11 +++++-- 3 files changed, 40 insertions(+), 37 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr97521.c diff --git a/gcc/expr.c b/gcc/expr.c index 9d951e82522..ae16f077758 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -96,7 +96,6 @@ static void emit_single_push_insn (machine_mode, rtx, tree); static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx, profile_probability); static rtx const_vector_from_tree (tree); -static rtx const_scalar_mask_from_tree (scalar_int_mode, tree); static tree tree_expr_size (const_tree); static HOST_WIDE_INT int_expr_size (tree); static void convert_mode_scalar (rtx, rtx, int); @@ -10356,16 +10355,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, scalar_int_mode int_mode; if (is_int_mode (mode, &int_mode)) { - if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp))) - return const_scalar_mask_from_tree (int_mode, exp); - else - { - tree type_for_mode - = lang_hooks.types.type_for_mode (int_mode, 1); - if (type_for_mode) - tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR, - type_for_mode, exp); - } + tree type_for_mode = lang_hooks.types.type_for_mode (int_mode, 1); + if (type_for_mode) + tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR, + type_for_mode, exp); } if (!tmp) { @@ -12739,30 +12732,6 @@ const_vector_mask_from_tree (tree exp) return builder.build (); } -/* EXP is a VECTOR_CST in which each element is either all-zeros or all-ones. - Return a constant scalar rtx of mode MODE in which bit X is set if element - X of EXP is nonzero. */ -static rtx -const_scalar_mask_from_tree (scalar_int_mode mode, tree exp) -{ - wide_int res = wi::zero (GET_MODE_PRECISION (mode)); - tree elt; - - /* The result has a fixed number of bits so the input must too. */ - unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant (); - for (unsigned int i = 0; i < nunits; ++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/testsuite/gcc.target/i386/pr97521.c b/gcc/testsuite/gcc.target/i386/pr97521.c new file mode 100644 index 00000000000..804ffd61e13 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr97521.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-options "-O -mno-sse2" } */ + +typedef unsigned char __attribute__ ((__vector_size__ (8))) V; +typedef unsigned long long __attribute__ ((__vector_size__ (16))) W; + +V c; +W d, e; + +V +foo (W f) +{ + W g = (W) { 0, 209 } <7 <= (0 < f); + W h = e + g + d; + V j = (V) (h[0]) + (V) c; + return j; +} + +int +main (void) +{ + V x = foo ((W) { 3 }); + for (unsigned i = 0; i < sizeof (x); i++) + if (x[i] != 0xff) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree.c b/gcc/tree.c index fa03d963eed..6759ac8179a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10926,8 +10926,15 @@ build_truth_vector_type_for_mode (poly_uint64 nunits, machine_mode mask_mode) { gcc_assert (mask_mode != BLKmode); - poly_uint64 vsize = GET_MODE_BITSIZE (mask_mode); - unsigned HOST_WIDE_INT esize = vector_element_size (vsize, nunits); + unsigned HOST_WIDE_INT esize; + if (VECTOR_MODE_P (mask_mode)) + { + poly_uint64 vsize = GET_MODE_BITSIZE (mask_mode); + esize = vector_element_size (vsize, nunits); + } + else + esize = 1; + tree bool_type = build_nonstandard_boolean_type (esize); return make_vector_type (bool_type, nunits, mask_mode); -- 2.30.2