public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Sandiford <richard.sandiford@arm.com>
To: gcc-patches@gcc.gnu.org
Subject: [35/67] Add uses of as_a <scalar_int_mode>
Date: Fri, 09 Dec 2016 13:16:00 -0000	[thread overview]
Message-ID: <87a8c5jl9t.fsf@e105548-lin.cambridge.arm.com> (raw)
In-Reply-To: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com> (Richard	Sandiford's message of "Fri, 09 Dec 2016 12:48:01 +0000")

This patch adds asserting as_a <scalar_int_mode> conversions
in contexts where the input is known to be a scalar integer mode.

In expand_divmod, op1 is always a scalar_int_mode if
op1_is_constant (but might not be otherwise).

In expand_binop, the patch reverses a < comparison in order to
avoid splitting a long line.

gcc/
2016-11-24  Richard Sandiford  <richard.sandiford@arm.com>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

	* cfgexpand.c (convert_debug_memory_address): Use
	as_a <scalar_int_mode>.
	* combine.c (expand_compound_operation): Likewise.
	(make_extraction): Likewise.
	(change_zero_ext): Likewise.
	(simplify_comparison): Likewise.
	* cse.c (cse_insn): Likewise.
	* dwarf2out.c (minmax_loc_descriptor): Likewise.
	(mem_loc_descriptor): Likewise.
	(loc_descriptor): Likewise.
	* expmed.c (synth_mult): Likewise.
	(emit_store_flag_1): Likewise.
	(expand_divmod): Likewise.  Use HWI_COMPUTABLE_MODE_P instead
	of a comparison with size.
	* expr.c (expand_assignment): Use as_a <scalar_int_mode>.
	(reduce_to_bit_field_precision): Likewise.
	* function.c (expand_function_end): Likewise.
	* internal-fn.c (expand_arith_overflow_result_store): Likewise.
	* loop-doloop.c (doloop_modify): Likewise.
	* optabs.c (expand_binop): Likewise.
	(expand_unop): Likewise.
	(expand_copysign_absneg): Likewise.
	(prepare_cmp_insn): Likewise.
	(maybe_legitimize_operand): Likewise.
	* recog.c (const_scalar_int_operand): Likewise.
	* rtlanal.c (get_address_mode): Likewise.
	* simplify-rtx.c (simplify_unary_operation_1): Likewise.
	(simplify_cond_clz_ctz): Likewise.
	* tree-nested.c (get_nl_goto_field): Likewise.
	* tree.c (build_vector_type_for_mode): Likewise.
	* var-tracking.c (use_narrower_mode): Likewise.

gcc/c-family/
2016-11-24  Richard Sandiford  <richard.sandiford@arm.com>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

	* c-common.c (c_common_type_for_mode): Use as_a <scalar_int_mode>.

gcc/lto/
2016-11-24  Richard Sandiford  <richard.sandiford@arm.com>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

	* lto-lang.c (lto_type_for_mode): Use as_a <scalar_int_mode>.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index cb04536..0e06725 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2216,15 +2216,15 @@ c_common_type_for_mode (machine_mode mode, int unsignedp)
   if (mode == TYPE_MODE (void_type_node))
     return void_type_node;
 
-  if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
-    return (unsignedp
-	    ? make_unsigned_type (GET_MODE_PRECISION (mode))
-	    : make_signed_type (GET_MODE_PRECISION (mode)));
-
-  if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
-    return (unsignedp
-	    ? make_unsigned_type (GET_MODE_PRECISION (mode))
-	    : make_signed_type (GET_MODE_PRECISION (mode)));
+  if (mode == TYPE_MODE (build_pointer_type (char_type_node))
+      || mode == TYPE_MODE (build_pointer_type (integer_type_node)))
+    {
+      unsigned int precision
+	= GET_MODE_PRECISION (as_a <scalar_int_mode> (mode));
+      return (unsignedp
+	      ? make_unsigned_type (precision)
+	      : make_signed_type (precision));
+    }
 
   if (COMPLEX_MODE_P (mode))
     {
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index dbb7bca..c4863dd 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3954,12 +3954,10 @@ static rtx
 convert_debug_memory_address (machine_mode mode, rtx x,
 			      addr_space_t as)
 {
-  machine_mode xmode = GET_MODE (x);
-
 #ifndef POINTERS_EXTEND_UNSIGNED
   gcc_assert (mode == Pmode
 	      || mode == targetm.addr_space.address_mode (as));
-  gcc_assert (xmode == mode || xmode == VOIDmode);
+  gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode);
 #else
   rtx temp;
 
@@ -3968,6 +3966,8 @@ convert_debug_memory_address (machine_mode mode, rtx x,
   if (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode)
     return x;
 
+  /* X must have some form of address mode already.  */
+  scalar_int_mode xmode = as_a <scalar_int_mode> (GET_MODE (x));
   if (GET_MODE_PRECISION (mode) < GET_MODE_PRECISION (xmode))
     x = lowpart_subreg (mode, x, xmode);
   else if (POINTERS_EXTEND_UNSIGNED > 0)
diff --git a/gcc/combine.c b/gcc/combine.c
index 92b2ec9..0f25782 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7121,16 +7121,19 @@ expand_compound_operation (rtx x)
     default:
       return x;
     }
+
+  /* We've rejected non-scalar operations by now.  */
+  scalar_int_mode mode = as_a <scalar_int_mode> (GET_MODE (x));
+
   /* Convert sign extension to zero extension, if we know that the high
      bit is not set, as this is easier to optimize.  It will be converted
      back to cheaper alternative in make_extraction.  */
   if (GET_CODE (x) == SIGN_EXTEND
-      && HWI_COMPUTABLE_MODE_P (GET_MODE (x))
+      && HWI_COMPUTABLE_MODE_P (mode)
       && ((nonzero_bits (XEXP (x, 0), inner_mode)
 	   & ~(((unsigned HOST_WIDE_INT) GET_MODE_MASK (inner_mode)) >> 1))
 	  == 0))
     {
-      machine_mode mode = GET_MODE (x);
       rtx temp = gen_rtx_ZERO_EXTEND (mode, XEXP (x, 0));
       rtx temp2 = expand_compound_operation (temp);
 
@@ -7152,27 +7155,27 @@ expand_compound_operation (rtx x)
 	 know that the last value didn't have any inappropriate bits
 	 set.  */
       if (GET_CODE (XEXP (x, 0)) == TRUNCATE
-	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
-	  && HWI_COMPUTABLE_MODE_P (GET_MODE (x))
-	  && (nonzero_bits (XEXP (XEXP (x, 0), 0), GET_MODE (x))
+	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode
+	  && HWI_COMPUTABLE_MODE_P (mode)
+	  && (nonzero_bits (XEXP (XEXP (x, 0), 0), mode)
 	      & ~GET_MODE_MASK (inner_mode)) == 0)
 	return XEXP (XEXP (x, 0), 0);
 
       /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
       if (GET_CODE (XEXP (x, 0)) == SUBREG
-	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
+	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == mode
 	  && subreg_lowpart_p (XEXP (x, 0))
-	  && HWI_COMPUTABLE_MODE_P (GET_MODE (x))
-	  && (nonzero_bits (SUBREG_REG (XEXP (x, 0)), GET_MODE (x))
+	  && HWI_COMPUTABLE_MODE_P (mode)
+	  && (nonzero_bits (SUBREG_REG (XEXP (x, 0)), mode)
 	      & ~GET_MODE_MASK (inner_mode)) == 0)
 	return SUBREG_REG (XEXP (x, 0));
 
       /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI when foo
 	 is a comparison and STORE_FLAG_VALUE permits.  This is like
-	 the first case, but it works even when GET_MODE (x) is larger
+	 the first case, but it works even when MODE is larger
 	 than HOST_WIDE_INT.  */
       if (GET_CODE (XEXP (x, 0)) == TRUNCATE
-	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == GET_MODE (x)
+	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode
 	  && COMPARISON_P (XEXP (XEXP (x, 0), 0))
 	  && GET_MODE_PRECISION (inner_mode) <= HOST_BITS_PER_WIDE_INT
 	  && (STORE_FLAG_VALUE & ~GET_MODE_MASK (inner_mode)) == 0)
@@ -7180,7 +7183,7 @@ expand_compound_operation (rtx x)
 
       /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
       if (GET_CODE (XEXP (x, 0)) == SUBREG
-	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == GET_MODE (x)
+	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == mode
 	  && subreg_lowpart_p (XEXP (x, 0))
 	  && COMPARISON_P (SUBREG_REG (XEXP (x, 0)))
 	  && GET_MODE_PRECISION (inner_mode) <= HOST_BITS_PER_WIDE_INT
@@ -7204,10 +7207,9 @@ expand_compound_operation (rtx x)
      extraction.  Then the constant of 31 would be substituted in
      to produce such a position.  */
 
-  modewidth = GET_MODE_PRECISION (GET_MODE (x));
+  modewidth = GET_MODE_PRECISION (mode);
   if (modewidth >= pos + len)
     {
-      machine_mode mode = GET_MODE (x);
       tem = gen_lowpart (mode, XEXP (x, 0));
       if (!tem || GET_CODE (tem) == CLOBBER)
 	return x;
@@ -7217,10 +7219,10 @@ expand_compound_operation (rtx x)
 				  mode, tem, modewidth - len);
     }
   else if (unsignedp && len < HOST_BITS_PER_WIDE_INT)
-    tem = simplify_and_const_int (NULL_RTX, GET_MODE (x),
+    tem = simplify_and_const_int (NULL_RTX, mode,
 				  simplify_shift_const (NULL_RTX, LSHIFTRT,
-							GET_MODE (x),
-							XEXP (x, 0), pos),
+							mode, XEXP (x, 0),
+							pos),
 				  (HOST_WIDE_INT_1U << len) - 1);
   else
     /* Any other cases we can't handle.  */
@@ -7721,9 +7723,13 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
     }
 
   /* Adjust mode of POS_RTX, if needed.  If we want a wider mode, we
-     have to zero extend.  Otherwise, we can just use a SUBREG.  */
+     have to zero extend.  Otherwise, we can just use a SUBREG.
+
+     We dealt with constant rtxes earlier, so pos_rtx cannot
+     have VOIDmode at this point.  */
   if (pos_rtx != 0
-      && GET_MODE_SIZE (pos_mode) > GET_MODE_SIZE (GET_MODE (pos_rtx)))
+      && (GET_MODE_SIZE (pos_mode)
+	  > GET_MODE_SIZE (as_a <scalar_int_mode> (GET_MODE (pos_rtx)))))
     {
       rtx temp = simplify_gen_unary (ZERO_EXTEND, pos_mode, pos_rtx,
 				     GET_MODE (pos_rtx));
@@ -11307,7 +11313,9 @@ change_zero_ext (rtx pat)
 	       && !paradoxical_subreg_p (XEXP (x, 0))
 	       && subreg_lowpart_p (XEXP (x, 0)))
 	{
-	  size = GET_MODE_PRECISION (GET_MODE (XEXP (x, 0)));
+	  scalar_int_mode inner_mode
+	    = as_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)));
+	  size = GET_MODE_PRECISION (inner_mode);
 	  x = SUBREG_REG (XEXP (x, 0));
 	  if (GET_MODE (x) != mode)
 	    x = gen_lowpart_SUBREG (mode, x);
@@ -11317,7 +11325,9 @@ change_zero_ext (rtx pat)
 	       && HARD_REGISTER_P (XEXP (x, 0))
 	       && can_change_dest_mode (XEXP (x, 0), 0, mode))
 	{
-	  size = GET_MODE_PRECISION (GET_MODE (XEXP (x, 0)));
+	  scalar_int_mode inner_mode
+	    = as_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)));
+	  size = GET_MODE_PRECISION (inner_mode);
 	  x = gen_rtx_REG (mode, REGNO (XEXP (x, 0)));
 	}
       else
@@ -11730,8 +11740,8 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
   rtx op1 = *pop1;
   rtx tem, tem1;
   int i;
-  scalar_int_mode mode, inner_mode;
-  machine_mode tmode;
+  scalar_int_mode mode, inner_mode, tmode;
+  opt_scalar_int_mode tmode_iter;
 
   /* Try a few ways of applying the same transformation to both operands.  */
   while (1)
@@ -11839,7 +11849,8 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
 	    }
 
 	  else if (c0 == c1)
-	    FOR_EACH_MODE_UNTIL (tmode, GET_MODE (op0))
+	    FOR_EACH_MODE_UNTIL (tmode,
+				 as_a <scalar_int_mode> (GET_MODE (op0)))
 	      if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
 		{
 		  op0 = gen_lowpart_or_truncate (tmode, inner_op0);
@@ -12708,8 +12719,9 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
   if (is_int_mode (GET_MODE (op0), &mode)
       && GET_MODE_SIZE (mode) < UNITS_PER_WORD
       && ! have_insn_for (COMPARE, mode))
-    FOR_EACH_WIDER_MODE (tmode, mode)
+    FOR_EACH_WIDER_MODE (tmode_iter, mode)
       {
+	tmode = *tmode_iter;
 	if (!HWI_COMPUTABLE_MODE_P (tmode))
 	  break;
 	if (have_insn_for (COMPARE, tmode))
diff --git a/gcc/cse.c b/gcc/cse.c
index 2f29062..4d22d78 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4552,14 +4552,17 @@ cse_insn (rtx_insn *insn)
 	       && CONST_INT_P (XEXP (SET_DEST (sets[0].rtl), 2)))
 	{
 	  rtx dest_reg = XEXP (SET_DEST (sets[0].rtl), 0);
+	  /* This is the mode of XEXP (tem, 0) as well.  */
+	  scalar_int_mode dest_mode
+	    = as_a <scalar_int_mode> (GET_MODE (dest_reg));
 	  rtx width = XEXP (SET_DEST (sets[0].rtl), 1);
 	  rtx pos = XEXP (SET_DEST (sets[0].rtl), 2);
 	  HOST_WIDE_INT val = INTVAL (XEXP (tem, 0));
 	  HOST_WIDE_INT mask;
 	  unsigned int shift;
 	  if (BITS_BIG_ENDIAN)
-	    shift = GET_MODE_PRECISION (GET_MODE (dest_reg))
-	      - INTVAL (pos) - INTVAL (width);
+	    shift = (GET_MODE_PRECISION (dest_mode)
+		     - INTVAL (pos) - INTVAL (width));
 	  else
 	    shift = INTVAL (pos);
 	  if (INTVAL (width) == HOST_BITS_PER_WIDE_INT)
@@ -5231,8 +5234,11 @@ cse_insn (rtx_insn *insn)
 		  HOST_WIDE_INT val = INTVAL (dest_cst);
 		  HOST_WIDE_INT mask;
 		  unsigned int shift;
+		  /* This is the mode of DEST_CST as well.  */
+		  scalar_int_mode dest_mode
+		    = as_a <scalar_int_mode> (GET_MODE (dest_reg));
 		  if (BITS_BIG_ENDIAN)
-		    shift = GET_MODE_PRECISION (GET_MODE (dest_reg))
+		    shift = GET_MODE_PRECISION (dest_mode)
 			    - INTVAL (pos) - INTVAL (width);
 		  else
 		    shift = INTVAL (pos);
@@ -5242,7 +5248,7 @@ cse_insn (rtx_insn *insn)
 		    mask = (HOST_WIDE_INT_1 << INTVAL (width)) - 1;
 		  val &= ~(mask << shift);
 		  val |= (INTVAL (trial) & mask) << shift;
-		  val = trunc_int_for_mode (val, GET_MODE (dest_reg));
+		  val = trunc_int_for_mode (val, dest_mode);
 		  validate_unshare_change (insn, &SET_DEST (sets[i].rtl),
 					   dest_reg, 1);
 		  validate_unshare_change (insn, &SET_SRC (sets[i].rtl),
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index ed5ec24..accca42 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -13969,15 +13969,17 @@ minmax_loc_descriptor (rtx rtl, machine_mode mode,
   add_loc_descr (&op1, new_loc_descr (DW_OP_over, 0, 0));
   if (GET_CODE (rtl) == UMIN || GET_CODE (rtl) == UMAX)
     {
-      if (GET_MODE_SIZE (mode) < DWARF2_ADDR_SIZE)
+      /* Checked by the caller.  */
+      int_mode = as_a <scalar_int_mode> (mode);
+      if (GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE)
 	{
-	  HOST_WIDE_INT mask = GET_MODE_MASK (mode);
+	  HOST_WIDE_INT mask = GET_MODE_MASK (int_mode);
 	  add_loc_descr (&op0, int_loc_descriptor (mask));
 	  add_loc_descr (&op0, new_loc_descr (DW_OP_and, 0, 0));
 	  add_loc_descr (&op1, int_loc_descriptor (mask));
 	  add_loc_descr (&op1, new_loc_descr (DW_OP_and, 0, 0));
 	}
-      else if (GET_MODE_SIZE (mode) == DWARF2_ADDR_SIZE)
+      else if (GET_MODE_SIZE (int_mode) == DWARF2_ADDR_SIZE)
 	{
 	  HOST_WIDE_INT bias = 1;
 	  bias <<= (DWARF2_ADDR_SIZE * BITS_PER_UNIT - 1);
@@ -14860,7 +14862,8 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
 	    break;
 
 	  if (CONST_INT_P (XEXP (rtl, 1))
-	      && GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE)
+	      && (GET_MODE_SIZE (as_a <scalar_int_mode> (mode))
+		  <= DWARF2_ADDR_SIZE))
 	    loc_descr_plus_const (&mem_loc_result, INTVAL (XEXP (rtl, 1)));
 	  else
 	    {
@@ -15643,8 +15646,11 @@ loc_descriptor (rtx rtl, machine_mode mode,
 
     case CONST_INT:
       if (mode != VOIDmode && mode != BLKmode)
-	loc_result = address_of_int_loc_descriptor (GET_MODE_SIZE (mode),
-						    INTVAL (rtl));
+	{
+	  int_mode = as_a <scalar_int_mode> (mode);
+	  loc_result = address_of_int_loc_descriptor (GET_MODE_SIZE (int_mode),
+						      INTVAL (rtl));
+	}
       break;
 
     case CONST_DOUBLE:
@@ -15689,11 +15695,12 @@ loc_descriptor (rtx rtl, machine_mode mode,
 
       if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
 	{
+	  int_mode = as_a <scalar_int_mode> (mode);
 	  loc_result = new_loc_descr (DW_OP_implicit_value,
-				      GET_MODE_SIZE (mode), 0);
+				      GET_MODE_SIZE (int_mode), 0);
 	  loc_result->dw_loc_oprnd2.val_class = dw_val_class_wide_int;
 	  loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc<wide_int> ();
-	  *loc_result->dw_loc_oprnd2.v.val_wide = rtx_mode_t (rtl, mode);
+	  *loc_result->dw_loc_oprnd2.v.val_wide = rtx_mode_t (rtl, int_mode);
 	}
       break;
 
diff --git a/gcc/expmed.c b/gcc/expmed.c
index f056e96..dea4923 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -2513,7 +2513,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
   bool cache_hit = false;
   enum alg_code cache_alg = alg_zero;
   bool speed = optimize_insn_for_speed_p ();
-  machine_mode imode;
+  scalar_int_mode imode;
   struct alg_hash_entry *entry_ptr;
 
   /* Indicate that no algorithm is yet found.  If no algorithm
@@ -2526,7 +2526,7 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
     return;
 
   /* Be prepared for vector modes.  */
-  imode = GET_MODE_INNER (mode);
+  imode = as_a <scalar_int_mode> (GET_MODE_INNER (mode));
 
   maxm = MIN (BITS_PER_WORD, GET_MODE_BITSIZE (imode));
 
@@ -3970,7 +3970,6 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
   rtx tquotient;
   rtx quotient = 0, remainder = 0;
   rtx_insn *last;
-  int size;
   rtx_insn *insn;
   optab optab1, optab2;
   int op1_is_constant, op1_is_pow2 = 0;
@@ -4092,7 +4091,6 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
   else
     tquotient = gen_reg_rtx (compute_mode);
 
-  size = GET_MODE_BITSIZE (compute_mode);
 #if 0
   /* It should be possible to restrict the precision to GET_MODE_BITSIZE
      (mode), and thereby get better code when OP1 is a constant.  Do that
@@ -4165,12 +4163,14 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
       case TRUNC_DIV_EXPR:
 	if (op1_is_constant)
 	  {
+	    scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
+	    int size = GET_MODE_BITSIZE (int_mode);
 	    if (unsignedp)
 	      {
 		unsigned HOST_WIDE_INT mh, ml;
 		int pre_shift, post_shift;
 		int dummy;
-		wide_int wd = rtx_mode_t (op1, compute_mode);
+		wide_int wd = rtx_mode_t (op1, int_mode);
 		unsigned HOST_WIDE_INT d = wd.to_uhwi ();
 
 		if (wi::popcount (wd) == 1)
@@ -4181,14 +4181,14 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 			unsigned HOST_WIDE_INT mask
 			  = (HOST_WIDE_INT_1U << pre_shift) - 1;
 			remainder
-			  = expand_binop (compute_mode, and_optab, op0,
-					  gen_int_mode (mask, compute_mode),
+			  = expand_binop (int_mode, and_optab, op0,
+					  gen_int_mode (mask, int_mode),
 					  remainder, 1,
 					  OPTAB_LIB_WIDEN);
 			if (remainder)
 			  return gen_lowpart (mode, remainder);
 		      }
-		    quotient = expand_shift (RSHIFT_EXPR, compute_mode, op0,
+		    quotient = expand_shift (RSHIFT_EXPR, int_mode, op0,
 					     pre_shift, tquotient, 1);
 		  }
 		else if (size <= HOST_BITS_PER_WIDE_INT)
@@ -4198,7 +4198,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 			/* Most significant bit of divisor is set; emit an scc
 			   insn.  */
 			quotient = emit_store_flag_force (tquotient, GEU, op0, op1,
-							  compute_mode, 1, 1);
+							  int_mode, 1, 1);
 		      }
 		    else
 		      {
@@ -4230,25 +4230,25 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 			      goto fail1;
 
 			    extra_cost
-			      = (shift_cost (speed, compute_mode, post_shift - 1)
-				 + shift_cost (speed, compute_mode, 1)
-				 + 2 * add_cost (speed, compute_mode));
+			      = (shift_cost (speed, int_mode, post_shift - 1)
+				 + shift_cost (speed, int_mode, 1)
+				 + 2 * add_cost (speed, int_mode));
 			    t1 = expmed_mult_highpart
-			      (compute_mode, op0,
-			       gen_int_mode (ml, compute_mode),
+			      (int_mode, op0,
+			       gen_int_mode (ml, int_mode),
 			       NULL_RTX, 1, max_cost - extra_cost);
 			    if (t1 == 0)
 			      goto fail1;
-			    t2 = force_operand (gen_rtx_MINUS (compute_mode,
+			    t2 = force_operand (gen_rtx_MINUS (int_mode,
 							       op0, t1),
 						NULL_RTX);
-			    t3 = expand_shift (RSHIFT_EXPR, compute_mode,
+			    t3 = expand_shift (RSHIFT_EXPR, int_mode,
 					       t2, 1, NULL_RTX, 1);
-			    t4 = force_operand (gen_rtx_PLUS (compute_mode,
+			    t4 = force_operand (gen_rtx_PLUS (int_mode,
 							      t1, t3),
 						NULL_RTX);
 			    quotient = expand_shift
-			      (RSHIFT_EXPR, compute_mode, t4,
+			      (RSHIFT_EXPR, int_mode, t4,
 			       post_shift - 1, tquotient, 1);
 			  }
 			else
@@ -4260,19 +4260,19 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 			      goto fail1;
 
 			    t1 = expand_shift
-			      (RSHIFT_EXPR, compute_mode, op0,
+			      (RSHIFT_EXPR, int_mode, op0,
 			       pre_shift, NULL_RTX, 1);
 			    extra_cost
-			      = (shift_cost (speed, compute_mode, pre_shift)
-				 + shift_cost (speed, compute_mode, post_shift));
+			      = (shift_cost (speed, int_mode, pre_shift)
+				 + shift_cost (speed, int_mode, post_shift));
 			    t2 = expmed_mult_highpart
-			      (compute_mode, t1,
-			       gen_int_mode (ml, compute_mode),
+			      (int_mode, t1,
+			       gen_int_mode (ml, int_mode),
 			       NULL_RTX, 1, max_cost - extra_cost);
 			    if (t2 == 0)
 			      goto fail1;
 			    quotient = expand_shift
-			      (RSHIFT_EXPR, compute_mode, t2,
+			      (RSHIFT_EXPR, int_mode, t2,
 			       post_shift, tquotient, 1);
 			  }
 		      }
@@ -4283,7 +4283,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 		insn = get_last_insn ();
 		if (insn != last)
 		  set_dst_reg_note (insn, REG_EQUAL,
-				    gen_rtx_UDIV (compute_mode, op0, op1),
+				    gen_rtx_UDIV (int_mode, op0, op1),
 				    quotient);
 	      }
 	    else		/* TRUNC_DIV, signed */
@@ -4305,36 +4305,36 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 		if (rem_flag && d < 0)
 		  {
 		    d = abs_d;
-		    op1 = gen_int_mode (abs_d, compute_mode);
+		    op1 = gen_int_mode (abs_d, int_mode);
 		  }
 
 		if (d == 1)
 		  quotient = op0;
 		else if (d == -1)
-		  quotient = expand_unop (compute_mode, neg_optab, op0,
+		  quotient = expand_unop (int_mode, neg_optab, op0,
 					  tquotient, 0);
 		else if (size <= HOST_BITS_PER_WIDE_INT
 			 && abs_d == HOST_WIDE_INT_1U << (size - 1))
 		  {
 		    /* This case is not handled correctly below.  */
 		    quotient = emit_store_flag (tquotient, EQ, op0, op1,
-						compute_mode, 1, 1);
+						int_mode, 1, 1);
 		    if (quotient == 0)
 		      goto fail1;
 		  }
 		else if (EXACT_POWER_OF_2_OR_ZERO_P (d)
 			 && (size <= HOST_BITS_PER_WIDE_INT || d >= 0)
 			 && (rem_flag
-			     ? smod_pow2_cheap (speed, compute_mode)
-			     : sdiv_pow2_cheap (speed, compute_mode))
+			     ? smod_pow2_cheap (speed, int_mode)
+			     : sdiv_pow2_cheap (speed, int_mode))
 			 /* We assume that cheap metric is true if the
 			    optab has an expander for this mode.  */
 			 && ((optab_handler ((rem_flag ? smod_optab
 					      : sdiv_optab),
-					     compute_mode)
+					     int_mode)
 			      != CODE_FOR_nothing)
 			     || (optab_handler (sdivmod_optab,
-						compute_mode)
+						int_mode)
 				 != CODE_FOR_nothing)))
 		  ;
 		else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d)
@@ -4343,23 +4343,23 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 		  {
 		    if (rem_flag)
 		      {
-			remainder = expand_smod_pow2 (compute_mode, op0, d);
+			remainder = expand_smod_pow2 (int_mode, op0, d);
 			if (remainder)
 			  return gen_lowpart (mode, remainder);
 		      }
 
-		    if (sdiv_pow2_cheap (speed, compute_mode)
-			&& ((optab_handler (sdiv_optab, compute_mode)
+		    if (sdiv_pow2_cheap (speed, int_mode)
+			&& ((optab_handler (sdiv_optab, int_mode)
 			     != CODE_FOR_nothing)
-			    || (optab_handler (sdivmod_optab, compute_mode)
+			    || (optab_handler (sdivmod_optab, int_mode)
 				!= CODE_FOR_nothing)))
 		      quotient = expand_divmod (0, TRUNC_DIV_EXPR,
-						compute_mode, op0,
+						int_mode, op0,
 						gen_int_mode (abs_d,
-							      compute_mode),
+							      int_mode),
 						NULL_RTX, 0);
 		    else
-		      quotient = expand_sdiv_pow2 (compute_mode, op0, abs_d);
+		      quotient = expand_sdiv_pow2 (int_mode, op0, abs_d);
 
 		    /* We have computed OP0 / abs(OP1).  If OP1 is negative,
 		       negate the quotient.  */
@@ -4370,13 +4370,13 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 			    && abs_d < (HOST_WIDE_INT_1U
 					<< (HOST_BITS_PER_WIDE_INT - 1)))
 			  set_dst_reg_note (insn, REG_EQUAL,
-					    gen_rtx_DIV (compute_mode, op0,
+					    gen_rtx_DIV (int_mode, op0,
 							 gen_int_mode
 							   (abs_d,
-							    compute_mode)),
+							    int_mode)),
 					    quotient);
 
-			quotient = expand_unop (compute_mode, neg_optab,
+			quotient = expand_unop (int_mode, neg_optab,
 						quotient, quotient, 0);
 		      }
 		  }
@@ -4392,29 +4392,27 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 			    || size - 1 >= BITS_PER_WORD)
 			  goto fail1;
 
-			extra_cost = (shift_cost (speed, compute_mode, post_shift)
-				      + shift_cost (speed, compute_mode, size - 1)
-				      + add_cost (speed, compute_mode));
+			extra_cost = (shift_cost (speed, int_mode, post_shift)
+				      + shift_cost (speed, int_mode, size - 1)
+				      + add_cost (speed, int_mode));
 			t1 = expmed_mult_highpart
-			  (compute_mode, op0, gen_int_mode (ml, compute_mode),
+			  (int_mode, op0, gen_int_mode (ml, int_mode),
 			   NULL_RTX, 0, max_cost - extra_cost);
 			if (t1 == 0)
 			  goto fail1;
 			t2 = expand_shift
-			  (RSHIFT_EXPR, compute_mode, t1,
+			  (RSHIFT_EXPR, int_mode, t1,
 			   post_shift, NULL_RTX, 0);
 			t3 = expand_shift
-			  (RSHIFT_EXPR, compute_mode, op0,
+			  (RSHIFT_EXPR, int_mode, op0,
 			   size - 1, NULL_RTX, 0);
 			if (d < 0)
 			  quotient
-			    = force_operand (gen_rtx_MINUS (compute_mode,
-							    t3, t2),
+			    = force_operand (gen_rtx_MINUS (int_mode, t3, t2),
 					     tquotient);
 			else
 			  quotient
-			    = force_operand (gen_rtx_MINUS (compute_mode,
-							    t2, t3),
+			    = force_operand (gen_rtx_MINUS (int_mode, t2, t3),
 					     tquotient);
 		      }
 		    else
@@ -4426,33 +4424,30 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 			  goto fail1;
 
 			ml |= HOST_WIDE_INT_M1U << (size - 1);
-			mlr = gen_int_mode (ml, compute_mode);
-			extra_cost = (shift_cost (speed, compute_mode, post_shift)
-				      + shift_cost (speed, compute_mode, size - 1)
-				      + 2 * add_cost (speed, compute_mode));
-			t1 = expmed_mult_highpart (compute_mode, op0, mlr,
+			mlr = gen_int_mode (ml, int_mode);
+			extra_cost = (shift_cost (speed, int_mode, post_shift)
+				      + shift_cost (speed, int_mode, size - 1)
+				      + 2 * add_cost (speed, int_mode));
+			t1 = expmed_mult_highpart (int_mode, op0, mlr,
 						   NULL_RTX, 0,
 						   max_cost - extra_cost);
 			if (t1 == 0)
 			  goto fail1;
-			t2 = force_operand (gen_rtx_PLUS (compute_mode,
-							  t1, op0),
+			t2 = force_operand (gen_rtx_PLUS (int_mode, t1, op0),
 					    NULL_RTX);
 			t3 = expand_shift
-			  (RSHIFT_EXPR, compute_mode, t2,
+			  (RSHIFT_EXPR, int_mode, t2,
 			   post_shift, NULL_RTX, 0);
 			t4 = expand_shift
-			  (RSHIFT_EXPR, compute_mode, op0,
+			  (RSHIFT_EXPR, int_mode, op0,
 			   size - 1, NULL_RTX, 0);
 			if (d < 0)
 			  quotient
-			    = force_operand (gen_rtx_MINUS (compute_mode,
-							    t4, t3),
+			    = force_operand (gen_rtx_MINUS (int_mode, t4, t3),
 					     tquotient);
 			else
 			  quotient
-			    = force_operand (gen_rtx_MINUS (compute_mode,
-							    t3, t4),
+			    = force_operand (gen_rtx_MINUS (int_mode, t3, t4),
 					     tquotient);
 		      }
 		  }
@@ -4462,7 +4457,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 		insn = get_last_insn ();
 		if (insn != last)
 		  set_dst_reg_note (insn, REG_EQUAL,
-				    gen_rtx_DIV (compute_mode, op0, op1),
+				    gen_rtx_DIV (int_mode, op0, op1),
 				    quotient);
 	      }
 	    break;
@@ -4474,8 +4469,10 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
       case FLOOR_DIV_EXPR:
       case FLOOR_MOD_EXPR:
       /* We will come here only for signed operations.  */
-	if (op1_is_constant && size <= HOST_BITS_PER_WIDE_INT)
+	if (op1_is_constant && HWI_COMPUTABLE_MODE_P (compute_mode))
 	  {
+	    scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
+	    int size = GET_MODE_BITSIZE (int_mode);
 	    unsigned HOST_WIDE_INT mh, ml;
 	    int pre_shift, lgup, post_shift;
 	    HOST_WIDE_INT d = INTVAL (op1);
@@ -4492,14 +4489,14 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 			unsigned HOST_WIDE_INT mask
 			  = (HOST_WIDE_INT_1U << pre_shift) - 1;
 			remainder = expand_binop
-			  (compute_mode, and_optab, op0,
-			   gen_int_mode (mask, compute_mode),
+			  (int_mode, and_optab, op0,
+			   gen_int_mode (mask, int_mode),
 			   remainder, 0, OPTAB_LIB_WIDEN);
 			if (remainder)
 			  return gen_lowpart (mode, remainder);
 		      }
 		    quotient = expand_shift
-		      (RSHIFT_EXPR, compute_mode, op0,
+		      (RSHIFT_EXPR, int_mode, op0,
 		       pre_shift, tquotient, 0);
 		  }
 		else
@@ -4514,22 +4511,22 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 			&& size - 1 < BITS_PER_WORD)
 		      {
 			t1 = expand_shift
-			  (RSHIFT_EXPR, compute_mode, op0,
+			  (RSHIFT_EXPR, int_mode, op0,
 			   size - 1, NULL_RTX, 0);
-			t2 = expand_binop (compute_mode, xor_optab, op0, t1,
+			t2 = expand_binop (int_mode, xor_optab, op0, t1,
 					   NULL_RTX, 0, OPTAB_WIDEN);
-			extra_cost = (shift_cost (speed, compute_mode, post_shift)
-				      + shift_cost (speed, compute_mode, size - 1)
-				      + 2 * add_cost (speed, compute_mode));
+			extra_cost = (shift_cost (speed, int_mode, post_shift)
+				      + shift_cost (speed, int_mode, size - 1)
+				      + 2 * add_cost (speed, int_mode));
 			t3 = expmed_mult_highpart
-			  (compute_mode, t2, gen_int_mode (ml, compute_mode),
+			  (int_mode, t2, gen_int_mode (ml, int_mode),
 			   NULL_RTX, 1, max_cost - extra_cost);
 			if (t3 != 0)
 			  {
 			    t4 = expand_shift
-			      (RSHIFT_EXPR, compute_mode, t3,
+			      (RSHIFT_EXPR, int_mode, t3,
 			       post_shift, NULL_RTX, 1);
-			    quotient = expand_binop (compute_mode, xor_optab,
+			    quotient = expand_binop (int_mode, xor_optab,
 						     t4, t1, tquotient, 0,
 						     OPTAB_WIDEN);
 			  }
@@ -4539,23 +4536,22 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 	    else
 	      {
 		rtx nsign, t1, t2, t3, t4;
-		t1 = force_operand (gen_rtx_PLUS (compute_mode,
+		t1 = force_operand (gen_rtx_PLUS (int_mode,
 						  op0, constm1_rtx), NULL_RTX);
-		t2 = expand_binop (compute_mode, ior_optab, op0, t1, NULL_RTX,
+		t2 = expand_binop (int_mode, ior_optab, op0, t1, NULL_RTX,
 				   0, OPTAB_WIDEN);
-		nsign = expand_shift (RSHIFT_EXPR, compute_mode, t2,
+		nsign = expand_shift (RSHIFT_EXPR, int_mode, t2,
 				      size - 1, NULL_RTX, 0);
-		t3 = force_operand (gen_rtx_MINUS (compute_mode, t1, nsign),
+		t3 = force_operand (gen_rtx_MINUS (int_mode, t1, nsign),
 				    NULL_RTX);
-		t4 = expand_divmod (0, TRUNC_DIV_EXPR, compute_mode, t3, op1,
+		t4 = expand_divmod (0, TRUNC_DIV_EXPR, int_mode, t3, op1,
 				    NULL_RTX, 0);
 		if (t4)
 		  {
 		    rtx t5;
-		    t5 = expand_unop (compute_mode, one_cmpl_optab, nsign,
+		    t5 = expand_unop (int_mode, one_cmpl_optab, nsign,
 				      NULL_RTX, 0);
-		    quotient = force_operand (gen_rtx_PLUS (compute_mode,
-							    t4, t5),
+		    quotient = force_operand (gen_rtx_PLUS (int_mode, t4, t5),
 					      tquotient);
 		  }
 	      }
@@ -4655,31 +4651,31 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 	  {
 	    if (op1_is_constant
 		&& EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
-		&& (size <= HOST_BITS_PER_WIDE_INT
+		&& (HWI_COMPUTABLE_MODE_P (compute_mode)
 		    || INTVAL (op1) >= 0))
 	      {
+		scalar_int_mode int_mode
+		  = as_a <scalar_int_mode> (compute_mode);
 		rtx t1, t2, t3;
 		unsigned HOST_WIDE_INT d = INTVAL (op1);
-		t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
+		t1 = expand_shift (RSHIFT_EXPR, int_mode, op0,
 				   floor_log2 (d), tquotient, 1);
-		t2 = expand_binop (compute_mode, and_optab, op0,
-				   gen_int_mode (d - 1, compute_mode),
+		t2 = expand_binop (int_mode, and_optab, op0,
+				   gen_int_mode (d - 1, int_mode),
 				   NULL_RTX, 1, OPTAB_LIB_WIDEN);
-		t3 = gen_reg_rtx (compute_mode);
-		t3 = emit_store_flag (t3, NE, t2, const0_rtx,
-				      compute_mode, 1, 1);
+		t3 = gen_reg_rtx (int_mode);
+		t3 = emit_store_flag (t3, NE, t2, const0_rtx, int_mode, 1, 1);
 		if (t3 == 0)
 		  {
 		    rtx_code_label *lab;
 		    lab = gen_label_rtx ();
-		    do_cmp_and_jump (t2, const0_rtx, EQ, compute_mode, lab);
+		    do_cmp_and_jump (t2, const0_rtx, EQ, int_mode, lab);
 		    expand_inc (t1, const1_rtx);
 		    emit_label (lab);
 		    quotient = t1;
 		  }
 		else
-		  quotient = force_operand (gen_rtx_PLUS (compute_mode,
-							  t1, t3),
+		  quotient = force_operand (gen_rtx_PLUS (int_mode, t1, t3),
 					    tquotient);
 		break;
 	      }
@@ -4869,8 +4865,10 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 	break;
 
       case EXACT_DIV_EXPR:
-	if (op1_is_constant && size <= HOST_BITS_PER_WIDE_INT)
+	if (op1_is_constant && HWI_COMPUTABLE_MODE_P (compute_mode))
 	  {
+	    scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
+	    int size = GET_MODE_BITSIZE (int_mode);
 	    HOST_WIDE_INT d = INTVAL (op1);
 	    unsigned HOST_WIDE_INT ml;
 	    int pre_shift;
@@ -4878,16 +4876,16 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 
 	    pre_shift = ctz_or_zero (d);
 	    ml = invert_mod2n (d >> pre_shift, size);
-	    t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
+	    t1 = expand_shift (RSHIFT_EXPR, int_mode, op0,
 			       pre_shift, NULL_RTX, unsignedp);
-	    quotient = expand_mult (compute_mode, t1,
-				    gen_int_mode (ml, compute_mode),
+	    quotient = expand_mult (int_mode, t1,
+				    gen_int_mode (ml, int_mode),
 				    NULL_RTX, 1);
 
 	    insn = get_last_insn ();
 	    set_dst_reg_note (insn, REG_EQUAL,
 			      gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
-					      compute_mode, op0, op1),
+					      int_mode, op0, op1),
 			      quotient);
 	  }
 	break;
@@ -4896,60 +4894,63 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
       case ROUND_MOD_EXPR:
 	if (unsignedp)
 	  {
+	    scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
 	    rtx tem;
 	    rtx_code_label *label;
 	    label = gen_label_rtx ();
-	    quotient = gen_reg_rtx (compute_mode);
-	    remainder = gen_reg_rtx (compute_mode);
+	    quotient = gen_reg_rtx (int_mode);
+	    remainder = gen_reg_rtx (int_mode);
 	    if (expand_twoval_binop (udivmod_optab, op0, op1, quotient, remainder, 1) == 0)
 	      {
 		rtx tem;
-		quotient = expand_binop (compute_mode, udiv_optab, op0, op1,
+		quotient = expand_binop (int_mode, udiv_optab, op0, op1,
 					 quotient, 1, OPTAB_LIB_WIDEN);
-		tem = expand_mult (compute_mode, quotient, op1, NULL_RTX, 1);
-		remainder = expand_binop (compute_mode, sub_optab, op0, tem,
+		tem = expand_mult (int_mode, quotient, op1, NULL_RTX, 1);
+		remainder = expand_binop (int_mode, sub_optab, op0, tem,
 					  remainder, 1, OPTAB_LIB_WIDEN);
 	      }
-	    tem = plus_constant (compute_mode, op1, -1);
-	    tem = expand_shift (RSHIFT_EXPR, compute_mode, tem, 1, NULL_RTX, 1);
-	    do_cmp_and_jump (remainder, tem, LEU, compute_mode, label);
+	    tem = plus_constant (int_mode, op1, -1);
+	    tem = expand_shift (RSHIFT_EXPR, int_mode, tem, 1, NULL_RTX, 1);
+	    do_cmp_and_jump (remainder, tem, LEU, int_mode, label);
 	    expand_inc (quotient, const1_rtx);
 	    expand_dec (remainder, op1);
 	    emit_label (label);
 	  }
 	else
 	  {
+	    scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
+	    int size = GET_MODE_BITSIZE (int_mode);
 	    rtx abs_rem, abs_op1, tem, mask;
 	    rtx_code_label *label;
 	    label = gen_label_rtx ();
-	    quotient = gen_reg_rtx (compute_mode);
-	    remainder = gen_reg_rtx (compute_mode);
+	    quotient = gen_reg_rtx (int_mode);
+	    remainder = gen_reg_rtx (int_mode);
 	    if (expand_twoval_binop (sdivmod_optab, op0, op1, quotient, remainder, 0) == 0)
 	      {
 		rtx tem;
-		quotient = expand_binop (compute_mode, sdiv_optab, op0, op1,
+		quotient = expand_binop (int_mode, sdiv_optab, op0, op1,
 					 quotient, 0, OPTAB_LIB_WIDEN);
-		tem = expand_mult (compute_mode, quotient, op1, NULL_RTX, 0);
-		remainder = expand_binop (compute_mode, sub_optab, op0, tem,
+		tem = expand_mult (int_mode, quotient, op1, NULL_RTX, 0);
+		remainder = expand_binop (int_mode, sub_optab, op0, tem,
 					  remainder, 0, OPTAB_LIB_WIDEN);
 	      }
-	    abs_rem = expand_abs (compute_mode, remainder, NULL_RTX, 1, 0);
-	    abs_op1 = expand_abs (compute_mode, op1, NULL_RTX, 1, 0);
-	    tem = expand_shift (LSHIFT_EXPR, compute_mode, abs_rem,
+	    abs_rem = expand_abs (int_mode, remainder, NULL_RTX, 1, 0);
+	    abs_op1 = expand_abs (int_mode, op1, NULL_RTX, 1, 0);
+	    tem = expand_shift (LSHIFT_EXPR, int_mode, abs_rem,
 				1, NULL_RTX, 1);
-	    do_cmp_and_jump (tem, abs_op1, LTU, compute_mode, label);
-	    tem = expand_binop (compute_mode, xor_optab, op0, op1,
+	    do_cmp_and_jump (tem, abs_op1, LTU, int_mode, label);
+	    tem = expand_binop (int_mode, xor_optab, op0, op1,
 				NULL_RTX, 0, OPTAB_WIDEN);
-	    mask = expand_shift (RSHIFT_EXPR, compute_mode, tem,
+	    mask = expand_shift (RSHIFT_EXPR, int_mode, tem,
 				 size - 1, NULL_RTX, 0);
-	    tem = expand_binop (compute_mode, xor_optab, mask, const1_rtx,
+	    tem = expand_binop (int_mode, xor_optab, mask, const1_rtx,
 				NULL_RTX, 0, OPTAB_WIDEN);
-	    tem = expand_binop (compute_mode, sub_optab, tem, mask,
+	    tem = expand_binop (int_mode, sub_optab, tem, mask,
 				NULL_RTX, 0, OPTAB_WIDEN);
 	    expand_inc (quotient, tem);
-	    tem = expand_binop (compute_mode, xor_optab, mask, op1,
+	    tem = expand_binop (int_mode, xor_optab, mask, op1,
 				NULL_RTX, 0, OPTAB_WIDEN);
-	    tem = expand_binop (compute_mode, sub_optab, tem, mask,
+	    tem = expand_binop (int_mode, sub_optab, tem, mask,
 				NULL_RTX, 0, OPTAB_WIDEN);
 	    expand_dec (remainder, tem);
 	    emit_label (label);
@@ -5443,25 +5444,29 @@ emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
       && (normalizep || STORE_FLAG_VALUE == 1
 	  || val_signbit_p (int_mode, STORE_FLAG_VALUE)))
     {
+      scalar_int_mode int_target_mode;
       subtarget = target;
 
       if (!target)
-	target_mode = int_mode;
-
-      /* If the result is to be wider than OP0, it is best to convert it
-	 first.  If it is to be narrower, it is *incorrect* to convert it
-	 first.  */
-      else if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (int_mode))
+	int_target_mode = int_mode;
+      else
 	{
-	  op0 = convert_modes (target_mode, int_mode, op0, 0);
-	  mode = target_mode;
+	  /* If the result is to be wider than OP0, it is best to convert it
+	     first.  If it is to be narrower, it is *incorrect* to convert it
+	     first.  */
+	  int_target_mode = as_a <scalar_int_mode> (target_mode);
+	  if (GET_MODE_SIZE (int_target_mode) > GET_MODE_SIZE (int_mode))
+	    {
+	      op0 = convert_modes (int_target_mode, int_mode, op0, 0);
+	      int_mode = int_target_mode;
+	    }
 	}
 
-      if (target_mode != mode)
+      if (int_target_mode != int_mode)
 	subtarget = 0;
 
       if (code == GE)
-	op0 = expand_unop (mode, one_cmpl_optab, op0,
+	op0 = expand_unop (int_mode, one_cmpl_optab, op0,
 			   ((STORE_FLAG_VALUE == 1 || normalizep)
 			    ? 0 : subtarget), 0);
 
@@ -5469,12 +5474,12 @@ emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
 	/* If we are supposed to produce a 0/1 value, we want to do
 	   a logical shift from the sign bit to the low-order bit; for
 	   a -1/0 value, we do an arithmetic shift.  */
-	op0 = expand_shift (RSHIFT_EXPR, mode, op0,
-			    GET_MODE_BITSIZE (mode) - 1,
+	op0 = expand_shift (RSHIFT_EXPR, int_mode, op0,
+			    GET_MODE_BITSIZE (int_mode) - 1,
 			    subtarget, normalizep != -1);
 
-      if (mode != target_mode)
-	op0 = convert_modes (target_mode, mode, op0, 0);
+      if (int_mode != int_target_mode)
+	op0 = convert_modes (int_target_mode, int_mode, op0, 0);
 
       return op0;
     }
diff --git a/gcc/expr.c b/gcc/expr.c
index fb7709a..2e7bff5 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5236,8 +5236,8 @@ expand_assignment (tree to, tree from, bool nontemporal)
 	{
 	  if (POINTER_TYPE_P (TREE_TYPE (to)))
 	    value = convert_memory_address_addr_space
-		      (GET_MODE (to_rtx), value,
-		       TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
+	      (as_a <scalar_int_mode> (GET_MODE (to_rtx)), value,
+	       TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
 
 	  emit_move_insn (to_rtx, value);
 	}
@@ -11068,7 +11068,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 }
 \f
 /* Subroutine of above: reduce EXP to the precision of TYPE (in the
-   signedness of TYPE), possibly returning the result in TARGET.  */
+   signedness of TYPE), possibly returning the result in TARGET.
+   TYPE is known to be a partial integer type.  */
 static rtx
 reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
 {
@@ -11084,18 +11085,17 @@ reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
     }
   else if (TYPE_UNSIGNED (type))
     {
-      machine_mode mode = GET_MODE (exp);
+      scalar_int_mode mode = as_a <scalar_int_mode> (GET_MODE (exp));
       rtx mask = immed_wide_int_const
 	(wi::mask (prec, false, GET_MODE_PRECISION (mode)), mode);
       return expand_and (mode, exp, mask, target);
     }
   else
     {
-      int count = GET_MODE_PRECISION (GET_MODE (exp)) - prec;
-      exp = expand_shift (LSHIFT_EXPR, GET_MODE (exp),
-			  exp, count, target, 0);
-      return expand_shift (RSHIFT_EXPR, GET_MODE (exp),
-			   exp, count, target, 0);
+      scalar_int_mode mode = as_a <scalar_int_mode> (GET_MODE (exp));
+      int count = GET_MODE_PRECISION (mode) - prec;
+      exp = expand_shift (LSHIFT_EXPR, mode, exp, count, target, 0);
+      return expand_shift (RSHIFT_EXPR, mode, exp, count, target, 0);
     }
 }
 \f
diff --git a/gcc/function.c b/gcc/function.c
index 0829fbe..8a887e4 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5600,8 +5600,8 @@ expand_function_end (void)
       REG_FUNCTION_VALUE_P (outgoing) = 1;
 
       /* The address may be ptr_mode and OUTGOING may be Pmode.  */
-      value_address = convert_memory_address (GET_MODE (outgoing),
-					      value_address);
+      scalar_int_mode mode = as_a <scalar_int_mode> (GET_MODE (outgoing));
+      value_address = convert_memory_address (mode, value_address);
 
       emit_move_insn (outgoing, value_address);
 
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 3b06dc2..61e844f 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -582,7 +582,8 @@ static void
 expand_arith_overflow_result_store (tree lhs, rtx target,
 				    machine_mode mode, rtx res)
 {
-  machine_mode tgtmode = GET_MODE_INNER (GET_MODE (target));
+  scalar_int_mode tgtmode
+    = as_a <scalar_int_mode> (GET_MODE_INNER (GET_MODE (target)));
   rtx lres = res;
   if (tgtmode != mode)
     {
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index 1dff2ff..b032534 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -436,7 +436,8 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
   counter_reg = XEXP (condition, 0);
   if (GET_CODE (counter_reg) == PLUS)
     counter_reg = XEXP (counter_reg, 0);
-  mode = GET_MODE (counter_reg);
+  /* These patterns must operate on integer counters.  */
+  mode = as_a <scalar_int_mode> (GET_MODE (counter_reg));
 
   increment_count = false;
   switch (GET_CODE (condition))
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index 58f6e0c..724b03b 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -973,15 +973,15 @@ lto_type_for_mode (machine_mode mode, int unsigned_p)
   if (mode == TYPE_MODE (void_type_node))
     return void_type_node;
 
-  if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
-    return (unsigned_p
-	    ? make_unsigned_type (GET_MODE_PRECISION (mode))
-	    : make_signed_type (GET_MODE_PRECISION (mode)));
-
-  if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
-    return (unsigned_p
-	    ? make_unsigned_type (GET_MODE_PRECISION (mode))
-	    : make_signed_type (GET_MODE_PRECISION (mode)));
+  if (mode == TYPE_MODE (build_pointer_type (char_type_node))
+      || mode == TYPE_MODE (build_pointer_type (integer_type_node)))
+    {
+      unsigned int precision
+	= GET_MODE_PRECISION (as_a <scalar_int_mode> (mode));
+      return (unsigned_p
+	      ? make_unsigned_type (precision)
+	      : make_signed_type (precision));
+    }
 
   if (COMPLEX_MODE_P (mode))
     {
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 77ca419..054457a 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -1230,8 +1230,8 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
 	     it back to the proper size to fit in the broadcast vector.  */
 	  machine_mode inner_mode = GET_MODE_INNER (mode);
 	  if (!CONST_INT_P (op1)
-	      && (GET_MODE_BITSIZE (inner_mode)
-		  < GET_MODE_BITSIZE (GET_MODE (op1))))
+	      && (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (op1)))
+		  > GET_MODE_BITSIZE (inner_mode)))
 	    op1 = force_reg (inner_mode,
 			     simplify_gen_unary (TRUNCATE, inner_mode, op1,
 						 GET_MODE (op1)));
@@ -1376,11 +1376,13 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
       && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
     {
       unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
-      machine_mode op1_mode;
+      scalar_int_mode op1_mode;
 
       double_shift_mask = targetm.shift_truncation_mask (int_mode);
       shift_mask = targetm.shift_truncation_mask (word_mode);
-      op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
+      op1_mode = (GET_MODE (op1) != VOIDmode
+		  ? as_a <scalar_int_mode> (GET_MODE (op1))
+		  : word_mode);
 
       /* Apply the truncation to constant shifts.  */
       if (double_shift_mask > 0 && CONST_INT_P (op1))
@@ -3009,24 +3011,32 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
 		 result.  Similarly for clrsb.  */
 	      if ((unoptab == clz_optab || unoptab == clrsb_optab)
 		  && temp != 0)
-		temp = expand_binop
-		  (wider_mode, sub_optab, temp,
-		   gen_int_mode (GET_MODE_PRECISION (wider_mode)
-				 - GET_MODE_PRECISION (mode),
-				 wider_mode),
-		   target, true, OPTAB_DIRECT);
+		{
+		  scalar_int_mode wider_int_mode
+		    = as_a <scalar_int_mode> (wider_mode);
+		  int_mode = as_a <scalar_int_mode> (mode);
+		  temp = expand_binop
+		    (wider_mode, sub_optab, temp,
+		     gen_int_mode (GET_MODE_PRECISION (wider_int_mode)
+				   - GET_MODE_PRECISION (int_mode),
+				   wider_int_mode),
+		     target, true, OPTAB_DIRECT);
+		}
 
 	      /* Likewise for bswap.  */
 	      if (unoptab == bswap_optab && temp != 0)
 		{
-		  gcc_assert (GET_MODE_PRECISION (wider_mode)
-			      == GET_MODE_BITSIZE (wider_mode)
-			      && GET_MODE_PRECISION (mode)
-				 == GET_MODE_BITSIZE (mode));
-
-		  temp = expand_shift (RSHIFT_EXPR, wider_mode, temp,
-				       GET_MODE_BITSIZE (wider_mode)
-				       - GET_MODE_BITSIZE (mode),
+		  scalar_int_mode wider_int_mode
+		    = as_a <scalar_int_mode> (wider_mode);
+		  int_mode = as_a <scalar_int_mode> (mode);
+		  gcc_assert (GET_MODE_PRECISION (wider_int_mode)
+			      == GET_MODE_BITSIZE (wider_int_mode)
+			      && GET_MODE_PRECISION (int_mode)
+				 == GET_MODE_BITSIZE (int_mode));
+
+		  temp = expand_shift (RSHIFT_EXPR, wider_int_mode, temp,
+				       GET_MODE_BITSIZE (wider_int_mode)
+				       - GET_MODE_BITSIZE (int_mode),
 				       NULL_RTX, true);
 		}
 
@@ -3253,7 +3263,7 @@ static rtx
 expand_copysign_absneg (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
 		        int bitpos, bool op0_is_abs)
 {
-  machine_mode imode;
+  scalar_int_mode imode;
   enum insn_code icode;
   rtx sign;
   rtx_code_label *label;
@@ -3266,7 +3276,7 @@ expand_copysign_absneg (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
   icode = optab_handler (signbit_optab, mode);
   if (icode != CODE_FOR_nothing)
     {
-      imode = insn_data[(int) icode].operand[0].mode;
+      imode = as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode);
       sign = gen_reg_rtx (imode);
       emit_unop_insn (icode, sign, op1, UNKNOWN);
     }
@@ -3798,10 +3808,10 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
 	    continue;
 
 	  /* Must make sure the size fits the insn's mode.  */
-	  if ((CONST_INT_P (size)
-	       && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
-	      || (GET_MODE_BITSIZE (GET_MODE (size))
-		  > GET_MODE_BITSIZE (cmp_mode)))
+	  if (CONST_INT_P (size)
+	      ? INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode))
+	      : (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (size)))
+		 > GET_MODE_BITSIZE (cmp_mode)))
 	    continue;
 
 	  result_mode = insn_data[cmp_code].operand[0].mode;
@@ -6930,8 +6940,8 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
       goto input;
 
     case EXPAND_ADDRESS:
-      gcc_assert (mode != VOIDmode);
-      op->value = convert_memory_address (mode, op->value);
+      op->value = convert_memory_address (as_a <scalar_int_mode> (mode),
+					  op->value);
       goto input;
 
     case EXPAND_INTEGER:
diff --git a/gcc/recog.c b/gcc/recog.c
index 3a17de2..317ec29 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1189,8 +1189,9 @@ const_scalar_int_operand (rtx op, machine_mode mode)
 
   if (mode != VOIDmode)
     {
-      int prec = GET_MODE_PRECISION (mode);
-      int bitsize = GET_MODE_BITSIZE (mode);
+      scalar_int_mode int_mode = as_a <scalar_int_mode> (mode);
+      int prec = GET_MODE_PRECISION (int_mode);
+      int bitsize = GET_MODE_BITSIZE (int_mode);
 
       if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
 	return 0;
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 129f69f..a7fb5cf 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -5741,7 +5741,7 @@ get_address_mode (rtx mem)
   gcc_assert (MEM_P (mem));
   mode = GET_MODE (XEXP (mem, 0));
   if (mode != VOIDmode)
-    return mode;
+    return as_a <scalar_int_mode> (mode);
   return targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
 }
 \f
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index ac7cb24..f4997bf 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -917,7 +917,7 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
 {
   enum rtx_code reversed;
   rtx temp;
-  scalar_int_mode inner, int_mode, op0_mode;
+  scalar_int_mode inner, int_mode, op_mode, op0_mode;
 
   switch (code)
     {
@@ -1151,26 +1151,27 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
 	  && XEXP (op, 1) == const0_rtx
 	  && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
 	{
+	  int_mode = as_a <scalar_int_mode> (mode);
 	  int isize = GET_MODE_PRECISION (inner);
 	  if (STORE_FLAG_VALUE == 1)
 	    {
 	      temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
 					  GEN_INT (isize - 1));
-	      if (mode == inner)
+	      if (int_mode == inner)
 		return temp;
-	      if (GET_MODE_PRECISION (mode) > isize)
-		return simplify_gen_unary (SIGN_EXTEND, mode, temp, inner);
-	      return simplify_gen_unary (TRUNCATE, mode, temp, inner);
+	      if (GET_MODE_PRECISION (int_mode) > isize)
+		return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
+	      return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
 	    }
 	  else if (STORE_FLAG_VALUE == -1)
 	    {
 	      temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
 					  GEN_INT (isize - 1));
-	      if (mode == inner)
+	      if (int_mode == inner)
 		return temp;
-	      if (GET_MODE_PRECISION (mode) > isize)
-		return simplify_gen_unary (ZERO_EXTEND, mode, temp, inner);
-	      return simplify_gen_unary (TRUNCATE, mode, temp, inner);
+	      if (GET_MODE_PRECISION (int_mode) > isize)
+		return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
+	      return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
 	    }
 	}
       break;
@@ -1490,12 +1491,13 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
 	  && is_a <scalar_int_mode> (mode, &int_mode)
 	  && CONST_INT_P (XEXP (op, 1))
 	  && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
-	  && GET_MODE_BITSIZE (GET_MODE (op)) > INTVAL (XEXP (op, 1)))
+	  && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
+	      GET_MODE_BITSIZE (op_mode) > INTVAL (XEXP (op, 1))))
 	{
 	  scalar_int_mode tmode;
 	  gcc_assert (GET_MODE_BITSIZE (int_mode)
-		      > GET_MODE_BITSIZE (GET_MODE (op)));
-	  if (int_mode_for_size (GET_MODE_BITSIZE (GET_MODE (op))
+		      > GET_MODE_BITSIZE (op_mode));
+	  if (int_mode_for_size (GET_MODE_BITSIZE (op_mode)
 				 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
 	    {
 	      rtx inner =
@@ -1607,10 +1609,11 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
 	  && is_a <scalar_int_mode> (mode, &int_mode)
 	  && CONST_INT_P (XEXP (op, 1))
 	  && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
-	  && GET_MODE_PRECISION (GET_MODE (op)) > INTVAL (XEXP (op, 1)))
+	  && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
+	      GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
 	{
 	  scalar_int_mode tmode;
-	  if (int_mode_for_size (GET_MODE_PRECISION (GET_MODE (op))
+	  if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
 				 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
 	    {
 	      rtx inner =
@@ -5400,10 +5403,10 @@ simplify_cond_clz_ctz (rtx x, rtx_code cmp_code, rtx true_val, rtx false_val)
     return NULL_RTX;
 
   HOST_WIDE_INT op_val;
-  if (((op_code == CLZ
-	&& CLZ_DEFINED_VALUE_AT_ZERO (GET_MODE (on_nonzero), op_val))
-      || (op_code == CTZ
-	  && CTZ_DEFINED_VALUE_AT_ZERO (GET_MODE (on_nonzero), op_val)))
+  scalar_int_mode mode ATTRIBUTE_UNUSED
+    = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
+  if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
+       || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
       && op_val == INTVAL (on_zero))
     return on_nonzero;
 
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 0c8bc64..df60852 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -621,7 +621,9 @@ get_nl_goto_field (struct nesting_info *info)
       else
 	type = lang_hooks.types.type_for_mode (Pmode, 1);
 
-      size = GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL));
+      scalar_int_mode mode
+	= as_a <scalar_int_mode> (STACK_SAVEAREA_MODE (SAVE_NONLOCAL));
+      size = GET_MODE_SIZE (mode);
       size = size / GET_MODE_SIZE (Pmode);
       size = size + 1;
 
diff --git a/gcc/tree.c b/gcc/tree.c
index b58f503..d7bbcb3 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -10936,6 +10936,7 @@ tree
 build_vector_type_for_mode (tree innertype, machine_mode mode)
 {
   int nunits;
+  unsigned int bitsize;
 
   switch (GET_MODE_CLASS (mode))
     {
@@ -10950,11 +10951,9 @@ build_vector_type_for_mode (tree innertype, machine_mode mode)
 
     case MODE_INT:
       /* Check that there are no leftover bits.  */
-      gcc_assert (GET_MODE_BITSIZE (mode)
-		  % TREE_INT_CST_LOW (TYPE_SIZE (innertype)) == 0);
-
-      nunits = GET_MODE_BITSIZE (mode)
-	       / TREE_INT_CST_LOW (TYPE_SIZE (innertype));
+      bitsize = GET_MODE_BITSIZE (as_a <scalar_int_mode> (mode));
+      gcc_assert (bitsize % TREE_INT_CST_LOW (TYPE_SIZE (innertype)) == 0);
+      nunits = bitsize / TREE_INT_CST_LOW (TYPE_SIZE (innertype));
       break;
 
     default:
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 31f7a31..bec9195 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -991,7 +991,8 @@ use_narrower_mode (rtx x, machine_mode mode, machine_mode wmode)
       /* Ensure shift amount is not wider than mode.  */
       if (GET_MODE (op1) == VOIDmode)
 	op1 = lowpart_subreg (mode, op1, wmode);
-      else if (GET_MODE_PRECISION (mode) < GET_MODE_PRECISION (GET_MODE (op1)))
+      else if (GET_MODE_PRECISION (mode)
+	       < GET_MODE_PRECISION (as_a <scalar_int_mode> (GET_MODE (op1))))
 	op1 = lowpart_subreg (mode, op1, GET_MODE (op1));
       return simplify_gen_binary (ASHIFT, mode, op0, op1);
     default:

  parent reply	other threads:[~2016-12-09 13:16 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-09 12:48 [0/67] Add wrapper classes for machine_modes Richard Sandiford
2016-12-09 12:50 ` [1/67] Add an E_ prefix to mode names and update case statements Richard Sandiford
2016-12-09 12:52 ` [2/67] Make machine_mode a class Richard Sandiford
2016-12-15 22:34   ` Trevor Saunders
2016-12-09 12:53 ` [3/67] Add GDB pretty printer for machine mode classes Richard Sandiford
2016-12-09 12:54 ` [4/67] Add FOR_EACH iterators for modes Richard Sandiford
2016-12-09 12:55 ` [6/67] Make GET_MODE_WIDER return an opt_mode Richard Sandiford
2016-12-09 12:55 ` [5/67] Small tweak to array_value_type Richard Sandiford
2016-12-09 12:57 ` [7/67] Add scalar_float_mode Richard Sandiford
2016-12-09 14:19   ` David Malcolm
2016-12-09 14:30     ` Richard Sandiford
2016-12-09 12:57 ` [8/67] Simplify gen_trunc/extend_conv_libfunc Richard Sandiford
2016-12-09 12:58 ` [9/67] Add SCALAR_FLOAT_TYPE_MODE Richard Sandiford
2016-12-09 12:59 ` [10/67] Make assemble_real take a scalar_float_mode Richard Sandiford
2016-12-09 13:00 ` [0/67] Add wrapper classes for machine_modes Richard Biener
2016-12-09 13:54   ` Richard Sandiford
2016-12-09 13:00 ` [11/67] Add a float_mode_for_size helper function Richard Sandiford
2016-12-09 13:00 ` [12/67] Use opt_scalar_float_mode when iterating over float modes Richard Sandiford
2016-12-09 13:01 ` [13/67] Make floatn_mode return an opt_scalar_float_mode Richard Sandiford
2016-12-09 13:02 ` [14/67] Make libgcc_floating_mode_supported_p take a scalar_float_mode Richard Sandiford
2016-12-09 13:03 ` [16/67] Add scalar_int_mode_pod Richard Sandiford
2016-12-09 13:03 ` [15/67] Add scalar_int_mode Richard Sandiford
2016-12-09 13:04 ` [17/67] Add an int_mode_for_size helper function Richard Sandiford
2016-12-09 13:05 ` [19/67] Add a smallest_int_mode_for_size " Richard Sandiford
2016-12-09 13:05 ` [18/67] Make int_mode_for_mode return an opt_scalar_int_mode Richard Sandiford
2016-12-09 13:06 ` [20/67] Replace MODE_INT checks with is_int_mode Richard Sandiford
2016-12-09 13:07 ` [21/67] Replace SCALAR_INT_MODE_P checks with is_a <scalar_int_mode> Richard Sandiford
2016-12-09 13:07 ` [22/67] Replace !VECTOR_MODE_P " Richard Sandiford
2016-12-09 13:08 ` [23/67] Replace != VOIDmode checks " Richard Sandiford
2016-12-09 13:08 ` [24/67] Replace a != BLKmode check " Richard Sandiford
2016-12-09 13:22   ` Richard Biener
2016-12-09 14:42     ` Richard Sandiford
2016-12-09 13:09 ` [25/67] Use is_a <scalar_int_mode> for bitmask optimisations Richard Sandiford
2016-12-09 13:10 ` [27/67] Use is_a <scalar_int_mode> before LOAD_EXTEND_OP Richard Sandiford
2016-12-09 13:10 ` [26/67] Use is_a <scalar_int_mode> in subreg/extract simplifications Richard Sandiford
2016-12-09 13:11 ` [28/67] Use is_a <scalar_int_mode> for miscellaneous types of test Richard Sandiford
2016-12-09 13:12 ` [29/67] Make some *_loc_descriptor helpers take scalar_int_mode Richard Sandiford
2016-12-09 13:12 ` [30/67] Use scalar_int_mode for doubleword splits Richard Sandiford
2016-12-09 13:13 ` [31/67] Use scalar_int_mode for move2add Richard Sandiford
2016-12-09 13:14 ` [33/67] Add a NARROWEST_INT_MODE macro Richard Sandiford
2016-12-09 13:14 ` [32/67] Check is_a <scalar_int_mode> before calling valid_pointer_mode Richard Sandiford
2016-12-09 13:15 ` [34/67] Add a SCALAR_INT_TYPE_MODE macro Richard Sandiford
2016-12-09 13:16 ` [36/67] Use scalar_int_mode in the RTL iv routines Richard Sandiford
2016-12-09 13:16 ` Richard Sandiford [this message]
2016-12-09 13:17 ` [38/67] Move SCALAR_INT_MODE_P out of strict_volatile_bitfield_p Richard Sandiford
2016-12-09 13:17 ` [37/67] Use scalar_int_mode when emitting cstores Richard Sandiford
2016-12-09 13:18 ` [39/67] Two changes to the get_best_mode interface Richard Sandiford
2016-12-09 13:19 ` [40/67] Use scalar_int_mode for extraction_insn fields Richard Sandiford
2016-12-09 13:20 ` [41/67] Split scalar integer handling out of force_to_mode Richard Sandiford
2016-12-09 13:20 ` [42/67] Use scalar_int_mode in simplify_shift_const_1 Richard Sandiford
2016-12-09 13:22 ` [43/67] Use scalar_int_mode in simplify_comparison Richard Sandiford
2016-12-09 13:22 ` [44/67] Make simplify_and_const_int take a scalar_int_mode Richard Sandiford
2016-12-09 13:23 ` [45/67] Make extract_left_shift " Richard Sandiford
2016-12-09 13:23 ` [46/67] Make widest_int_mode_for_size return " Richard Sandiford
2016-12-09 13:24 ` [47/67] Make subroutines of nonzero_bits operate on scalar_int_mode Richard Sandiford
2016-12-09 13:25 ` [49/67] Simplify nonzero/num_sign_bits hooks Richard Sandiford
2016-12-09 13:25 ` [48/67] Make subroutines of num_sign_bit_copies operate on scalar_int_mode Richard Sandiford
2016-12-09 13:28 ` [50/67] Add helper routines for SUBREG_PROMOTED_VAR_P subregs Richard Sandiford
2016-12-09 13:30 ` [51/67] Use opt_scalar_int_mode when iterating over integer modes Richard Sandiford
2016-12-09 13:30 ` [52/67] Use scalar_int_mode in extract/store_bit_field Richard Sandiford
2016-12-09 13:31 ` [54/67] Add explicit int checks for alternative optab implementations Richard Sandiford
2016-12-09 13:31 ` [53/67] Pass a mode to const_scalar_mask_from_tree Richard Sandiford
2016-12-09 13:33 ` [56/67] Use the more specific type when two modes are known to be equal Richard Sandiford
2016-12-09 13:33 ` [55/67] Use scalar_int_mode in simplify_const_unary_operation Richard Sandiford
2016-12-09 13:34 ` [57/67] Use scalar_int_mode in expand_expr_addr_expr Richard Sandiford
2016-12-09 13:35 ` [58/67] Use scalar_int_mode in a try_combine optimisation Richard Sandiford
2016-12-09 13:36 ` [60/67] Pass scalar_int_modes to do_jump_by_parts_* Richard Sandiford
2016-12-09 13:36 ` [59/67] Add a rtx_jump_table_data::get_data_mode helper Richard Sandiford
2016-12-09 13:37 ` [61/67] Use scalar_int_mode in the AArch64 port Richard Sandiford
2016-12-09 13:38 ` [63/67] Simplifications after type switch Richard Sandiford
2016-12-09 13:38 ` [62/67] Big machine_mode to scalar_int_mode replacement Richard Sandiford
2016-12-09 13:40 ` [64/67] Add a scalar_mode class Richard Sandiford
2016-12-09 13:40 ` [65/67] Use scalar_mode in the AArch64 port Richard Sandiford
2016-12-09 13:40 ` [66/67] Add a scalar_mode_pod class Richard Sandiford
2016-12-09 13:41 ` [67/67] Add a complex_mode class Richard Sandiford
2016-12-09 18:20 ` [0/67] Add wrapper classes for machine_modes Sandra Loosemore
2017-05-05  7:08 ` Jeff Law
2017-05-24 14:33   ` Richard Sandiford
2017-06-28 17:27     ` Jeff Law

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87a8c5jl9t.fsf@e105548-lin.cambridge.arm.com \
    --to=richard.sandiford@arm.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).