On October 25, 2017 6:05:48 PM GMT+02:00, Richard Sandiford <richard.sandif...@linaro.org> wrote: >Richard Biener <richard.guent...@gmail.com> writes: >> On October 25, 2017 5:54:02 PM GMT+02:00, Richard Sandiford >> <richard.sandif...@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.sandif...@linaro.org> >>> Alan Hayward <alan.hayw...@arm.com> >>> David Sherwood <david.sherw...@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))) >>> {