Patchwork [10/11] Expander fixes for 40-bit integers

login
register
mail settings
Submitter Bernd Schmidt
Date July 1, 2011, 5:41 p.m.
Message ID <4E0E06AC.3080209@codesourcery.com>
Download mbox | patch
Permalink /patch/102939/
State New
Headers show

Comments

Bernd Schmidt - July 1, 2011, 5:41 p.m.
This fixes a few random problems that occur when you add a new
fractional integer mode - for example, trying to expand doubleword
shifts normally for them, or trying to generate 40->64 bit widening
multiply. In some cases where it seems we can only deal with modes where
precision == bitsisze, I've added asserts.


Bernd
* optabs.c (expand_binop): Tighten conditions for doubleword
	expansions.
	(widen_bswap): Assert that mode bitsize and precision are the
	same.
	* stor-layout.c (get_best_mode): Skip modes that have lower
	precision than bitsize.
	* recog.c (simplify_while_replacing): Assert that bitsize and
	precision are the same.
Richard Henderson - July 6, 2011, 6:32 p.m.
On 07/01/2011 10:41 AM, Bernd Schmidt wrote:
> 	* optabs.c (expand_binop): Tighten conditions for doubleword
> 	expansions.
> 	(widen_bswap): Assert that mode bitsize and precision are the
> 	same.
> 	* stor-layout.c (get_best_mode): Skip modes that have lower
> 	precision than bitsize.
> 	* recog.c (simplify_while_replacing): Assert that bitsize and
> 	precision are the same.

Ok.


r~

Patch

Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c.orig
+++ gcc/optabs.c
@@ -1428,12 +1428,12 @@  expand_binop (enum machine_mode mode, op
      takes operands of this mode and makes a wider mode.  */
 
   if (binoptab == smul_optab
-      && GET_MODE_WIDER_MODE (mode) != VOIDmode
+      && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
       && (optab_handler ((unsignedp ? umul_widen_optab : smul_widen_optab),
-			 GET_MODE_WIDER_MODE (mode))
+			 GET_MODE_2XWIDER_MODE (mode))
 	  != CODE_FOR_nothing))
     {
-      temp = expand_binop (GET_MODE_WIDER_MODE (mode),
+      temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
 			   unsignedp ? umul_widen_optab : smul_widen_optab,
 			   op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
 
@@ -1575,6 +1575,7 @@  expand_binop (enum machine_mode mode, op
       && mclass == MODE_INT
       && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
+      && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode)
       && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
       && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
       && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
@@ -1647,7 +1648,7 @@  expand_binop (enum machine_mode mode, op
   if ((binoptab == rotl_optab || binoptab == rotr_optab)
       && mclass == MODE_INT
       && CONST_INT_P (op1)
-      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
+      && GET_MODE_PRECISION (mode) == 2 * BITS_PER_WORD
       && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
       && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
     {
@@ -2463,6 +2464,8 @@  widen_bswap (enum machine_mode mode, rtx
   x = widen_operand (op0, wider_mode, mode, true, true);
   x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
 
+  gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
+	      && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
   if (x != 0)
     x = expand_shift (RSHIFT_EXPR, wider_mode, x,
 		      GET_MODE_BITSIZE (wider_mode)
Index: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c.orig
+++ gcc/stor-layout.c
@@ -2389,7 +2389,8 @@  get_best_mode (int bitsize, int bitpos,
        mode = GET_MODE_WIDER_MODE (mode))
     {
       unit = GET_MODE_BITSIZE (mode);
-      if ((bitpos % unit) + bitsize <= unit)
+      if (unit == GET_MODE_PRECISION (mode)
+	  && (bitpos % unit) + bitsize <= unit)
 	break;
     }
 
@@ -2414,7 +2415,8 @@  get_best_mode (int bitsize, int bitpos,
 	   tmode = GET_MODE_WIDER_MODE (tmode))
 	{
 	  unit = GET_MODE_BITSIZE (tmode);
-	  if (bitpos / unit == (bitpos + bitsize - 1) / unit
+	  if (unit == GET_MODE_PRECISION (tmode)
+	      && bitpos / unit == (bitpos + bitsize - 1) / unit
 	      && unit <= BITS_PER_WORD
 	      && unit <= MIN (align, BIGGEST_ALIGNMENT)
 	      && (largest_mode == VOIDmode
Index: gcc/recog.c
===================================================================
--- gcc/recog.c.orig
+++ gcc/recog.c
@@ -638,6 +638,8 @@  simplify_while_replacing (rtx *loc, rtx
 		  (GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (wanted_mode) -
 		   offset);
 
+	      gcc_assert (GET_MODE_PRECISION (wanted_mode)
+			  == GET_MODE_BITSIZE (wanted_mode));
 	      pos %= GET_MODE_BITSIZE (wanted_mode);
 
 	      newmem = adjust_address_nv (XEXP (x, 0), wanted_mode, offset);