This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Add support for MODE_VECTOR_BOOL
On October 25, 2017 6:05:48 PM GMT+02:00, Richard Sandiford <richard.sandiford@linaro.org> wrote:
>Richard Biener <richard.guenther@gmail.com> writes:
>> On October 25, 2017 5:54:02 PM GMT+02:00, Richard Sandiford
>> <richard.sandiford@linaro.org> wrote:
>>>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.
>>>
>>>Tested on aarch64-linux-gnu, x86_64-linux-gnu and
>>>powerpc64le-linux-gnu,
>>>on top of the poly_int series. OK to install?
>>
>> AVX uses integer modes for predicates. Can't you do the same thing,
>with
>> variable size, of course?
>
>Variable-sized integers would be really painful. The main point of
>the scalar_int_mode series was to take advantage of the fact that
>integers are always fixed size, to avoid poly_int speading even
>further.
>
>I don't think there's any benefit to modelling them as integers for
>SVE.
>We never want to refer to them as integers, but we often want to refer
>to them as vectors. And treating them as vectors fits with the
>tree representation.
>
>> AVX has moves between predicate registers and GPRs.
>
>SVE doesn't have/need this. The GPRs have 64 bits and the maximum
>predicate size is 256 bits, so the two aren't necessarily compatible.
>
>I guess you're worried that target-independent code will suddenly
>need to cope with two different representations of the same thing.
>But besides this patch, it all gets hidden behind the existing
>get_mask_mode hook.
OK, fine. I was exactly wondering that. The AVX handling required changes all over the place...
Richard.
>Thanks,
>Richard
>
>>
>> Richard.
>>
>>
>>>Richard
>>>
>>>
>>>2017-10-25 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.
>>> * 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 (gen_const_vec_duplicate): Likewise,
>>> (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.
>>>
>>>Index: gcc/mode-classes.def
>>>===================================================================
>>>--- gcc/mode-classes.def 2017-10-25 16:50:18.000869425 +0100
>>>+++ gcc/mode-classes.def 2017-10-25 16:50:35.628184659 +0100
>>>@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.
>>> 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 */ \
>>>Index: gcc/machmode.h
>>>===================================================================
>>>--- gcc/machmode.h 2017-10-25 16:50:31.832332710 +0100
>>>+++ gcc/machmode.h 2017-10-25 16:50:35.628184659 +0100
>>>@@ -108,6 +108,7 @@ #define INTEGRAL_MODE_P(MODE) \
>>> (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 @@ #define COMPLEX_MODE_P(MODE) \
>>> || 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 \
>>>Index: gcc/machmode.def
>>>===================================================================
>>>--- gcc/machmode.def 2017-10-25 16:50:18.000869425 +0100
>>>+++ gcc/machmode.def 2017-10-25 16:50:35.628184659 +0100
>>>@@ -142,6 +142,12 @@ along with GCC; see the file COPYING3.
>>> 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 (COUNT, BYTESIZE)
>>>+ Create a vector of booleans with COUNT elements and BYTESIZE bytes.
>>>+ Each boolean 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
>>>Index: gcc/genmodes.c
>>>===================================================================
>>>--- gcc/genmodes.c 2017-10-25 16:50:31.828332866 +0100
>>>+++ gcc/genmodes.c 2017-10-25 16:50:35.627184698 +0100
>>>@@ -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,36 @@ make_vector_modes (enum mode_class cl, u
>>> }
>>> }
>>>
>>>+/* Create a vector of booleans with COUNT elements and BYTESIZE
>bytes
>>>+ in total. */
>>>+#define VECTOR_BOOL_MODE(COUNT, BYTESIZE) \
>>>+ make_vector_bool_mode (COUNT, BYTESIZE, __FILE__, __LINE__)
>>>+static void ATTRIBUTE_UNUSED
>>>+make_vector_bool_mode (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;
>>>+ }
>>>+
>>>+ char buf[8];
>>>+ if ((size_t) snprintf (buf, sizeof buf, "V%uBI", count) >= sizeof
>>>buf)
>>>+ {
>>>+ error ("%s:%d: number of vector elements is too high",
>>>+ file, line);
>>>+ return;
>>>+ }
>>>+
>>>+ struct mode_data *v = new_mode (MODE_VECTOR_BOOL,
>>>+ xstrdup (buf), file, line);
>>>+ v->component = m;
>>>+ v->ncomponents = count;
>>>+ v->bytesize = bytesize;
>>>+}
>>>+
>>> /* Input. */
>>>
>>> #define _SPECIAL_MODE(C, N) \
>>>@@ -1438,7 +1472,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 +1692,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 +1724,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 +1768,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:
>>>Index: gcc/lto-streamer-in.c
>>>===================================================================
>>>--- gcc/lto-streamer-in.c 2017-10-25 16:50:31.832332710 +0100
>>>+++ gcc/lto-streamer-in.c 2017-10-25 16:50:35.628184659 +0100
>>>@@ -1662,6 +1662,7 @@ lto_input_mode_table (struct lto_file_de
>>> {
>>> switch (mclass)
>>> {
>>>+ case MODE_VECTOR_BOOL:
>>> case MODE_VECTOR_INT:
>>> case MODE_VECTOR_FLOAT:
>>> case MODE_VECTOR_FRACT:
>>>Index: gcc/stor-layout.c
>>>===================================================================
>>>--- gcc/stor-layout.c 2017-10-25 16:50:24.925601288 +0100
>>>+++ gcc/stor-layout.c 2017-10-25 16:50:35.629184620 +0100
>>>@@ -378,12 +378,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:
>>>Index: gcc/tree.c
>>>===================================================================
>>>--- gcc/tree.c 2017-10-25 16:50:31.843332282 +0100
>>>+++ gcc/tree.c 2017-10-25 16:50:35.630184581 +0100
>>>@@ -10561,6 +10561,7 @@ build_vector_type_for_mode (tree innerty
>>>
>>> switch (GET_MODE_CLASS (mode))
>>> {
>>>+ case MODE_VECTOR_BOOL:
>>> case MODE_VECTOR_INT:
>>> case MODE_VECTOR_FLOAT:
>>> case MODE_VECTOR_FRACT:
>>>Index: gcc/varasm.c
>>>===================================================================
>>>--- gcc/varasm.c 2017-10-25 16:50:24.928601171 +0100
>>>+++ gcc/varasm.c 2017-10-25 16:50:35.631184542 +0100
>>>@@ -3926,6 +3926,32 @@ output_constant_pool_2 (fixed_size_mode
>>> 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 = CONST_VECTOR_NUNITS (x);
>>>+ 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:
>>>Index: gcc/emit-rtl.c
>>>===================================================================
>>>--- gcc/emit-rtl.c 2017-10-25 16:50:31.826332943 +0100
>>>+++ gcc/emit-rtl.c 2017-10-25 16:50:35.625184776 +0100
>>>@@ -5960,6 +5960,16 @@ gen_const_vec_duplicate_1 (machine_mode
>>> rtx
>>> gen_const_vec_duplicate (machine_mode mode, rtx elt)
>>> {
>>>+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
>>>+ {
>>>+ if (elt == const1_rtx || elt == constm1_rtx)
>>>+ return CONST1_RTX (mode);
>>>+ else if (elt == const0_rtx)
>>>+ return CONST0_RTX (mode);
>>>+ else
>>>+ gcc_unreachable ();
>>>+ }
>>>+
>>> scalar_mode inner_mode = GET_MODE_INNER (mode);
>>> if (elt == CONST0_RTX (inner_mode))
>>> return CONST0_RTX (mode);
>>>@@ -6284,6 +6294,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))
>>>@@ -6301,6 +6317,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);
>>>@@ -6402,10 +6427,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 ();
>>>Index: gcc/expr.c
>>>===================================================================
>>>--- gcc/expr.c 2017-10-25 16:50:31.827332904 +0100
>>>+++ gcc/expr.c 2017-10-25 16:50:35.627184698 +0100
>>>@@ -10053,12 +10053,7 @@ expand_expr_real_1 (tree exp, rtx target
>>> 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))
>>>Index: gcc/tree-vect-generic.c
>>>===================================================================
>>>--- gcc/tree-vect-generic.c 2017-10-25 16:50:25.047596556 +0100
>>>+++ gcc/tree-vect-generic.c 2017-10-25 16:50:35.629184620 +0100
>>>@@ -980,12 +980,7 @@ expand_vector_operation (gimple_stmt_ite
>>>/* 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:
>>>@@ -1174,6 +1169,8 @@ type_for_widest_vector_mode (tree type,
>>> 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;
>>>
>>>@@ -1531,12 +1528,7 @@ expand_vector_scalar_condition (gimple_s
>>>/* 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
>>>Index: gcc/c-family/c-common.c
>>>===================================================================
>>>--- gcc/c-family/c-common.c 2017-10-25 16:50:24.861603766 +0100
>>>+++ gcc/c-family/c-common.c 2017-10-25 16:50:35.625184776 +0100
>>>@@ -2281,6 +2281,14 @@ c_common_type_for_mode (machine_mode mod
>>> 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)))
>>> {
>>>Index: gcc/fortran/trans-types.c
>>>===================================================================
>>>--- gcc/fortran/trans-types.c 2017-10-25 16:50:24.869603456 +0100
>>>+++ gcc/fortran/trans-types.c 2017-10-25 16:50:35.627184698 +0100
>>>@@ -3159,6 +3159,14 @@ gfc_type_for_mode (machine_mode mode, in
>>>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)))
>>> {
>>>Index: gcc/go/go-lang.c
>>>===================================================================
>>>--- gcc/go/go-lang.c 2017-10-25 16:50:24.870603417 +0100
>>>+++ gcc/go/go-lang.c 2017-10-25 16:50:35.627184698 +0100
>>>@@ -372,9 +372,17 @@ go_langhook_type_for_mode (machine_mode
>>> 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);
>>>Index: gcc/lto/lto-lang.c
>>>===================================================================
>>>--- gcc/lto/lto-lang.c 2017-10-25 16:50:24.871603378 +0100
>>>+++ gcc/lto/lto-lang.c 2017-10-25 16:50:35.628184659 +0100
>>>@@ -971,6 +971,14 @@ lto_type_for_mode (machine_mode mode, in
>>> 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)))
>>> {