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  <rguenther@suse.de>

	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.
This commit is contained in:
Richard Biener 2020-10-23 08:40:15 +02:00
parent 4052c05e5b
commit 605c2a393d
3 changed files with 40 additions and 37 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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);