[PATCH] assign_stack_local big-endian correction fix

David Edelsohn dje@watson.ibm.com
Thu Aug 4 13:54:00 GMT 2005


	assign_stack_local_1 adds a correction on big-endian systems when
the mode size does not match the requested allocation size:

  if (BYTES_BIG_ENDIAN && mode != BLKmode)
    bigend_correction = size - GET_MODE_SIZE (mode);

For example, allocating 4 bytes on the stack in HImode biases the pointer
to the least significant bytes.  If one accesses the entire stack slot in
a wider mode, e.g. SImode, the value continues to be interpreted
correctly.

	The code implementing the correction makes two assumptions: 1) the
allocation size is larger than the mode size; and 2) the allocation size
is a multiple of the mode size.  When the assumptions break down, the
returned MEM can point outside the allocated stack slot and the alignment
may no longer hold true.

	In my specific case, I am trying to allocate a 4 byte object with
V4SImode alignment for use with the Altivec lve and stve vector element
instructions.  assign_stack_local_1 creates a correctly aligned offset on
the stack, but bigend_correction is computed as 4 - 16 = -12, correcting
the offset to point outside the stack slot and with an incorrect
alignment.  Wonderful results ensue.

	In discussions with Ian Lance Taylor, we both agree that
assign_stack_local_1 should not apply an endian correction to stack
allocations smaller than the mode size.  This patch implements that
understanding.

	One can address the more general issue of allocating a stack slot
that is not a multiple of the mode size (more specifically the alignment),
but that does not occur in practice and the ratio is reasonable semantics
for assign_stack_local_1 to assume.

Bootstrapped and regression tested on powerpc-ibm-aix5.2.0.0.  Okay for
mainline?

Thanks, David

:ADDPATCH middle-end:


2005-08-04  David Edelsohn  <edelsohn@gnu.org>
	    Ian Lance Taylor <ian@airs.com>

	* function.c (assign_stack_local_1): Do not correct stack slot
	address if allocation size is smaller than mode size.

Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.638
diff -c -p -r1.638 function.c
*** function.c	22 Jul 2005 07:13:42 -0000	1.638
--- function.c	3 Aug 2005 18:56:49 -0000
*************** assign_stack_local_1 (enum machine_mode 
*** 454,460 ****
  
    /* On a big-endian machine, if we are allocating more space than we will use,
       use the least significant bytes of those that are allocated.  */
!   if (BYTES_BIG_ENDIAN && mode != BLKmode)
      bigend_correction = size - GET_MODE_SIZE (mode);
  
    /* If we have already instantiated virtual registers, return the actual
--- 454,460 ----
  
    /* On a big-endian machine, if we are allocating more space than we will use,
       use the least significant bytes of those that are allocated.  */
!   if (BYTES_BIG_ENDIAN && mode != BLKmode && GET_MODE_SIZE (mode) < size)
      bigend_correction = size - GET_MODE_SIZE (mode);
  
    /* If we have already instantiated virtual registers, return the actual



More information about the Gcc-patches mailing list