Message ID | 873782itg4.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | Make more use of opt_mode | expand |
On Mon, Sep 4, 2017 at 1:39 PM, Richard Sandiford <richard.sandiford@linaro.org> wrote: > ...following on from the mode_for_size change. The patch also removes > machmode.h versions of the stor-layout.c comments, since the comments > in the .c file are more complete. Ok. Richard. > 2017-09-04 Richard Sandiford <richard.sandiford@linaro.org> > > gcc/ > * machmode.h (mode_for_vector): Return an opt_mode. > * stor-layout.c (mode_for_vector): Likewise. > (mode_for_int_vector): Update accordingly. > (layout_type): Likewise. > * config/i386/i386.c (emit_memmov): Likewise. > (ix86_expand_set_or_movmem): Likewise. > (ix86_expand_vector_init): Likewise. > (ix86_get_mask_mode): Likewise. > * config/powerpcspe/powerpcspe.c (rs6000_expand_vec_perm_const_1): > Likewise. > * config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Likewise. > * expmed.c (extract_bit_field_1): Likewise. > * expr.c (expand_expr_real_2): Likewise. > * optabs-query.c (can_vec_perm_p): Likewise. > (can_vec_mask_load_store_p): Likewise. > * optabs.c (expand_vec_perm): Likewise. > * targhooks.c (default_get_mask_mode): Likewise. > * tree-vect-stmts.c (vectorizable_store): Likewise. > (vectorizable_load): Likewise. > (get_vectype_for_scalar_type_and_size): Likewise. > > Index: gcc/machmode.h > =================================================================== > --- gcc/machmode.h 2017-09-04 12:18:53.153306182 +0100 > +++ gcc/machmode.h 2017-09-04 12:18:55.821333642 +0100 > @@ -682,8 +682,6 @@ decimal_float_mode_for_size (unsigned in > (mode_for_size (size, MODE_DECIMAL_FLOAT, 0)); > } > > -/* Similar to mode_for_size, but find the smallest mode for a given width. */ > - > extern machine_mode smallest_mode_for_size (unsigned int, enum mode_class); > > /* Find the narrowest integer mode that contains at least SIZE bits. > @@ -695,17 +693,9 @@ smallest_int_mode_for_size (unsigned int > return as_a <scalar_int_mode> (smallest_mode_for_size (size, MODE_INT)); > } > > -/* Return an integer mode of exactly the same size as the input mode. */ > - > extern opt_scalar_int_mode int_mode_for_mode (machine_mode); > - > extern machine_mode bitwise_mode_for_mode (machine_mode); > - > -/* Return a mode that is suitable for representing a vector, > - or BLKmode on failure. */ > - > -extern machine_mode mode_for_vector (scalar_mode, unsigned); > - > +extern opt_machine_mode mode_for_vector (scalar_mode, unsigned); > extern opt_machine_mode mode_for_int_vector (unsigned int, unsigned int); > > /* Return the integer vector equivalent of MODE, if one exists. In other > Index: gcc/stor-layout.c > =================================================================== > --- gcc/stor-layout.c 2017-09-04 12:18:53.153306182 +0100 > +++ gcc/stor-layout.c 2017-09-04 12:18:55.824344959 +0100 > @@ -471,11 +471,11 @@ bitwise_type_for_mode (machine_mode mode > return inner_type; > } > > -/* Find a mode that is suitable for representing a vector with > - NUNITS elements of mode INNERMODE. Returns BLKmode if there > - is no suitable mode. */ > +/* Find a mode that is suitable for representing a vector with NUNITS > + elements of mode INNERMODE, if one exists. The returned mode can be > + either an integer mode or a vector mode. */ > > -machine_mode > +opt_machine_mode > mode_for_vector (scalar_mode innermode, unsigned nunits) > { > machine_mode mode; > @@ -499,22 +499,18 @@ mode_for_vector (scalar_mode innermode, > FOR_EACH_MODE_FROM (mode, mode) > if (GET_MODE_NUNITS (mode) == nunits > && GET_MODE_INNER (mode) == innermode) > - break; > + return mode; > > /* For integers, try mapping it to a same-sized scalar mode. */ > - if (mode == VOIDmode > - && GET_MODE_CLASS (innermode) == MODE_INT) > + if (GET_MODE_CLASS (innermode) == MODE_INT) > { > unsigned int nbits = nunits * GET_MODE_BITSIZE (innermode); > - mode = int_mode_for_size (nbits, 0).else_blk (); > + if (int_mode_for_size (nbits, 0).exists (&mode) > + && have_regs_of_mode[mode]) > + return mode; > } > > - if (mode == VOIDmode > - || (GET_MODE_CLASS (mode) == MODE_INT > - && !have_regs_of_mode[mode])) > - return BLKmode; > - > - return mode; > + return opt_machine_mode (); > } > > /* Return the mode for a vector that has NUNITS integer elements of > @@ -525,12 +521,10 @@ mode_for_vector (scalar_mode innermode, > mode_for_int_vector (unsigned int int_bits, unsigned int nunits) > { > scalar_int_mode int_mode; > - if (int_mode_for_size (int_bits, 0).exists (&int_mode)) > - { > - machine_mode vec_mode = mode_for_vector (int_mode, nunits); > - if (vec_mode != BLKmode) > - return vec_mode; > - } > + machine_mode vec_mode; > + if (int_mode_for_size (int_bits, 0).exists (&int_mode) > + && mode_for_vector (int_mode, nunits).exists (&vec_mode)) > + return vec_mode; > return opt_machine_mode (); > } > > @@ -2264,7 +2258,7 @@ layout_type (tree type) > if (TYPE_MODE (type) == VOIDmode) > SET_TYPE_MODE (type, > mode_for_vector (SCALAR_TYPE_MODE (innertype), > - nunits)); > + nunits).else_blk ()); > > TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type)); > TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type)); > Index: gcc/config/i386/i386.c > =================================================================== > --- gcc/config/i386/i386.c 2017-09-04 12:18:44.903326171 +0100 > +++ gcc/config/i386/i386.c 2017-09-04 12:18:55.808284598 +0100 > @@ -27420,9 +27420,8 @@ emit_memmov (rtx destmem, rtx *srcmem, r > if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode)) > { > int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode); > - move_mode = mode_for_vector (word_mode, nunits); > - code = optab_handler (mov_optab, move_mode); > - if (code == CODE_FOR_nothing) > + if (!mode_for_vector (word_mode, nunits).exists (&move_mode) > + || (code = optab_handler (mov_optab, move_mode)) == CODE_FOR_nothing) > { > move_mode = word_mode; > piece_size = GET_MODE_SIZE (move_mode); > @@ -28654,8 +28653,8 @@ ix86_expand_set_or_movmem (rtx dst, rtx > if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode)) > { > int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode); > - move_mode = mode_for_vector (word_mode, nunits); > - if (optab_handler (mov_optab, move_mode) == CODE_FOR_nothing) > + if (!mode_for_vector (word_mode, nunits).exists (&move_mode) > + || optab_handler (mov_optab, move_mode) == CODE_FOR_nothing) > move_mode = word_mode; > } > gcc_assert (optab_handler (mov_optab, move_mode) != CODE_FOR_nothing); > @@ -44497,11 +44496,9 @@ ix86_expand_vector_init (bool mmx_ok, rt > rtx ops[2] = { XVECEXP (vals, 0, 0), XVECEXP (vals, 0, 1) }; > if (inner_mode == QImode || inner_mode == HImode) > { > - mode = mode_for_vector (SImode, > - n_elts * GET_MODE_SIZE (inner_mode) / 4); > - inner_mode > - = mode_for_vector (SImode, > - n_elts * GET_MODE_SIZE (inner_mode) / 8); > + unsigned int n_bits = n_elts * GET_MODE_SIZE (inner_mode); > + mode = mode_for_vector (SImode, n_bits / 4).require (); > + inner_mode = mode_for_vector (SImode, n_bits / 8).require (); > ops[0] = gen_lowpart (inner_mode, ops[0]); > ops[1] = gen_lowpart (inner_mode, ops[1]); > subtarget = gen_reg_rtx (mode); > @@ -51619,7 +51616,7 @@ ix86_get_mask_mode (unsigned nunits, uns > > gcc_assert (elem_size * nunits == vector_size); > > - return mode_for_vector (elem_mode, nunits); > + return mode_for_vector (elem_mode, nunits).else_blk (); > } > > > Index: gcc/config/powerpcspe/powerpcspe.c > =================================================================== > --- gcc/config/powerpcspe/powerpcspe.c 2017-09-04 12:18:53.148287319 +0100 > +++ gcc/config/powerpcspe/powerpcspe.c 2017-09-04 12:18:55.812299689 +0100 > @@ -38679,7 +38679,7 @@ rs6000_expand_vec_perm_const_1 (rtx targ > > vmode = GET_MODE (target); > gcc_assert (GET_MODE_NUNITS (vmode) == 2); > - dmode = mode_for_vector (GET_MODE_INNER (vmode), 4); > + dmode = mode_for_vector (GET_MODE_INNER (vmode), 4).require (); > x = gen_rtx_VEC_CONCAT (dmode, op0, op1); > v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1)); > x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v)); > Index: gcc/config/rs6000/rs6000.c > =================================================================== > --- gcc/config/rs6000/rs6000.c 2017-09-04 12:18:53.151298637 +0100 > +++ gcc/config/rs6000/rs6000.c 2017-09-04 12:18:55.815311006 +0100 > @@ -35525,7 +35525,7 @@ rs6000_expand_vec_perm_const_1 (rtx targ > > vmode = GET_MODE (target); > gcc_assert (GET_MODE_NUNITS (vmode) == 2); > - dmode = mode_for_vector (GET_MODE_INNER (vmode), 4); > + dmode = mode_for_vector (GET_MODE_INNER (vmode), 4).require (); > x = gen_rtx_VEC_CONCAT (dmode, op0, op1); > v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1)); > x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v)); > Index: gcc/expmed.c > =================================================================== > --- gcc/expmed.c 2017-09-04 12:18:50.673054653 +0100 > +++ gcc/expmed.c 2017-09-04 12:18:55.817318551 +0100 > @@ -1578,10 +1578,11 @@ extract_bit_field_1 (rtx str_rtx, unsign > machine_mode new_mode = GET_MODE (op0); > if (GET_MODE_INNER (new_mode) != GET_MODE_INNER (tmode)) > { > - new_mode = mode_for_vector (GET_MODE_INNER (tmode), > - GET_MODE_BITSIZE (GET_MODE (op0)) > - / GET_MODE_UNIT_BITSIZE (tmode)); > - if (!VECTOR_MODE_P (new_mode) > + scalar_mode inner_mode = GET_MODE_INNER (tmode); > + unsigned int nunits = (GET_MODE_BITSIZE (GET_MODE (op0)) > + / GET_MODE_UNIT_BITSIZE (tmode)); > + if (!mode_for_vector (inner_mode, nunits).exists (&new_mode) > + || !VECTOR_MODE_P (new_mode) > || GET_MODE_SIZE (new_mode) != GET_MODE_SIZE (GET_MODE (op0)) > || GET_MODE_INNER (new_mode) != GET_MODE_INNER (tmode) > || !targetm.vector_mode_supported_p (new_mode)) > Index: gcc/expr.c > =================================================================== > --- gcc/expr.c 2017-09-04 12:18:44.938520082 +0100 > +++ gcc/expr.c 2017-09-04 12:18:55.820329869 +0100 > @@ -9445,7 +9445,7 @@ #define REDUCE_BIT_FIELD(expr) (reduce_b > tree sel_type = TREE_TYPE (treeop2); > machine_mode vmode > = mode_for_vector (SCALAR_TYPE_MODE (TREE_TYPE (sel_type)), > - TYPE_VECTOR_SUBPARTS (sel_type)); > + TYPE_VECTOR_SUBPARTS (sel_type)).require (); > gcc_assert (GET_MODE_CLASS (vmode) == MODE_VECTOR_INT); > op2 = simplify_subreg (vmode, op2, TYPE_MODE (sel_type), 0); > gcc_assert (op2 && GET_CODE (op2) == CONST_VECTOR); > Index: gcc/optabs-query.c > =================================================================== > --- gcc/optabs-query.c 2017-08-30 12:20:31.700622400 +0100 > +++ gcc/optabs-query.c 2017-09-04 12:18:55.821333642 +0100 > @@ -376,10 +376,9 @@ can_vec_perm_p (machine_mode mode, bool > return true; > > /* We allow fallback to a QI vector mode, and adjust the mask. */ > - if (GET_MODE_INNER (mode) == QImode) > - return false; > - qimode = mode_for_vector (QImode, GET_MODE_SIZE (mode)); > - if (!VECTOR_MODE_P (qimode)) > + if (GET_MODE_INNER (mode) == QImode > + || !mode_for_vector (QImode, GET_MODE_SIZE (mode)).exists (&qimode) > + || !VECTOR_MODE_P (qimode)) > return false; > > /* ??? For completeness, we ought to check the QImode version of > @@ -547,12 +546,14 @@ can_vec_mask_load_store_p (machine_mode > vector_sizes &= ~cur; > if (cur <= GET_MODE_SIZE (smode)) > continue; > - vmode = mode_for_vector (smode, cur / GET_MODE_SIZE (smode)); > - mask_mode = targetm.vectorize.get_mask_mode (GET_MODE_NUNITS (vmode), > - cur); > - if (VECTOR_MODE_P (vmode) > - && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing) > - return true; > + unsigned int nunits = cur / GET_MODE_SIZE (smode); > + if (mode_for_vector (smode, nunits).exists (&vmode) > + && VECTOR_MODE_P (vmode)) > + { > + mask_mode = targetm.vectorize.get_mask_mode (nunits, cur); > + if (convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing) > + return true; > + } > } > return false; > } > Index: gcc/optabs.c > =================================================================== > --- gcc/optabs.c 2017-09-04 11:48:08.609549644 +0100 > +++ gcc/optabs.c 2017-09-04 12:18:55.823341187 +0100 > @@ -5434,13 +5434,10 @@ expand_vec_perm (machine_mode mode, rtx > > /* Set QIMODE to a different vector mode with byte elements. > If no such mode, or if MODE already has byte elements, use VOIDmode. */ > - qimode = VOIDmode; > - if (GET_MODE_INNER (mode) != QImode) > - { > - qimode = mode_for_vector (QImode, w); > - if (!VECTOR_MODE_P (qimode)) > - qimode = VOIDmode; > - } > + if (GET_MODE_INNER (mode) == QImode > + || !mode_for_vector (QImode, w).exists (&qimode) > + || !VECTOR_MODE_P (qimode)) > + qimode = VOIDmode; > > /* If the input is a constant, expand it specially. */ > gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT); > Index: gcc/targhooks.c > =================================================================== > --- gcc/targhooks.c 2017-09-04 11:50:24.568774867 +0100 > +++ gcc/targhooks.c 2017-09-04 12:18:55.825348732 +0100 > @@ -1210,8 +1210,8 @@ default_get_mask_mode (unsigned nunits, > > gcc_assert (elem_size * nunits == vector_size); > > - vector_mode = mode_for_vector (elem_mode, nunits); > - if (!VECTOR_MODE_P (vector_mode) > + if (!mode_for_vector (elem_mode, nunits).exists (&vector_mode) > + || !VECTOR_MODE_P (vector_mode) > || !targetm.vector_mode_supported_p (vector_mode)) > vector_mode = BLKmode; > > Index: gcc/tree-vect-stmts.c > =================================================================== > --- gcc/tree-vect-stmts.c 2017-08-31 07:32:43.676061469 +0100 > +++ gcc/tree-vect-stmts.c 2017-09-04 12:18:55.828360049 +0100 > @@ -6032,8 +6032,9 @@ vectorizable_store (gimple *stmt, gimple > /* First check if vec_extract optab doesn't support extraction > of vector elts directly. */ > scalar_mode elmode = SCALAR_TYPE_MODE (elem_type); > - machine_mode vmode = mode_for_vector (elmode, group_size); > - if (! VECTOR_MODE_P (vmode) > + machine_mode vmode; > + if (!mode_for_vector (elmode, group_size).exists (&vmode) > + || !VECTOR_MODE_P (vmode) > || (convert_optab_handler (vec_extract_optab, > TYPE_MODE (vectype), vmode) > == CODE_FOR_nothing)) > @@ -6046,11 +6047,12 @@ vectorizable_store (gimple *stmt, gimple > unsigned lsize > = group_size * GET_MODE_BITSIZE (elmode); > elmode = int_mode_for_size (lsize, 0).require (); > - vmode = mode_for_vector (elmode, nunits / group_size); > /* If we can't construct such a vector fall back to > element extracts from the original vector type and > element size stores. */ > - if (VECTOR_MODE_P (vmode) > + if (mode_for_vector (elmode, > + nunits / group_size).exists (&vmode) > + && VECTOR_MODE_P (vmode) > && (convert_optab_handler (vec_extract_optab, > vmode, elmode) > != CODE_FOR_nothing)) > @@ -7070,8 +7072,9 @@ vectorizable_load (gimple *stmt, gimple_ > /* First check if vec_init optab supports construction from > vector elts directly. */ > scalar_mode elmode = SCALAR_TYPE_MODE (TREE_TYPE (vectype)); > - machine_mode vmode = mode_for_vector (elmode, group_size); > - if (VECTOR_MODE_P (vmode) > + machine_mode vmode; > + if (mode_for_vector (elmode, group_size).exists (&vmode) > + && VECTOR_MODE_P (vmode) > && (convert_optab_handler (vec_init_optab, > TYPE_MODE (vectype), vmode) > != CODE_FOR_nothing)) > @@ -7092,10 +7095,11 @@ vectorizable_load (gimple *stmt, gimple_ > unsigned lsize > = group_size * TYPE_PRECISION (TREE_TYPE (vectype)); > elmode = int_mode_for_size (lsize, 0).require (); > - vmode = mode_for_vector (elmode, nunits / group_size); > /* If we can't construct such a vector fall back to > element loads of the original vector type. */ > - if (VECTOR_MODE_P (vmode) > + if (mode_for_vector (elmode, > + nunits / group_size).exists (&vmode) > + && VECTOR_MODE_P (vmode) > && (convert_optab_handler (vec_init_optab, vmode, elmode) > != CODE_FOR_nothing)) > { > @@ -9098,8 +9102,8 @@ get_vectype_for_scalar_type_and_size (tr > lookup a vector mode of the specified size. */ > if (size == 0) > simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode); > - else > - simd_mode = mode_for_vector (inner_mode, size / nbytes); > + else if (!mode_for_vector (inner_mode, size / nbytes).exists (&simd_mode)) > + return NULL_TREE; > nunits = GET_MODE_SIZE (simd_mode) / nbytes; > /* NOTE: nunits == 1 is allowed to support single element vector types. */ > if (nunits < 1)
Index: gcc/machmode.h =================================================================== --- gcc/machmode.h 2017-09-04 12:18:53.153306182 +0100 +++ gcc/machmode.h 2017-09-04 12:18:55.821333642 +0100 @@ -682,8 +682,6 @@ decimal_float_mode_for_size (unsigned in (mode_for_size (size, MODE_DECIMAL_FLOAT, 0)); } -/* Similar to mode_for_size, but find the smallest mode for a given width. */ - extern machine_mode smallest_mode_for_size (unsigned int, enum mode_class); /* Find the narrowest integer mode that contains at least SIZE bits. @@ -695,17 +693,9 @@ smallest_int_mode_for_size (unsigned int return as_a <scalar_int_mode> (smallest_mode_for_size (size, MODE_INT)); } -/* Return an integer mode of exactly the same size as the input mode. */ - extern opt_scalar_int_mode int_mode_for_mode (machine_mode); - extern machine_mode bitwise_mode_for_mode (machine_mode); - -/* Return a mode that is suitable for representing a vector, - or BLKmode on failure. */ - -extern machine_mode mode_for_vector (scalar_mode, unsigned); - +extern opt_machine_mode mode_for_vector (scalar_mode, unsigned); extern opt_machine_mode mode_for_int_vector (unsigned int, unsigned int); /* Return the integer vector equivalent of MODE, if one exists. In other Index: gcc/stor-layout.c =================================================================== --- gcc/stor-layout.c 2017-09-04 12:18:53.153306182 +0100 +++ gcc/stor-layout.c 2017-09-04 12:18:55.824344959 +0100 @@ -471,11 +471,11 @@ bitwise_type_for_mode (machine_mode mode return inner_type; } -/* Find a mode that is suitable for representing a vector with - NUNITS elements of mode INNERMODE. Returns BLKmode if there - is no suitable mode. */ +/* Find a mode that is suitable for representing a vector with NUNITS + elements of mode INNERMODE, if one exists. The returned mode can be + either an integer mode or a vector mode. */ -machine_mode +opt_machine_mode mode_for_vector (scalar_mode innermode, unsigned nunits) { machine_mode mode; @@ -499,22 +499,18 @@ mode_for_vector (scalar_mode innermode, FOR_EACH_MODE_FROM (mode, mode) if (GET_MODE_NUNITS (mode) == nunits && GET_MODE_INNER (mode) == innermode) - break; + return mode; /* For integers, try mapping it to a same-sized scalar mode. */ - if (mode == VOIDmode - && GET_MODE_CLASS (innermode) == MODE_INT) + if (GET_MODE_CLASS (innermode) == MODE_INT) { unsigned int nbits = nunits * GET_MODE_BITSIZE (innermode); - mode = int_mode_for_size (nbits, 0).else_blk (); + if (int_mode_for_size (nbits, 0).exists (&mode) + && have_regs_of_mode[mode]) + return mode; } - if (mode == VOIDmode - || (GET_MODE_CLASS (mode) == MODE_INT - && !have_regs_of_mode[mode])) - return BLKmode; - - return mode; + return opt_machine_mode (); } /* Return the mode for a vector that has NUNITS integer elements of @@ -525,12 +521,10 @@ mode_for_vector (scalar_mode innermode, mode_for_int_vector (unsigned int int_bits, unsigned int nunits) { scalar_int_mode int_mode; - if (int_mode_for_size (int_bits, 0).exists (&int_mode)) - { - machine_mode vec_mode = mode_for_vector (int_mode, nunits); - if (vec_mode != BLKmode) - return vec_mode; - } + machine_mode vec_mode; + if (int_mode_for_size (int_bits, 0).exists (&int_mode) + && mode_for_vector (int_mode, nunits).exists (&vec_mode)) + return vec_mode; return opt_machine_mode (); } @@ -2264,7 +2258,7 @@ layout_type (tree type) if (TYPE_MODE (type) == VOIDmode) SET_TYPE_MODE (type, mode_for_vector (SCALAR_TYPE_MODE (innertype), - nunits)); + nunits).else_blk ()); TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type)); TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type)); Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2017-09-04 12:18:44.903326171 +0100 +++ gcc/config/i386/i386.c 2017-09-04 12:18:55.808284598 +0100 @@ -27420,9 +27420,8 @@ emit_memmov (rtx destmem, rtx *srcmem, r if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode)) { int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode); - move_mode = mode_for_vector (word_mode, nunits); - code = optab_handler (mov_optab, move_mode); - if (code == CODE_FOR_nothing) + if (!mode_for_vector (word_mode, nunits).exists (&move_mode) + || (code = optab_handler (mov_optab, move_mode)) == CODE_FOR_nothing) { move_mode = word_mode; piece_size = GET_MODE_SIZE (move_mode); @@ -28654,8 +28653,8 @@ ix86_expand_set_or_movmem (rtx dst, rtx if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode)) { int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode); - move_mode = mode_for_vector (word_mode, nunits); - if (optab_handler (mov_optab, move_mode) == CODE_FOR_nothing) + if (!mode_for_vector (word_mode, nunits).exists (&move_mode) + || optab_handler (mov_optab, move_mode) == CODE_FOR_nothing) move_mode = word_mode; } gcc_assert (optab_handler (mov_optab, move_mode) != CODE_FOR_nothing); @@ -44497,11 +44496,9 @@ ix86_expand_vector_init (bool mmx_ok, rt rtx ops[2] = { XVECEXP (vals, 0, 0), XVECEXP (vals, 0, 1) }; if (inner_mode == QImode || inner_mode == HImode) { - mode = mode_for_vector (SImode, - n_elts * GET_MODE_SIZE (inner_mode) / 4); - inner_mode - = mode_for_vector (SImode, - n_elts * GET_MODE_SIZE (inner_mode) / 8); + unsigned int n_bits = n_elts * GET_MODE_SIZE (inner_mode); + mode = mode_for_vector (SImode, n_bits / 4).require (); + inner_mode = mode_for_vector (SImode, n_bits / 8).require (); ops[0] = gen_lowpart (inner_mode, ops[0]); ops[1] = gen_lowpart (inner_mode, ops[1]); subtarget = gen_reg_rtx (mode); @@ -51619,7 +51616,7 @@ ix86_get_mask_mode (unsigned nunits, uns gcc_assert (elem_size * nunits == vector_size); - return mode_for_vector (elem_mode, nunits); + return mode_for_vector (elem_mode, nunits).else_blk (); } Index: gcc/config/powerpcspe/powerpcspe.c =================================================================== --- gcc/config/powerpcspe/powerpcspe.c 2017-09-04 12:18:53.148287319 +0100 +++ gcc/config/powerpcspe/powerpcspe.c 2017-09-04 12:18:55.812299689 +0100 @@ -38679,7 +38679,7 @@ rs6000_expand_vec_perm_const_1 (rtx targ vmode = GET_MODE (target); gcc_assert (GET_MODE_NUNITS (vmode) == 2); - dmode = mode_for_vector (GET_MODE_INNER (vmode), 4); + dmode = mode_for_vector (GET_MODE_INNER (vmode), 4).require (); x = gen_rtx_VEC_CONCAT (dmode, op0, op1); v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1)); x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v)); Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c 2017-09-04 12:18:53.151298637 +0100 +++ gcc/config/rs6000/rs6000.c 2017-09-04 12:18:55.815311006 +0100 @@ -35525,7 +35525,7 @@ rs6000_expand_vec_perm_const_1 (rtx targ vmode = GET_MODE (target); gcc_assert (GET_MODE_NUNITS (vmode) == 2); - dmode = mode_for_vector (GET_MODE_INNER (vmode), 4); + dmode = mode_for_vector (GET_MODE_INNER (vmode), 4).require (); x = gen_rtx_VEC_CONCAT (dmode, op0, op1); v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1)); x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v)); Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2017-09-04 12:18:50.673054653 +0100 +++ gcc/expmed.c 2017-09-04 12:18:55.817318551 +0100 @@ -1578,10 +1578,11 @@ extract_bit_field_1 (rtx str_rtx, unsign machine_mode new_mode = GET_MODE (op0); if (GET_MODE_INNER (new_mode) != GET_MODE_INNER (tmode)) { - new_mode = mode_for_vector (GET_MODE_INNER (tmode), - GET_MODE_BITSIZE (GET_MODE (op0)) - / GET_MODE_UNIT_BITSIZE (tmode)); - if (!VECTOR_MODE_P (new_mode) + scalar_mode inner_mode = GET_MODE_INNER (tmode); + unsigned int nunits = (GET_MODE_BITSIZE (GET_MODE (op0)) + / GET_MODE_UNIT_BITSIZE (tmode)); + if (!mode_for_vector (inner_mode, nunits).exists (&new_mode) + || !VECTOR_MODE_P (new_mode) || GET_MODE_SIZE (new_mode) != GET_MODE_SIZE (GET_MODE (op0)) || GET_MODE_INNER (new_mode) != GET_MODE_INNER (tmode) || !targetm.vector_mode_supported_p (new_mode)) Index: gcc/expr.c =================================================================== --- gcc/expr.c 2017-09-04 12:18:44.938520082 +0100 +++ gcc/expr.c 2017-09-04 12:18:55.820329869 +0100 @@ -9445,7 +9445,7 @@ #define REDUCE_BIT_FIELD(expr) (reduce_b tree sel_type = TREE_TYPE (treeop2); machine_mode vmode = mode_for_vector (SCALAR_TYPE_MODE (TREE_TYPE (sel_type)), - TYPE_VECTOR_SUBPARTS (sel_type)); + TYPE_VECTOR_SUBPARTS (sel_type)).require (); gcc_assert (GET_MODE_CLASS (vmode) == MODE_VECTOR_INT); op2 = simplify_subreg (vmode, op2, TYPE_MODE (sel_type), 0); gcc_assert (op2 && GET_CODE (op2) == CONST_VECTOR); Index: gcc/optabs-query.c =================================================================== --- gcc/optabs-query.c 2017-08-30 12:20:31.700622400 +0100 +++ gcc/optabs-query.c 2017-09-04 12:18:55.821333642 +0100 @@ -376,10 +376,9 @@ can_vec_perm_p (machine_mode mode, bool return true; /* We allow fallback to a QI vector mode, and adjust the mask. */ - if (GET_MODE_INNER (mode) == QImode) - return false; - qimode = mode_for_vector (QImode, GET_MODE_SIZE (mode)); - if (!VECTOR_MODE_P (qimode)) + if (GET_MODE_INNER (mode) == QImode + || !mode_for_vector (QImode, GET_MODE_SIZE (mode)).exists (&qimode) + || !VECTOR_MODE_P (qimode)) return false; /* ??? For completeness, we ought to check the QImode version of @@ -547,12 +546,14 @@ can_vec_mask_load_store_p (machine_mode vector_sizes &= ~cur; if (cur <= GET_MODE_SIZE (smode)) continue; - vmode = mode_for_vector (smode, cur / GET_MODE_SIZE (smode)); - mask_mode = targetm.vectorize.get_mask_mode (GET_MODE_NUNITS (vmode), - cur); - if (VECTOR_MODE_P (vmode) - && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing) - return true; + unsigned int nunits = cur / GET_MODE_SIZE (smode); + if (mode_for_vector (smode, nunits).exists (&vmode) + && VECTOR_MODE_P (vmode)) + { + mask_mode = targetm.vectorize.get_mask_mode (nunits, cur); + if (convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing) + return true; + } } return false; } Index: gcc/optabs.c =================================================================== --- gcc/optabs.c 2017-09-04 11:48:08.609549644 +0100 +++ gcc/optabs.c 2017-09-04 12:18:55.823341187 +0100 @@ -5434,13 +5434,10 @@ expand_vec_perm (machine_mode mode, rtx /* Set QIMODE to a different vector mode with byte elements. If no such mode, or if MODE already has byte elements, use VOIDmode. */ - qimode = VOIDmode; - if (GET_MODE_INNER (mode) != QImode) - { - qimode = mode_for_vector (QImode, w); - if (!VECTOR_MODE_P (qimode)) - qimode = VOIDmode; - } + if (GET_MODE_INNER (mode) == QImode + || !mode_for_vector (QImode, w).exists (&qimode) + || !VECTOR_MODE_P (qimode)) + qimode = VOIDmode; /* If the input is a constant, expand it specially. */ gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT); Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c 2017-09-04 11:50:24.568774867 +0100 +++ gcc/targhooks.c 2017-09-04 12:18:55.825348732 +0100 @@ -1210,8 +1210,8 @@ default_get_mask_mode (unsigned nunits, gcc_assert (elem_size * nunits == vector_size); - vector_mode = mode_for_vector (elem_mode, nunits); - if (!VECTOR_MODE_P (vector_mode) + if (!mode_for_vector (elem_mode, nunits).exists (&vector_mode) + || !VECTOR_MODE_P (vector_mode) || !targetm.vector_mode_supported_p (vector_mode)) vector_mode = BLKmode; Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-08-31 07:32:43.676061469 +0100 +++ gcc/tree-vect-stmts.c 2017-09-04 12:18:55.828360049 +0100 @@ -6032,8 +6032,9 @@ vectorizable_store (gimple *stmt, gimple /* First check if vec_extract optab doesn't support extraction of vector elts directly. */ scalar_mode elmode = SCALAR_TYPE_MODE (elem_type); - machine_mode vmode = mode_for_vector (elmode, group_size); - if (! VECTOR_MODE_P (vmode) + machine_mode vmode; + if (!mode_for_vector (elmode, group_size).exists (&vmode) + || !VECTOR_MODE_P (vmode) || (convert_optab_handler (vec_extract_optab, TYPE_MODE (vectype), vmode) == CODE_FOR_nothing)) @@ -6046,11 +6047,12 @@ vectorizable_store (gimple *stmt, gimple unsigned lsize = group_size * GET_MODE_BITSIZE (elmode); elmode = int_mode_for_size (lsize, 0).require (); - vmode = mode_for_vector (elmode, nunits / group_size); /* If we can't construct such a vector fall back to element extracts from the original vector type and element size stores. */ - if (VECTOR_MODE_P (vmode) + if (mode_for_vector (elmode, + nunits / group_size).exists (&vmode) + && VECTOR_MODE_P (vmode) && (convert_optab_handler (vec_extract_optab, vmode, elmode) != CODE_FOR_nothing)) @@ -7070,8 +7072,9 @@ vectorizable_load (gimple *stmt, gimple_ /* First check if vec_init optab supports construction from vector elts directly. */ scalar_mode elmode = SCALAR_TYPE_MODE (TREE_TYPE (vectype)); - machine_mode vmode = mode_for_vector (elmode, group_size); - if (VECTOR_MODE_P (vmode) + machine_mode vmode; + if (mode_for_vector (elmode, group_size).exists (&vmode) + && VECTOR_MODE_P (vmode) && (convert_optab_handler (vec_init_optab, TYPE_MODE (vectype), vmode) != CODE_FOR_nothing)) @@ -7092,10 +7095,11 @@ vectorizable_load (gimple *stmt, gimple_ unsigned lsize = group_size * TYPE_PRECISION (TREE_TYPE (vectype)); elmode = int_mode_for_size (lsize, 0).require (); - vmode = mode_for_vector (elmode, nunits / group_size); /* If we can't construct such a vector fall back to element loads of the original vector type. */ - if (VECTOR_MODE_P (vmode) + if (mode_for_vector (elmode, + nunits / group_size).exists (&vmode) + && VECTOR_MODE_P (vmode) && (convert_optab_handler (vec_init_optab, vmode, elmode) != CODE_FOR_nothing)) { @@ -9098,8 +9102,8 @@ get_vectype_for_scalar_type_and_size (tr lookup a vector mode of the specified size. */ if (size == 0) simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode); - else - simd_mode = mode_for_vector (inner_mode, size / nbytes); + else if (!mode_for_vector (inner_mode, size / nbytes).exists (&simd_mode)) + return NULL_TREE; nunits = GET_MODE_SIZE (simd_mode) / nbytes; /* NOTE: nunits == 1 is allowed to support single element vector types. */ if (nunits < 1)