From 5c0caeb37ff72cfd9153e164e9fd9eec7d56e969 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 3 Jan 2018 21:43:02 +0000 Subject: [PATCH] Add support for MODE_VECTOR_BOOL This patch adds a new mode class to represent vectors of booleans. GET_MODE_BITSIZE (m) / GET_MODE_NUNITS (m) determines the number of bits that are used to represent each boolean; this can be 1 for a fully-packed representation or greater than 1 for an unpacked representation. In the latter case, the value of bits other than the lowest is not significant. These are used by the SVE port to represent predicates. 2018-01-03 Richard Sandiford Alan Hayward David Sherwood gcc/ * mode-classes.def (MODE_VECTOR_BOOL): New mode class. * machmode.h (INTEGRAL_MODE_P, VECTOR_MODE_P): Return true for MODE_VECTOR_BOOL. * machmode.def (VECTOR_BOOL_MODE): Document. * genmodes.c (VECTOR_BOOL_MODE): New macro. (make_vector_bool_mode): New function. (complete_mode, emit_mode_wider, emit_mode_adjustments): Handle MODE_VECTOR_BOOL. * lto-streamer-in.c (lto_input_mode_table): Likewise. * rtx-vector-builder.c (rtx_vector_builder::find_cached_value): Likewise. * stor-layout.c (int_mode_for_mode): Likewise. * tree.c (build_vector_type_for_mode): Likewise. * varasm.c (output_constant_pool_2): Likewise. * emit-rtl.c (init_emit_once): Make sure that CONST1_RTX (BImode) and CONSTM1_RTX (BImode) are the same thing. Initialize const_tiny_rtx for MODE_VECTOR_BOOL. * expr.c (expand_expr_real_1): Use VECTOR_MODE_P instead of a list of mode class checks. * tree-vect-generic.c (expand_vector_operation): Use VECTOR_MODE_P instead of a list of mode class checks. (expand_vector_scalar_condition): Likewise. (type_for_widest_vector_mode): Handle BImode as an inner mode. gcc/c-family/ * c-common.c (c_common_type_for_mode): Handle MODE_VECTOR_BOOL. gcc/fortran/ * trans-types.c (gfc_type_for_mode): Handle MODE_VECTOR_BOOL. gcc/go/ * go-lang.c (go_langhook_type_for_mode): Handle MODE_VECTOR_BOOL. gcc/lto/ * lto-lang.c (lto_type_for_mode): Handle MODE_VECTOR_BOOL. Co-Authored-By: Alan Hayward Co-Authored-By: David Sherwood From-SVN: r256202 --- gcc/ChangeLog | 28 ++++++++++++++++++++++++++++ gcc/c-family/ChangeLog | 6 ++++++ gcc/c-family/c-common.c | 8 ++++++++ gcc/emit-rtl.c | 19 +++++++++++++++---- gcc/expr.c | 7 +------ gcc/fortran/ChangeLog | 6 ++++++ gcc/fortran/trans-types.c | 8 ++++++++ gcc/genmodes.c | 38 +++++++++++++++++++++++++++++++++++++- gcc/go/ChangeLog | 6 ++++++ gcc/go/go-lang.c | 10 +++++++++- gcc/lto-streamer-in.c | 1 + gcc/lto/ChangeLog | 6 ++++++ gcc/lto/lto-lang.c | 8 ++++++++ gcc/machmode.def | 7 +++++++ gcc/machmode.h | 6 ++++-- gcc/mode-classes.def | 1 + gcc/rtx-vector-builder.c | 10 ++++++++++ gcc/stor-layout.c | 5 +++-- gcc/tree-vect-generic.c | 16 ++++------------ gcc/tree.c | 1 + gcc/varasm.c | 26 ++++++++++++++++++++++++++ 21 files changed, 195 insertions(+), 28 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4759c30c11..28b1d4ef280 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,31 @@ +2018-01-03 Richard Sandiford + Alan Hayward + David Sherwood + + * mode-classes.def (MODE_VECTOR_BOOL): New mode class. + * machmode.h (INTEGRAL_MODE_P, VECTOR_MODE_P): Return true + for MODE_VECTOR_BOOL. + * machmode.def (VECTOR_BOOL_MODE): Document. + * genmodes.c (VECTOR_BOOL_MODE): New macro. + (make_vector_bool_mode): New function. + (complete_mode, emit_mode_wider, emit_mode_adjustments): Handle + MODE_VECTOR_BOOL. + * lto-streamer-in.c (lto_input_mode_table): Likewise. + * rtx-vector-builder.c (rtx_vector_builder::find_cached_value): + Likewise. + * stor-layout.c (int_mode_for_mode): Likewise. + * tree.c (build_vector_type_for_mode): Likewise. + * varasm.c (output_constant_pool_2): Likewise. + * emit-rtl.c (init_emit_once): Make sure that CONST1_RTX (BImode) and + CONSTM1_RTX (BImode) are the same thing. Initialize const_tiny_rtx + for MODE_VECTOR_BOOL. + * expr.c (expand_expr_real_1): Use VECTOR_MODE_P instead of a list + of mode class checks. + * tree-vect-generic.c (expand_vector_operation): Use VECTOR_MODE_P + instead of a list of mode class checks. + (expand_vector_scalar_condition): Likewise. + (type_for_widest_vector_mode): Handle BImode as an inner mode. + 2018-01-03 Richard Sandiford Alan Hayward David Sherwood diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 0deb8889076..e79d9858ac0 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2018-01-03 Richard Sandiford + Alan Hayward + David Sherwood + + * c-common.c (c_common_type_for_mode): Handle MODE_VECTOR_BOOL. + 2018-01-03 Richard Sandiford Alan Hayward David Sherwood diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index cebd1b871d1..87bd326b5e4 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -2279,6 +2279,14 @@ c_common_type_for_mode (machine_mode mode, int unsignedp) if (inner_type != NULL_TREE) return build_complex_type (inner_type); } + else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL + && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) + { + unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode), + GET_MODE_NUNITS (mode)); + tree bool_type = build_nonstandard_boolean_type (elem_bits); + return build_vector_type_for_mode (bool_type, mode); + } else if (VECTOR_MODE_P (mode) && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) { diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index eedd1616722..c6ce35889b1 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -6268,6 +6268,12 @@ init_emit_once (void) FOR_EACH_MODE_IN_CLASS (mode, MODE_INT) const_tiny_rtx[3][(int) mode] = constm1_rtx; + /* For BImode, 1 and -1 are unsigned and signed interpretations + of the same value. */ + const_tiny_rtx[0][(int) BImode] = const0_rtx; + const_tiny_rtx[1][(int) BImode] = const_true_rtx; + const_tiny_rtx[3][(int) BImode] = const_true_rtx; + for (mode = MIN_MODE_PARTIAL_INT; mode <= MAX_MODE_PARTIAL_INT; mode = (machine_mode)((int)(mode) + 1)) @@ -6285,6 +6291,15 @@ init_emit_once (void) const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner); } + /* As for BImode, "all 1" and "all -1" are unsigned and signed + interpretations of the same value. */ + FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_BOOL) + { + const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0); + const_tiny_rtx[3][(int) mode] = gen_const_vector (mode, 3); + const_tiny_rtx[1][(int) mode] = const_tiny_rtx[3][(int) mode]; + } + FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT) { const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0); @@ -6386,10 +6401,6 @@ init_emit_once (void) if (GET_MODE_CLASS ((machine_mode) i) == MODE_CC) const_tiny_rtx[0][i] = const0_rtx; - const_tiny_rtx[0][(int) BImode] = const0_rtx; - if (STORE_FLAG_VALUE == 1) - const_tiny_rtx[1][(int) BImode] = const1_rtx; - FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_POINTER_BOUNDS) { scalar_mode smode = smode_iter.require (); diff --git a/gcc/expr.c b/gcc/expr.c index 281a714a797..cd1e57d0eec 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -10082,12 +10082,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, case VECTOR_CST: { tree tmp = NULL_TREE; - if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT - || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT - || GET_MODE_CLASS (mode) == MODE_VECTOR_FRACT - || GET_MODE_CLASS (mode) == MODE_VECTOR_UFRACT - || GET_MODE_CLASS (mode) == MODE_VECTOR_ACCUM - || GET_MODE_CLASS (mode) == MODE_VECTOR_UACCUM) + if (VECTOR_MODE_P (mode)) return const_vector_from_tree (exp); scalar_int_mode int_mode; if (is_int_mode (mode, &int_mode)) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 6188c250b3d..480f36a0254 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2018-01-03 Richard Sandiford + Alan Hayward + David Sherwood + + * trans-types.c (gfc_type_for_mode): Handle MODE_VECTOR_BOOL. + 2018-01-03 Richard Sandiford Alan Hayward David Sherwood diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 82415beea84..16d851e49da 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -3185,6 +3185,14 @@ gfc_type_for_mode (machine_mode mode, int unsignedp) tree type = gfc_type_for_size (GET_MODE_PRECISION (int_mode), unsignedp); return type != NULL_TREE && mode == TYPE_MODE (type) ? type : NULL_TREE; } + else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL + && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) + { + unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode), + GET_MODE_NUNITS (mode)); + tree bool_type = build_nonstandard_boolean_type (elem_bits); + return build_vector_type_for_mode (bool_type, mode); + } else if (VECTOR_MODE_P (mode) && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) { diff --git a/gcc/genmodes.c b/gcc/genmodes.c index b134c1b7515..9e37d65997e 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -375,6 +375,10 @@ complete_mode (struct mode_data *m) m->bytesize = 2 * m->component->bytesize; break; + case MODE_VECTOR_BOOL: + validate_mode (m, UNSET, SET, SET, SET, UNSET); + break; + case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: case MODE_VECTOR_FRACT: @@ -526,6 +530,28 @@ make_vector_modes (enum mode_class cl, unsigned int width, } } +/* Create a vector of booleans called NAME with COUNT elements and + BYTESIZE bytes in total. */ +#define VECTOR_BOOL_MODE(NAME, COUNT, BYTESIZE) \ + make_vector_bool_mode (#NAME, COUNT, BYTESIZE, __FILE__, __LINE__) +static void ATTRIBUTE_UNUSED +make_vector_bool_mode (const char *name, unsigned int count, + unsigned int bytesize, const char *file, + unsigned int line) +{ + struct mode_data *m = find_mode ("BI"); + if (!m) + { + error ("%s:%d: no mode \"BI\"", file, line); + return; + } + + struct mode_data *v = new_mode (MODE_VECTOR_BOOL, name, file, line); + v->component = m; + v->ncomponents = count; + v->bytesize = bytesize; +} + /* Input. */ #define _SPECIAL_MODE(C, N) \ @@ -1438,7 +1464,8 @@ emit_mode_wider (void) /* For vectors we want twice the number of components, with the same element type. */ - if (m->cl == MODE_VECTOR_INT + if (m->cl == MODE_VECTOR_BOOL + || m->cl == MODE_VECTOR_INT || m->cl == MODE_VECTOR_FLOAT || m->cl == MODE_VECTOR_FRACT || m->cl == MODE_VECTOR_UFRACT @@ -1657,6 +1684,7 @@ emit_mode_adjustments (void) printf ("\n /* %s:%d */\n", a->file, a->line); switch (a->mode->cl) { + case MODE_VECTOR_BOOL: case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: case MODE_VECTOR_FRACT: @@ -1688,6 +1716,10 @@ emit_mode_adjustments (void) m->name); break; + case MODE_VECTOR_BOOL: + /* Changes to BImode should not affect vector booleans. */ + break; + case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: case MODE_VECTOR_FRACT: @@ -1728,6 +1760,10 @@ emit_mode_adjustments (void) printf (" mode_base_align[E_%smode] = s;\n", m->name); break; + case MODE_VECTOR_BOOL: + /* Changes to BImode should not affect vector booleans. */ + break; + case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: case MODE_VECTOR_FRACT: diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 727254b9ee5..cf7586ecd90 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,9 @@ +2018-01-03 Richard Sandiford + Alan Hayward + David Sherwood + + * go-lang.c (go_langhook_type_for_mode): Handle MODE_VECTOR_BOOL. + 2018-01-03 Richard Sandiford Alan Hayward David Sherwood diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c index 4a057992da7..e47036f6081 100644 --- a/gcc/go/go-lang.c +++ b/gcc/go/go-lang.c @@ -377,8 +377,16 @@ go_langhook_type_for_mode (machine_mode mode, int unsignedp) make sense for the middle-end to ask the frontend for a type which the frontend does not support. However, at least for now it is required. See PR 46805. */ - if (VECTOR_MODE_P (mode) + if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) + { + unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode), + GET_MODE_NUNITS (mode)); + tree bool_type = build_nonstandard_boolean_type (elem_bits); + return build_vector_type_for_mode (bool_type, mode); + } + else if (VECTOR_MODE_P (mode) + && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) { tree inner; diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 46be029f255..8529c82376b 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -1675,6 +1675,7 @@ lto_input_mode_table (struct lto_file_decl_data *file_data) { switch (mclass) { + case MODE_VECTOR_BOOL: case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: case MODE_VECTOR_FRACT: diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 8240d9f35a5..9c5f292fe5f 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2018-01-03 Richard Sandiford + Alan Hayward + David Sherwood + + * lto-lang.c (lto_type_for_mode): Handle MODE_VECTOR_BOOL. + 2018-01-03 Richard Sandiford Alan Hayward David Sherwood diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index 81a20358a2c..a310d699a19 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -1012,6 +1012,14 @@ lto_type_for_mode (machine_mode mode, int unsigned_p) if (inner_type != NULL_TREE) return build_complex_type (inner_type); } + else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL + && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) + { + unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode), + GET_MODE_NUNITS (mode)); + tree bool_type = build_nonstandard_boolean_type (elem_bits); + return build_vector_type_for_mode (bool_type, mode); + } else if (VECTOR_MODE_P (mode) && valid_vector_subparts_p (GET_MODE_NUNITS (mode))) { diff --git a/gcc/machmode.def b/gcc/machmode.def index 45c5acf90eb..9a92b580b2f 100644 --- a/gcc/machmode.def +++ b/gcc/machmode.def @@ -142,6 +142,13 @@ along with GCC; see the file COPYING3. If not see than two bytes (if CLASS is FLOAT). CLASS must be INT or FLOAT. The names follow the same rule as VECTOR_MODE uses. + VECTOR_BOOL_MODE (NAME, COUNT, BYTESIZE) + Create a vector mode called NAME that contains COUNT boolean + elements and occupies BYTESIZE bytes in total. Each boolean + element occupies (COUNT * BITS_PER_UNIT) / BYTESIZE bits, with + the element at index 0 occupying the lsb of the first byte in + memory. Only the lowest bit of each element is significant. + COMPLEX_MODES (CLASS); For all modes presently declared in class CLASS, construct corresponding complex modes. Modes smaller than one byte diff --git a/gcc/machmode.h b/gcc/machmode.h index 8e918d6dd31..5eaa868527d 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -108,6 +108,7 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES]; (GET_MODE_CLASS (MODE) == MODE_INT \ || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT \ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT \ + || GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \ || GET_MODE_CLASS (MODE) == MODE_VECTOR_INT) /* Nonzero if MODE is a floating-point mode. */ @@ -123,8 +124,9 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES]; || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) /* Nonzero if MODE is a vector mode. */ -#define VECTOR_MODE_P(MODE) \ - (GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \ +#define VECTOR_MODE_P(MODE) \ + (GET_MODE_CLASS (MODE) == MODE_VECTOR_BOOL \ + || GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \ || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT \ || GET_MODE_CLASS (MODE) == MODE_VECTOR_FRACT \ || GET_MODE_CLASS (MODE) == MODE_VECTOR_UFRACT \ diff --git a/gcc/mode-classes.def b/gcc/mode-classes.def index 3624f29120e..522e446c7ba 100644 --- a/gcc/mode-classes.def +++ b/gcc/mode-classes.def @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see DEF_MODE_CLASS (MODE_DECIMAL_FLOAT), /* decimal floating point */ \ DEF_MODE_CLASS (MODE_COMPLEX_INT), /* complex numbers */ \ DEF_MODE_CLASS (MODE_COMPLEX_FLOAT), \ + DEF_MODE_CLASS (MODE_VECTOR_BOOL), /* vectors of single bits */ \ DEF_MODE_CLASS (MODE_VECTOR_INT), /* SIMD vectors */ \ DEF_MODE_CLASS (MODE_VECTOR_FRACT), /* SIMD vectors */ \ DEF_MODE_CLASS (MODE_VECTOR_UFRACT), /* SIMD vectors */ \ diff --git a/gcc/rtx-vector-builder.c b/gcc/rtx-vector-builder.c index 33f76d05ace..c58760a7aaf 100644 --- a/gcc/rtx-vector-builder.c +++ b/gcc/rtx-vector-builder.c @@ -88,6 +88,16 @@ rtx_vector_builder::find_cached_value () rtx elt = (*this)[0]; + if (GET_MODE_CLASS (m_mode) == MODE_VECTOR_BOOL) + { + if (elt == const1_rtx || elt == constm1_rtx) + return CONST1_RTX (m_mode); + else if (elt == const0_rtx) + return CONST0_RTX (m_mode); + else + gcc_unreachable (); + } + /* We can be called before the global vector constants are set up, but in that case we'll just return null. */ scalar_mode inner_mode = GET_MODE_INNER (m_mode); diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index d64f7b7388a..58ebd6cfcfc 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -379,12 +379,13 @@ int_mode_for_mode (machine_mode mode) case MODE_COMPLEX_FLOAT: case MODE_FLOAT: case MODE_DECIMAL_FLOAT: - case MODE_VECTOR_INT: - case MODE_VECTOR_FLOAT: case MODE_FRACT: case MODE_ACCUM: case MODE_UFRACT: case MODE_UACCUM: + case MODE_VECTOR_BOOL: + case MODE_VECTOR_INT: + case MODE_VECTOR_FLOAT: case MODE_VECTOR_FRACT: case MODE_VECTOR_ACCUM: case MODE_VECTOR_UFRACT: diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index d7e77b6ace3..3dcbdeba959 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -981,12 +981,7 @@ expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type /* If the compute mode is not a vector mode (hence we are not decomposing a BLKmode vector to smaller, hardware-supported vectors), we may want to expand the operations in parallel. */ - if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FRACT - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UFRACT - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_ACCUM - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UACCUM) + if (!VECTOR_MODE_P (compute_mode)) switch (code) { case PLUS_EXPR: @@ -1175,6 +1170,8 @@ type_for_widest_vector_mode (tree type, optab op) mode = MIN_MODE_VECTOR_ACCUM; else if (SCALAR_UACCUM_MODE_P (inner_mode)) mode = MIN_MODE_VECTOR_UACCUM; + else if (inner_mode == BImode) + mode = MIN_MODE_VECTOR_BOOL; else mode = MIN_MODE_VECTOR_INT; @@ -1537,12 +1534,7 @@ expand_vector_scalar_condition (gimple_stmt_iterator *gsi) /* If the compute mode is not a vector mode (hence we are not decomposing a BLKmode vector to smaller, hardware-supported vectors), we may want to expand the operations in parallel. */ - if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FRACT - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UFRACT - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_ACCUM - && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UACCUM) + if (!VECTOR_MODE_P (compute_mode)) new_rhs = expand_vector_parallel (gsi, do_cond, type, rhs2, rhs3, COND_EXPR); else diff --git a/gcc/tree.c b/gcc/tree.c index 92376d179ac..63084ac2d4f 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10509,6 +10509,7 @@ build_vector_type_for_mode (tree innertype, machine_mode mode) switch (GET_MODE_CLASS (mode)) { + case MODE_VECTOR_BOOL: case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: case MODE_VECTOR_FRACT: diff --git a/gcc/varasm.c b/gcc/varasm.c index 6f9b565bddb..ea79893a547 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -3918,6 +3918,32 @@ output_constant_pool_2 (fixed_size_mode mode, rtx x, unsigned int align) assemble_integer (x, GET_MODE_SIZE (mode), align, 1); break; + case MODE_VECTOR_BOOL: + { + gcc_assert (GET_CODE (x) == CONST_VECTOR); + + /* Pick the smallest integer mode that contains at least one + whole element. Often this is byte_mode and contains more + than one element. */ + unsigned int nelts = GET_MODE_NUNITS (mode); + unsigned int elt_bits = GET_MODE_BITSIZE (mode) / nelts; + unsigned int int_bits = MAX (elt_bits, BITS_PER_UNIT); + scalar_int_mode int_mode = int_mode_for_size (int_bits, 0).require (); + + /* Build the constant up one integer at a time. */ + unsigned int elts_per_int = int_bits / elt_bits; + for (unsigned int i = 0; i < nelts; i += elts_per_int) + { + unsigned HOST_WIDE_INT value = 0; + unsigned int limit = MIN (nelts - i, elts_per_int); + for (unsigned int j = 0; j < limit; ++j) + if (INTVAL (CONST_VECTOR_ELT (x, i + j)) != 0) + value |= 1 << (j * elt_bits); + output_constant_pool_2 (int_mode, gen_int_mode (value, int_mode), + i != 0 ? MIN (align, int_bits) : align); + } + break; + } case MODE_VECTOR_FLOAT: case MODE_VECTOR_INT: case MODE_VECTOR_FRACT: -- 2.30.2