[18/77] Make int_mode_for_mode return an opt_scalar_int_mode

Message ID 87zic8k9nu.fsf@linaro.org
State New
Headers show
Series
  • Add wrapper classes for machine_modes
Related show

Commit Message

Richard Sandiford July 13, 2017, 8:45 a.m.
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.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@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.

Patch hide | download patch | download mbox

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);