diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/expr.c | 39 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr97521.c | 27 | ||||
-rw-r--r-- | gcc/tree.c | 11 |
3 files changed, 40 insertions, 37 deletions
@@ -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 0000000..804ffd6 --- /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; +} @@ -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); |