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:
parent
4052c05e5b
commit
605c2a393d
39
gcc/expr.c
39
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)
|
||||
|
27
gcc/testsuite/gcc.target/i386/pr97521.c
Normal file
27
gcc/testsuite/gcc.target/i386/pr97521.c
Normal 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;
|
||||
}
|
11
gcc/tree.c
11
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);
|
||||
|
Loading…
Reference in New Issue
Block a user