> On Jul 5, 2018, at 12:01 PM, Segher Boessenkool <seg...@kernel.crashing.org> 
> wrote:
> 
> On Thu, Jul 05, 2018 at 08:45:30AM -0400, Paul Koning wrote:
>> I have a struct that looks like this:
>> 
>> struct Xrb
>> {
>>    uint16_t xrlen;           /* Length of I/O buffer in bytes */
>>    uint16_t xrbc;            /* Byte count for transfer */
>>    void * xrloc;             /* Pointer to I/O buffer */
>>    uint8_t xrci;             /* Channel number times 2 for transfer */
>>    uint32_t xrblk:24;        /* Random access block number */
>>    uint16_t xrtime;  /* Wait time for terminal input */
>>    uint16_t xrmod;           /* Modifiers */
>> };
>> 
>> When I write to xrblk (that 24 bit field) on my 16 bit target, I get 
>> unexpectly inefficient output:
>> 
>>    XRB->xrblk = 5;
>> 
>>      movb    #5,10(r0)
>>      clrb    11(r0)
>>      clrb    7(r0)
> 
> (7? not 12?)

Octal offsets.  It's writing the 3 bytes in LSB to MSB order.  (PDP11 -- which 
has funny-endian ordering.)

> rather than the expected word write to the word-aligned lower half of that 
> field.
>> 
>> Looking at the dumps, I see it coming into the RTL expand phase as a single 
>> write, which expand then turns into the three insns corresponding to the 
>> above.  But (of course) there is a word (HImode) move also, which has the 
>> same cost as the byte one.
>> 
>> Is there something I have to do in my target definition to get this to come 
>> out right?  This is a strict_alignment target, but alignment is satisfied in 
>> this example.  Also, SLOW_BYTE_ACCESS is 1.
> 
> What is your MOVE_MAX?  It should be 2 probably.

It is. 

I just constructed another test case that shows the same issue more blatantly:

struct s
{
    char a;
    char b;
    char c;
    char d;
    int e;
    int f;
    char h;
    char i;
};

struct s ts;

void setts(void)
{
    ts.a=2;
    ts.b=4;
    ts.c=1;
    ts.d=24;
    ts.e=5;
    ts.f=42;
    ts.h=9;
    ts.i=3;
}

Each of the fields are written separately, even though clearly the adjacent 
byte writes can and should be combined into a single HImode move.  This happens 
both with -O2 and -Os.

        paul

Reply via email to