diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-01-03 21:43:02 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-01-03 21:43:02 +0000 |
commit | 5c0caeb37ff72cfd9153e164e9fd9eec7d56e969 (patch) | |
tree | 99f960801c55a722346016899054db7e08ba7b13 /gcc | |
parent | cf098191e47535b89373dccb9a2d3cc4a4ebaef7 (diff) | |
download | gcc-5c0caeb37ff72cfd9153e164e9fd9eec7d56e969.zip gcc-5c0caeb37ff72cfd9153e164e9fd9eec7d56e969.tar.gz gcc-5c0caeb37ff72cfd9153e164e9fd9eec7d56e969.tar.bz2 |
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 <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
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 <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256202
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 8 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 19 | ||||
-rw-r--r-- | gcc/expr.c | 7 | ||||
-rw-r--r-- | gcc/fortran/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fortran/trans-types.c | 8 | ||||
-rw-r--r-- | gcc/genmodes.c | 38 | ||||
-rw-r--r-- | gcc/go/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/go/go-lang.c | 10 | ||||
-rw-r--r-- | gcc/lto-streamer-in.c | 1 | ||||
-rw-r--r-- | gcc/lto/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/lto/lto-lang.c | 8 | ||||
-rw-r--r-- | gcc/machmode.def | 7 | ||||
-rw-r--r-- | gcc/machmode.h | 6 | ||||
-rw-r--r-- | gcc/mode-classes.def | 1 | ||||
-rw-r--r-- | gcc/rtx-vector-builder.c | 10 | ||||
-rw-r--r-- | gcc/stor-layout.c | 5 | ||||
-rw-r--r-- | gcc/tree-vect-generic.c | 16 | ||||
-rw-r--r-- | gcc/tree.c | 1 | ||||
-rw-r--r-- | gcc/varasm.c | 26 |
21 files changed, 195 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4759c3..28b1d4e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,34 @@ Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> + * 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 <richard.sandiford@linaro.org> + Alan Hayward <alan.hayward@arm.com> + David Sherwood <david.sherwood@arm.com> + * machmode.h (mode_size): Change from unsigned short to poly_uint16_pod. (mode_to_bytes): Return a poly_uint16 rather than an unsigned short. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 0deb888..e79d985 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -2,6 +2,12 @@ Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> + * c-common.c (c_common_type_for_mode): Handle MODE_VECTOR_BOOL. + +2018-01-03 Richard Sandiford <richard.sandiford@linaro.org> + Alan Hayward <alan.hayward@arm.com> + David Sherwood <david.sherwood@arm.com> + * c-ubsan.c (ubsan_instrument_shift): Treat GET_MODE_BITSIZE as polynomial. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index cebd1b8..87bd326 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 eedd161..c6ce358 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 (); @@ -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 6188c25..480f36a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -2,6 +2,12 @@ Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> + * trans-types.c (gfc_type_for_mode): Handle MODE_VECTOR_BOOL. + +2018-01-03 Richard Sandiford <richard.sandiford@linaro.org> + Alan Hayward <alan.hayward@arm.com> + David Sherwood <david.sherwood@arm.com> + * trans-types.c (gfc_type_for_mode): Check valid_vector_subparts_p. 2018-01-03 Thomas Koenig <tkoenig@gcc.gnu.org> diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 82415be..16d851e 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 b134c1b..9e37d65 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 727254b..cf7586e 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -2,6 +2,12 @@ Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> + * go-lang.c (go_langhook_type_for_mode): Handle MODE_VECTOR_BOOL. + +2018-01-03 Richard Sandiford <richard.sandiford@linaro.org> + Alan Hayward <alan.hayward@arm.com> + David Sherwood <david.sherwood@arm.com> + * go-lang.c (go_langhook_type_for_mode): Check valid_vector_subparts_p. 2018-01-03 Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c index 4a05799..e47036f 100644 --- a/gcc/go/go-lang.c +++ b/gcc/go/go-lang.c @@ -377,9 +377,17 @@ 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; inner = go_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp); diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 46be029..8529c82 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 8240d9f3..9c5f292 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -2,6 +2,12 @@ Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> + * lto-lang.c (lto_type_for_mode): Handle MODE_VECTOR_BOOL. + +2018-01-03 Richard Sandiford <richard.sandiford@linaro.org> + Alan Hayward <alan.hayward@arm.com> + David Sherwood <david.sherwood@arm.com> + * lto-lang.c (lto_type_for_mode): Check valid_vector_subparts_p. * lto.c (hash_canonical_type): Handle polynomial TYPE_VECTOR_SUBPARTS. diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index 81a2035..a310d69 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 45c5acf..9a92b58 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 8e918d6..5eaa868 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 3624f29..522e446 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 33f76d0..c58760a 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 d64f7b7..58ebd6c 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 d7e77b6..3dcbdeb 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 @@ -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 6f9b565b..ea79893 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: |