RFA: Use gen_int_mode in plus_constant

Richard Sandiford rsandifo@linux.vnet.ibm.com
Tue May 21 09:27:00 GMT 2013


Andreas Krebbel <krebbel@linux.vnet.ibm.com> writes:
> On 21/05/13 10:39, Richard Sandiford wrote:
>> Andreas Krebbel <krebbel@linux.vnet.ibm.com> writes:
>>> On 30/04/13 16:56, Richard Sandiford wrote:
>>>> This patch fixes out the GEN_INT/gen_int_mode that Richard pointed out
>>>> in the wide-int review.  It also passes "mode" rather than "VOIDmode"
>>>> to immed_double_int_const.  (As discussed in that thread, the latter
>>>> change shouldn't make any difference in practice, but is still more
>>>> correct in principle.)
>>>>
>>>> Bootstrapped & regression-tested on x86_64-linux-gnu.  OK to install?
>>>>
>>>> Richard
>>>>
>>>> gcc/
>>>> 	* explow.c (plus_constant): Pass "mode" to immed_double_int_const.
>>>> 	Use gen_int_mode rather than GEN_INT.
>>>>
>>>> Index: gcc/explow.c
>>>> ===================================================================
>>>> --- gcc/explow.c	2013-02-25 09:41:58.000000000 +0000
>>>> +++ gcc/explow.c	2013-04-30 15:52:57.270362112 +0100
>>>> @@ -106,10 +106,10 @@ plus_constant (enum machine_mode mode, r
>>>>  	  if (overflow)
>>>>  	    gcc_unreachable ();
>>>>
>>>> -	  return immed_double_int_const (v, VOIDmode);
>>>> +	  return immed_double_int_const (v, mode);
>>>>  	}
>>>>
>>>> -      return GEN_INT (INTVAL (x) + c);
>>>> +      return gen_int_mode (INTVAL (x) + c, mode);
>>>
>>> This calls trunc_int_for_mode which fails for mode == VOIDmode.
>>> On s390x gcc.c-torture/compile/20021008-1.c fails due to this.
>> 
>> But it's invalid to pass mode == VOIDmode to plus_constant too.
>> Which caller is causing trouble?
>> 
>> Thanks,
>> Richard
>> 
>
> Hi Richard,
>
> the call comes from reload when checking a const_int memory address.

Ah, thanks.  Could you give the patch below a go?

Richard


gcc/
	* recog.c (offsettable_address_addr_space_p): Fix calculation of
	address mode.  Move pointer mode initialization to the same place.

Index: gcc/recog.c
===================================================================
--- gcc/recog.c	2013-04-29 12:38:00.000000000 +0100
+++ gcc/recog.c	2013-05-21 10:21:24.553671961 +0100
@@ -1953,9 +1953,6 @@ offsettable_address_addr_space_p (int st
     (strictp ? strict_memory_address_addr_space_p
 	     : memory_address_addr_space_p);
   unsigned int mode_sz = GET_MODE_SIZE (mode);
-#ifdef POINTERS_EXTEND_UNSIGNED
-  enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
-#endif
 
   if (CONSTANT_ADDRESS_P (y))
     return 1;
@@ -1966,6 +1963,13 @@ offsettable_address_addr_space_p (int st
   if (mode_dependent_address_p (y, as))
     return 0;
 
+  enum machine_mode address_mode = GET_MODE (y);
+  if (address_mode == VOIDmode)
+    address_mode = targetm.addr_space.address_mode (as);
+#ifdef POINTERS_EXTEND_UNSIGNED
+  enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
+#endif
+
   /* ??? How much offset does an offsettable BLKmode reference need?
      Clearly that depends on the situation in which it's being used.
      However, the current situation in which we test 0xffffffff is
@@ -1981,7 +1985,7 @@ offsettable_address_addr_space_p (int st
       int good;
 
       y1 = *y2;
-      *y2 = plus_constant (GET_MODE (y), *y2, mode_sz - 1);
+      *y2 = plus_constant (address_mode, *y2, mode_sz - 1);
       /* Use QImode because an odd displacement may be automatically invalid
 	 for any wider mode.  But it should be valid for a single byte.  */
       good = (*addressp) (QImode, y, as);
@@ -2002,20 +2006,20 @@ offsettable_address_addr_space_p (int st
   if (GET_CODE (y) == LO_SUM
       && mode != BLKmode
       && mode_sz <= GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT)
-    z = gen_rtx_LO_SUM (GET_MODE (y), XEXP (y, 0),
-			plus_constant (GET_MODE (y), XEXP (y, 1),
+    z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0),
+			plus_constant (address_mode, XEXP (y, 1),
 				       mode_sz - 1));
 #ifdef POINTERS_EXTEND_UNSIGNED
   /* Likewise for a ZERO_EXTEND from pointer_mode.  */
   else if (POINTERS_EXTEND_UNSIGNED > 0
 	   && GET_CODE (y) == ZERO_EXTEND
 	   && GET_MODE (XEXP (y, 0)) == pointer_mode)
-    z = gen_rtx_ZERO_EXTEND (GET_MODE (y),
+    z = gen_rtx_ZERO_EXTEND (address_mode,
 			     plus_constant (pointer_mode, XEXP (y, 0),
 					    mode_sz - 1));
 #endif
   else
-    z = plus_constant (GET_MODE (y), y, mode_sz - 1);
+    z = plus_constant (address_mode, y, mode_sz - 1);
 
   /* Use QImode because an odd displacement may be automatically invalid
      for any wider mode.  But it should be valid for a single byte.  */



More information about the Gcc-patches mailing list