Unaligned block moves and MEM_ALIGN re-broken

David Edelsohn dje@watson.ibm.com
Thu Jan 24 16:52:00 GMT 2002


	We seem to have reverted back to moving unaligned DImode MEMs with
FPRs on PowerPC.  The rs6000_emit_move() change from November is not
intercepting this because the MEM now claims that its alignment is 64
bits for

struct x { char c[8]; };
int quux (struct x* a, struct x* b) {
   *a = *b;
}

	The problem is that we now are using circular logic to set the
alignment in memattrs:

#define MEM_ALIGN(RTX)                                                  \
(MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->align                          \
 : GET_MODE (RTX) != BLKmode ? GET_MODE_ALIGNMENT (GET_MODE (RTX))      \
 : BITS_PER_UNIT)

In other words, if memattrs is not defined, use the mode alignment.

Excerpt from expand_expr, INDIRECT_REF case:

        temp = gen_rtx_MEM (mode, op0);
        set_mem_attributes (temp, exp, 0);

gen_rtx_MEM:

  rtx rt = gen_rtx_raw_MEM (mode, addr);
  MEM_ATTRS (rt) = 0;

set_mem_attributes:

  unsigned int align = MEM_ALIGN (ref);
  ...
  /* We can set the alignment from the type if we are making an object,
     this is an INDIRECT_REF, or if TYPE_ALIGN_OK.  */
  if (objectp || TREE_CODE (t) == INDIRECT_REF || TYPE_ALIGN_OK (type))
    align = MAX (align, TYPE_ALIGN (type));


	So, we create the MEM, set memattrs to zero and call
set_mem_attributes() to define the attributes from the tree information.
However, set_mem_attributes() looks to MEM_ALIGN for its preliminary guess
at the alignment, which uses the default MODE alignment because memattrs
is not yet set!  When we compare the preliminary alignment against the
alignment specified by the tree, it is smaller and we prefer the alignment
specified by the MODE.  The example above is DImode, so 64 bits.

	This logic is completely broken.  Either the the MEM_* macros
should not return default values based on the MODE or set_mem_attributes()
should not use those macros for its initial values.  Choosing the maximum
of the MODE alignment and the TYPE alignment also seems especially wrong.

	If we are updating the attributes of a MEM, I can understand
querying the current attributes, but not when we are trying to create the
initial attribute values themselves. 

	My initial idea for fixing this is to remove the macros from
set_mem_attributes() and write the preliminary value calculations
explicitly so that we know when we want to use defaults based on the mode
(e.g., MEM_SIZE) and when we do not want to use defaults based on the mode
(e.g., MEM_ALIGN).  I also suspect that we want to change the MAX (align,
TYPE_ALIGN (type)) expression.

David



More information about the Gcc mailing list