Also use int_mode_for_mode instead of (int_)mode_for_size in cases where the requested size was the bitsize of an existing mode.
2017-07-13 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> gcc/ * machmode.h (opt_mode::else_blk): New function. (int_mode_for_mode): Declare. * stor-layout.c (int_mode_for_mode): Return an opt_scalar_int_mode. * builtins.c (expand_builtin_signbit): Adjust for new int_mode_for_mode return type. * cfgexpand.c (expand_debug_expr): Likewise. * combine.c (gen_lowpart_or_truncate): Likewise. (gen_lowpart_for_combine): Likewise. * config/aarch64/aarch64.c (aarch64_emit_approx_sqrt): Likewise. * config/avr/avr.c (avr_to_int_mode): Likewise. (avr_out_plus_1): Likewise. (avr_out_plus): Likewise. (avr_out_round): Likewise. * config/i386/i386.c (ix86_split_to_parts): Likewise. * config/powerpcspe/powerpcspe.c (rs6000_do_expand_vec_perm): Likewise. * config/rs6000/rs6000.c (rs6000_do_expand_vec_perm): Likewise. * config/s390/s390.c (s390_expand_vec_compare_cc): Likewise. (s390_expand_vcond): Likewise. * config/spu/spu.c (spu_split_immediate): Likewise. (spu_expand_mov): Likewise. * dse.c (get_stored_val): Likewise. * expmed.c (store_bit_field_1): Likewise. (convert_extracted_bit_field): Use int_mode_for_mode instead of int_mode_for_size. (extract_bit_field_1): Adjust for new int_mode_for_mode return type. (extract_low_bits): Likewise. * expr.c (emit_group_load_1): Likewise. Separate out the BLKmode handling rather than repeating the check. (emit_group_store): Likewise. (emit_move_via_integer): Adjust for new int_mode_for_mode return type. * optabs.c (expand_absneg_bit): Likewise. (expand_copysign_absneg): Likewise. (expand_copysign_bit): Likewise. * tree-if-conv.c (ifcvt_can_use_mask_load_store): Likewise. * tree-vect-slp.c (vect_transform_slp_perm_load): Likewise. * tree-vect-stmts.c (vect_gen_perm_mask_any): Likewise. * var-tracking.c (prepare_call_arguments): Likewise. * config/powerpcspe/powerpcspe.c (rs6000_do_expand_vec_perm): Use int_mode_for_mode instead of mode_for_size. * config/rs6000/rs6000.c (rs6000_do_expand_vec_perm): Likewise. Index: gcc/machmode.h =================================================================== --- gcc/machmode.h 2017-07-13 09:18:29.217658709 +0100 +++ gcc/machmode.h 2017-07-13 09:18:30.083577588 +0100 @@ -241,6 +241,7 @@ #define POINTER_BOUNDS_MODE_P(MODE) ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {} machine_mode else_void () const; + machine_mode else_blk () const; T operator * () const; bool exists () const; @@ -260,6 +261,15 @@ opt_mode<T>::else_void () const return m_mode; } +/* If the T exists, return its enum value, otherwise return E_BLKmode. */ + +template<typename T> +inline machine_mode +opt_mode<T>::else_blk () const +{ + return m_mode == E_VOIDmode ? E_BLKmode : m_mode; +} + /* Assert that the object contains a T and return it. */ template<typename T> @@ -583,10 +593,9 @@ extern machine_mode smallest_mode_for_si enum mode_class); -/* Return an integer mode of the exact same size as the input mode, - or BLKmode on failure. */ +/* Return an integer mode of exactly the same size as the input mode. */ -extern machine_mode int_mode_for_mode (machine_mode); +extern opt_scalar_int_mode int_mode_for_mode (machine_mode); extern machine_mode bitwise_mode_for_mode (machine_mode); Index: gcc/stor-layout.c =================================================================== --- gcc/stor-layout.c 2017-07-13 09:18:29.219658521 +0100 +++ gcc/stor-layout.c 2017-07-13 09:18:30.086577310 +0100 @@ -364,16 +364,16 @@ smallest_mode_for_size (unsigned int siz return mode; } -/* Find an integer mode of the exact same size, or BLKmode on failure. */ +/* Return an integer mode of exactly the same size as MODE, if one exists. */ -machine_mode +opt_scalar_int_mode int_mode_for_mode (machine_mode mode) { switch (GET_MODE_CLASS (mode)) { case MODE_INT: case MODE_PARTIAL_INT: - break; + return as_a <scalar_int_mode> (mode); case MODE_COMPLEX_INT: case MODE_COMPLEX_FLOAT: @@ -390,12 +390,11 @@ int_mode_for_mode (machine_mode mode) case MODE_VECTOR_UFRACT: case MODE_VECTOR_UACCUM: case MODE_POINTER_BOUNDS: - mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0); - break; + return int_mode_for_size (GET_MODE_BITSIZE (mode), 0); case MODE_RANDOM: if (mode == BLKmode) - break; + return opt_scalar_int_mode (); /* fall through */ @@ -403,8 +402,6 @@ int_mode_for_mode (machine_mode mode) default: gcc_unreachable (); } - - return mode; } /* Find a mode that can be used for efficient bitwise operations on MODE. Index: gcc/builtins.c =================================================================== --- gcc/builtins.c 2017-07-13 09:18:29.209659459 +0100 +++ gcc/builtins.c 2017-07-13 09:18:30.027582784 +0100 @@ -5413,8 +5413,7 @@ expand_builtin_signbit (tree exp, rtx ta if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD) { - imode = int_mode_for_mode (fmode); - gcc_assert (imode != BLKmode); + imode = *int_mode_for_mode (fmode); temp = gen_lowpart (imode, temp); } else Index: gcc/cfgexpand.c =================================================================== --- gcc/cfgexpand.c 2017-07-08 11:37:46.573465901 +0100 +++ gcc/cfgexpand.c 2017-07-13 09:18:30.028582691 +0100 @@ -4836,10 +4836,11 @@ expand_debug_expr (tree exp) } else { - machine_mode ifmode = int_mode_for_mode (mode); - machine_mode ihmode = int_mode_for_mode (imode); + scalar_int_mode ifmode; + scalar_int_mode ihmode; rtx halfsize; - if (ifmode == BLKmode || ihmode == BLKmode) + if (!int_mode_for_mode (mode).exists (&ifmode) + || !int_mode_for_mode (imode).exists (&ihmode)) return NULL; halfsize = GEN_INT (GET_MODE_BITSIZE (ihmode)); re = op0; Index: gcc/combine.c =================================================================== --- gcc/combine.c 2017-07-13 09:18:29.211659271 +0100 +++ gcc/combine.c 2017-07-13 09:18:30.031582413 +0100 @@ -8444,8 +8444,8 @@ gen_lowpart_or_truncate (machine_mode mo { /* Bit-cast X into an integer mode. */ if (!SCALAR_INT_MODE_P (GET_MODE (x))) - x = gen_lowpart (int_mode_for_mode (GET_MODE (x)), x); - x = simplify_gen_unary (TRUNCATE, int_mode_for_mode (mode), + x = gen_lowpart (*int_mode_for_mode (GET_MODE (x)), x); + x = simplify_gen_unary (TRUNCATE, *int_mode_for_mode (mode), x, GET_MODE (x)); } @@ -11519,7 +11519,7 @@ gen_lowpart_for_combine (machine_mode om if (imode == VOIDmode) { - imode = int_mode_for_mode (omode); + imode = *int_mode_for_mode (omode); x = gen_lowpart_common (imode, x); if (x == NULL) goto fail; Index: gcc/config/aarch64/aarch64.c =================================================================== --- gcc/config/aarch64/aarch64.c 2017-07-13 09:18:27.465825060 +0100 +++ gcc/config/aarch64/aarch64.c 2017-07-13 09:18:30.033582228 +0100 @@ -8148,7 +8148,7 @@ aarch64_emit_approx_sqrt (rtx dst, rtx s } machine_mode mmsk - = mode_for_vector (int_mode_for_mode (GET_MODE_INNER (mode)), + = mode_for_vector (*int_mode_for_mode (GET_MODE_INNER (mode)), GET_MODE_NUNITS (mode)); if (!recp) { Index: gcc/config/avr/avr.c =================================================================== --- gcc/config/avr/avr.c 2017-07-13 09:18:19.036703514 +0100 +++ gcc/config/avr/avr.c 2017-07-13 09:18:30.035582042 +0100 @@ -283,7 +283,7 @@ avr_to_int_mode (rtx x) return VOIDmode == mode ? x - : simplify_gen_subreg (int_mode_for_mode (mode), x, mode, 0); + : simplify_gen_subreg (*int_mode_for_mode (mode), x, mode, 0); } namespace { @@ -7737,7 +7737,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enu machine_mode mode = GET_MODE (xop[0]); /* INT_MODE of the same size. */ - machine_mode imode = int_mode_for_mode (mode); + scalar_int_mode imode = *int_mode_for_mode (mode); /* Number of bytes to operate on. */ int n_bytes = GET_MODE_SIZE (mode); @@ -8240,7 +8240,7 @@ avr_out_plus (rtx insn, rtx *xop, int *p rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn; rtx xdest = SET_DEST (xpattern); machine_mode mode = GET_MODE (xdest); - machine_mode imode = int_mode_for_mode (mode); + scalar_int_mode imode = *int_mode_for_mode (mode); int n_bytes = GET_MODE_SIZE (mode); enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern)); enum rtx_code code @@ -9175,7 +9175,7 @@ #define MAY_CLOBBER(RR) avr_out_round (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *xop, int *plen) { machine_mode mode = GET_MODE (xop[0]); - machine_mode imode = int_mode_for_mode (mode); + scalar_int_mode imode = *int_mode_for_mode (mode); // The smallest fractional bit not cleared by the rounding is 2^(-RP). int fbit = (int) GET_MODE_FBIT (mode); double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2])); Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2017-07-13 09:18:22.921279344 +0100 +++ gcc/config/i386/i386.c 2017-07-13 09:18:30.054580279 +0100 @@ -26215,7 +26215,7 @@ ix86_split_to_parts (rtx operand, rtx *p if (GET_CODE (operand) == CONST_VECTOR) { - machine_mode imode = int_mode_for_mode (mode); + scalar_int_mode imode = *int_mode_for_mode (mode); /* Caution: if we looked through a constant pool memory above, the operand may actually have a different mode now. That's ok, since we want to pun this all the way back to an integer. */ Index: gcc/config/powerpcspe/powerpcspe.c =================================================================== --- gcc/config/powerpcspe/powerpcspe.c 2017-07-13 09:18:28.017772208 +0100 +++ gcc/config/powerpcspe/powerpcspe.c 2017-07-13 09:18:30.062579537 +0100 @@ -38666,10 +38666,8 @@ rs6000_do_expand_vec_perm (rtx target, r imode = vmode; if (GET_MODE_CLASS (vmode) != MODE_VECTOR_INT) - { - imode = mode_for_size (GET_MODE_UNIT_BITSIZE (vmode), MODE_INT, 0); - imode = mode_for_vector (imode, nelt); - } + imode = mode_for_vector (*int_mode_for_mode (GET_MODE_INNER (vmode)), + nelt); x = gen_rtx_CONST_VECTOR (imode, gen_rtvec_v (nelt, perm)); x = expand_vec_perm (vmode, op0, op1, x, target); Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c 2017-07-13 09:18:28.021771829 +0100 +++ gcc/config/rs6000/rs6000.c 2017-07-13 09:18:30.071578702 +0100 @@ -35748,10 +35748,8 @@ rs6000_do_expand_vec_perm (rtx target, r imode = vmode; if (GET_MODE_CLASS (vmode) != MODE_VECTOR_INT) - { - imode = mode_for_size (GET_MODE_UNIT_BITSIZE (vmode), MODE_INT, 0); - imode = mode_for_vector (imode, nelt); - } + imode = mode_for_vector (*int_mode_for_mode (GET_MODE_INNER (vmode)), + nelt); x = gen_rtx_CONST_VECTOR (imode, gen_rtvec_v (nelt, perm)); x = expand_vec_perm (vmode, op0, op1, x, target); Index: gcc/config/s390/s390.c =================================================================== --- gcc/config/s390/s390.c 2017-07-13 09:18:28.023771640 +0100 +++ gcc/config/s390/s390.c 2017-07-13 09:18:30.075578330 +0100 @@ -6464,7 +6464,7 @@ s390_expand_vec_compare_cc (rtx target, default: gcc_unreachable (); } scratch_mode = mode_for_vector ( - int_mode_for_mode (GET_MODE_INNER (GET_MODE (cmp1))), + *int_mode_for_mode (GET_MODE_INNER (GET_MODE (cmp1))), GET_MODE_NUNITS (GET_MODE (cmp1))); gcc_assert (scratch_mode != BLKmode); @@ -6572,8 +6572,9 @@ s390_expand_vcond (rtx target, rtx then, /* We always use an integral type vector to hold the comparison result. */ - result_mode = mode_for_vector (int_mode_for_mode (GET_MODE_INNER (cmp_mode)), - GET_MODE_NUNITS (cmp_mode)); + result_mode + = mode_for_vector (*int_mode_for_mode (GET_MODE_INNER (cmp_mode)), + GET_MODE_NUNITS (cmp_mode)); result_target = gen_reg_rtx (result_mode); /* We allow vector immediates as comparison operands that Index: gcc/config/spu/spu.c =================================================================== --- gcc/config/spu/spu.c 2017-07-13 09:18:19.136692428 +0100 +++ gcc/config/spu/spu.c 2017-07-13 09:18:30.077578145 +0100 @@ -1492,10 +1492,9 @@ spu_split_immediate (rtx * ops) unsigned char arrlo[16]; rtx to, temp, hi, lo; int i; - machine_mode imode = mode; /* We need to do reals as ints because the constant used in the IOR might not be a legitimate real constant. */ - imode = int_mode_for_mode (mode); + scalar_int_mode imode = *int_mode_for_mode (mode); constant_to_array (mode, ops[1], arrhi); if (imode != mode) to = simplify_gen_subreg (imode, ops[0], mode, 0); @@ -1521,10 +1520,9 @@ spu_split_immediate (rtx * ops) unsigned char arr_andbi[16]; rtx to, reg_fsmbi, reg_and; int i; - machine_mode imode = mode; /* We need to do reals as ints because the constant used in the * AND might not be a legitimate real constant. */ - imode = int_mode_for_mode (mode); + scalar_int_mode imode = *int_mode_for_mode (mode); constant_to_array (mode, ops[1], arr_fsmbi); if (imode != mode) to = simplify_gen_subreg(imode, ops[0], GET_MODE (ops[0]), 0); @@ -4429,7 +4427,7 @@ spu_expand_mov (rtx * ops, machine_mode if (GET_CODE (ops[1]) == SUBREG && !valid_subreg (ops[1])) { rtx from = SUBREG_REG (ops[1]); - machine_mode imode = int_mode_for_mode (GET_MODE (from)); + scalar_int_mode imode = *int_mode_for_mode (GET_MODE (from)); gcc_assert (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_CLASS (imode) == MODE_INT Index: gcc/dse.c =================================================================== --- gcc/dse.c 2017-07-13 09:18:21.530429366 +0100 +++ gcc/dse.c 2017-07-13 09:18:30.078578052 +0100 @@ -1734,12 +1734,12 @@ get_stored_val (store_info *store_info, { /* The store is a memset (addr, const_val, const_size). */ gcc_assert (CONST_INT_P (store_info->rhs)); - store_mode = int_mode_for_mode (read_mode); - if (store_mode == BLKmode) + scalar_int_mode int_store_mode; + if (!int_mode_for_mode (read_mode).exists (&int_store_mode)) read_reg = NULL_RTX; else if (store_info->rhs == const0_rtx) - read_reg = extract_low_bits (read_mode, store_mode, const0_rtx); - else if (GET_MODE_BITSIZE (store_mode) > HOST_BITS_PER_WIDE_INT + read_reg = extract_low_bits (read_mode, int_store_mode, const0_rtx); + else if (GET_MODE_BITSIZE (int_store_mode) > HOST_BITS_PER_WIDE_INT || BITS_PER_UNIT >= HOST_BITS_PER_WIDE_INT) read_reg = NULL_RTX; else @@ -1753,8 +1753,8 @@ get_stored_val (store_info *store_info, c |= (c << shift); shift <<= 1; } - read_reg = gen_int_mode (c, store_mode); - read_reg = extract_low_bits (read_mode, store_mode, read_reg); + read_reg = gen_int_mode (c, int_store_mode); + read_reg = extract_low_bits (read_mode, int_store_mode, read_reg); } } else if (store_info->const_rhs Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2017-07-13 09:18:29.215658896 +0100 +++ gcc/expmed.c 2017-07-13 09:18:30.080577867 +0100 @@ -828,19 +828,15 @@ store_bit_field_1 (rtx str_rtx, unsigned if we aren't. This must come after the entire register case above, since that case is valid for any mode. The following cases are only valid for integral modes. */ - { - machine_mode imode = int_mode_for_mode (GET_MODE (op0)); - if (imode != GET_MODE (op0)) - { - if (MEM_P (op0)) - op0 = adjust_bitfield_address_size (op0, imode, 0, MEM_SIZE (op0)); - else - { - gcc_assert (imode != BLKmode); - op0 = gen_lowpart (imode, op0); - } - } - } + opt_scalar_int_mode imode = int_mode_for_mode (GET_MODE (op0)); + if (!imode.exists () || *imode != GET_MODE (op0)) + { + if (MEM_P (op0)) + op0 = adjust_bitfield_address_size (op0, imode.else_blk (), + 0, MEM_SIZE (op0)); + else + op0 = gen_lowpart (*imode, op0); + } /* Storing an lsb-aligned field in a register can be done with a movstrict instruction. */ @@ -955,7 +951,7 @@ store_bit_field_1 (rtx str_rtx, unsigned && GET_MODE_CLASS (GET_MODE (value)) != MODE_INT && GET_MODE_CLASS (GET_MODE (value)) != MODE_PARTIAL_INT) { - value = gen_reg_rtx (int_mode_for_mode (GET_MODE (value))); + value = gen_reg_rtx (*int_mode_for_mode (GET_MODE (value))); emit_move_insn (gen_lowpart (GET_MODE (orig_value), value), orig_value); } @@ -1425,8 +1421,7 @@ convert_extracted_bit_field (rtx x, mach value via a SUBREG. */ if (!SCALAR_INT_MODE_P (tmode)) { - scalar_int_mode int_mode - = *int_mode_for_size (GET_MODE_BITSIZE (tmode), 0); + scalar_int_mode int_mode = *int_mode_for_mode (tmode); x = convert_to_mode (int_mode, x, unsignedp); x = force_reg (int_mode, x); return gen_lowpart (tmode, x); @@ -1531,7 +1526,6 @@ extract_bit_field_1 (rtx str_rtx, unsign bool reverse, bool fallback_p, rtx *alt_rtl) { rtx op0 = str_rtx; - machine_mode int_mode; machine_mode mode1; if (tmode == VOIDmode) @@ -1620,30 +1614,29 @@ extract_bit_field_1 (rtx str_rtx, unsign /* Make sure we are playing with integral modes. Pun with subregs if we aren't. */ - { - machine_mode imode = int_mode_for_mode (GET_MODE (op0)); - if (imode != GET_MODE (op0)) - { - if (MEM_P (op0)) - op0 = adjust_bitfield_address_size (op0, imode, 0, MEM_SIZE (op0)); - else if (imode != BLKmode) - { - op0 = gen_lowpart (imode, op0); - - /* If we got a SUBREG, force it into a register since we - aren't going to be able to do another SUBREG on it. */ - if (GET_CODE (op0) == SUBREG) - op0 = force_reg (imode, op0); - } - else - { - HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (op0)); - rtx mem = assign_stack_temp (GET_MODE (op0), size); - emit_move_insn (mem, op0); - op0 = adjust_bitfield_address_size (mem, BLKmode, 0, size); - } - } - } + opt_scalar_int_mode imode = int_mode_for_mode (GET_MODE (op0)); + if (!imode.exists () || *imode != GET_MODE (op0)) + { + if (MEM_P (op0)) + op0 = adjust_bitfield_address_size (op0, imode.else_blk (), + 0, MEM_SIZE (op0)); + else if (imode.exists ()) + { + op0 = gen_lowpart (*imode, op0); + + /* If we got a SUBREG, force it into a register since we + aren't going to be able to do another SUBREG on it. */ + if (GET_CODE (op0) == SUBREG) + op0 = force_reg (*imode, op0); + } + else + { + HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (op0)); + rtx mem = assign_stack_temp (GET_MODE (op0), size); + emit_move_insn (mem, op0); + op0 = adjust_bitfield_address_size (mem, BLKmode, 0, size); + } + } /* ??? We currently assume TARGET is at least as big as BITSIZE. If that's wrong, the solution is to test for it and set TARGET to 0 @@ -1847,11 +1840,11 @@ extract_bit_field_1 (rtx str_rtx, unsign /* Find a correspondingly-sized integer field, so we can apply shifts and masks to it. */ - int_mode = int_mode_for_mode (tmode); - if (int_mode == BLKmode) - int_mode = int_mode_for_mode (mode); - /* Should probably push op0 out to memory and then do a load. */ - gcc_assert (int_mode != BLKmode); + scalar_int_mode int_mode; + if (!int_mode_for_mode (tmode).exists (&int_mode)) + /* If this fails, we should probably push op0 out to memory and then + do a load. */ + int_mode = *int_mode_for_mode (mode); target = extract_fixed_bit_field (int_mode, op0, bitsize, bitnum, target, unsignedp, reverse); @@ -2206,9 +2199,8 @@ extract_low_bits (machine_mode mode, mac return x; } - src_int_mode = int_mode_for_mode (src_mode); - int_mode = int_mode_for_mode (mode); - if (src_int_mode == BLKmode || int_mode == BLKmode) + if (!int_mode_for_mode (src_mode).exists (&src_int_mode) + || !int_mode_for_mode (mode).exists (&int_mode)) return NULL_RTX; if (!MODES_TIEABLE_P (src_int_mode, src_mode)) Index: gcc/expr.c =================================================================== --- gcc/expr.c 2017-07-13 09:18:29.216658803 +0100 +++ gcc/expr.c 2017-07-13 09:18:30.083577588 +0100 @@ -2094,17 +2094,17 @@ emit_group_load_1 (rtx *tmps, rtx dst, r && !MEM_P (orig_src) && GET_CODE (orig_src) != CONCAT) { - machine_mode imode = int_mode_for_mode (GET_MODE (orig_src)); - if (imode == BLKmode) - src = assign_stack_temp (GET_MODE (orig_src), ssize); + scalar_int_mode imode; + if (int_mode_for_mode (GET_MODE (orig_src)).exists (&imode)) + { + src = gen_reg_rtx (imode); + emit_move_insn (gen_lowpart (GET_MODE (orig_src), src), orig_src); + } else - src = gen_reg_rtx (imode); - if (imode != BLKmode) - src = gen_lowpart (GET_MODE (orig_src), src); - emit_move_insn (src, orig_src); - /* ...and back again. */ - if (imode != BLKmode) - src = gen_lowpart (imode, src); + { + src = assign_stack_temp (GET_MODE (orig_src), ssize); + emit_move_insn (src, orig_src); + } emit_group_load_1 (tmps, dst, src, type, ssize); return; } @@ -2368,14 +2368,18 @@ emit_group_store (rtx orig_dst, rtx src, if (!SCALAR_INT_MODE_P (m) && !MEM_P (orig_dst) && GET_CODE (orig_dst) != CONCAT) { - machine_mode imode = int_mode_for_mode (GET_MODE (orig_dst)); - if (imode == BLKmode) - dst = assign_stack_temp (GET_MODE (orig_dst), ssize); + scalar_int_mode imode; + if (int_mode_for_mode (GET_MODE (orig_dst)).exists (&imode)) + { + dst = gen_reg_rtx (imode); + emit_group_store (dst, src, type, ssize); + dst = gen_lowpart (GET_MODE (orig_dst), dst); + } else - dst = gen_reg_rtx (imode); - emit_group_store (dst, src, type, ssize); - if (imode != BLKmode) - dst = gen_lowpart (GET_MODE (orig_dst), dst); + { + dst = assign_stack_temp (GET_MODE (orig_dst), ssize); + emit_group_store (dst, src, type, ssize); + } emit_move_insn (orig_dst, dst); return; } @@ -3283,12 +3287,11 @@ emit_move_change_mode (machine_mode new_ static rtx_insn * emit_move_via_integer (machine_mode mode, rtx x, rtx y, bool force) { - machine_mode imode; + scalar_int_mode imode; enum insn_code code; /* There must exist a mode of the exact size we require. */ - imode = int_mode_for_mode (mode); - if (imode == BLKmode) + if (!int_mode_for_mode (mode).exists (&imode)) return NULL; /* The target must support moves in this mode. */ Index: gcc/optabs.c =================================================================== --- gcc/optabs.c 2017-07-13 09:18:23.799185854 +0100 +++ gcc/optabs.c 2017-07-13 09:18:30.085577402 +0100 @@ -2575,8 +2575,7 @@ expand_absneg_bit (enum rtx_code code, s if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) { - imode = int_mode_for_mode (mode); - if (imode == BLKmode) + if (!int_mode_for_mode (mode).exists (&imode)) return NULL_RTX; word = 0; nwords = 1; @@ -3269,8 +3268,7 @@ expand_copysign_absneg (scalar_float_mod { if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) { - imode = int_mode_for_mode (mode); - if (imode == BLKmode) + if (!int_mode_for_mode (mode).exists (&imode)) return NULL_RTX; op1 = gen_lowpart (imode, op1); } @@ -3332,15 +3330,14 @@ expand_copysign_absneg (scalar_float_mod expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target, int bitpos, bool op0_is_abs) { - machine_mode imode; + scalar_int_mode imode; int word, nwords, i; rtx temp; rtx_insn *insns; if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD) { - imode = int_mode_for_mode (mode); - if (imode == BLKmode) + if (!int_mode_for_mode (mode).exists (&imode)) return NULL_RTX; word = 0; nwords = 1; Index: gcc/tree-if-conv.c =================================================================== --- gcc/tree-if-conv.c 2017-07-03 14:36:28.872861805 +0100 +++ gcc/tree-if-conv.c 2017-07-13 09:18:30.087577217 +0100 @@ -933,8 +933,7 @@ ifcvt_can_use_mask_load_store (gimple *s /* Mask should be integer mode of the same size as the load/store mode. */ mode = TYPE_MODE (TREE_TYPE (lhs)); - if (int_mode_for_mode (mode) == BLKmode - || VECTOR_MODE_P (mode)) + if (!int_mode_for_mode (mode).exists () || VECTOR_MODE_P (mode)) return false; if (can_vec_mask_load_store_p (mode, VOIDmode, is_load)) Index: gcc/tree-vect-slp.c =================================================================== --- gcc/tree-vect-slp.c 2017-07-13 09:17:19.693324483 +0100 +++ gcc/tree-vect-slp.c 2017-07-13 09:18:30.088577124 +0100 @@ -3430,7 +3430,7 @@ vect_transform_slp_perm_load (slp_tree n /* The generic VEC_PERM_EXPR code always uses an integral type of the same size as the vector element being permuted. */ mask_element_type = lang_hooks.types.type_for_mode - (int_mode_for_mode (TYPE_MODE (TREE_TYPE (vectype))), 1); + (*int_mode_for_mode (TYPE_MODE (TREE_TYPE (vectype))), 1); mask_type = get_vectype_for_scalar_type (mask_element_type); nunits = TYPE_VECTOR_SUBPARTS (vectype); mask = XALLOCAVEC (unsigned char, nunits); Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-07-13 09:18:29.221658334 +0100 +++ gcc/tree-vect-stmts.c 2017-07-13 09:18:30.090576938 +0100 @@ -6432,7 +6432,7 @@ vect_gen_perm_mask_any (tree vectype, co nunits = TYPE_VECTOR_SUBPARTS (vectype); mask_elt_type = lang_hooks.types.type_for_mode - (int_mode_for_mode (TYPE_MODE (TREE_TYPE (vectype))), 1); + (*int_mode_for_mode (TYPE_MODE (TREE_TYPE (vectype))), 1); mask_type = get_vectype_for_scalar_type (mask_elt_type); mask_elts = XALLOCAVEC (tree, nunits); Index: gcc/var-tracking.c =================================================================== --- gcc/var-tracking.c 2017-07-13 09:18:22.945276764 +0100 +++ gcc/var-tracking.c 2017-07-13 09:18:30.093576660 +0100 @@ -6348,8 +6348,9 @@ prepare_call_arguments (basic_block bb, { /* For non-integer stack argument see also if they weren't initialized by integers. */ - machine_mode imode = int_mode_for_mode (GET_MODE (mem)); - if (imode != GET_MODE (mem) && imode != BLKmode) + scalar_int_mode imode; + if (int_mode_for_mode (GET_MODE (mem)).exists (&imode) + && imode != GET_MODE (mem)) { val = cselib_lookup (adjust_address_nv (mem, imode, 0), imode, 0, VOIDmode);