This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch,loopiv] misaligned packed array memory access
- From: Christian BRUEL <christian dot bruel at st dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 30 Jan 2008 14:20:11 +0100
- Subject: Re: [patch,loopiv] misaligned packed array memory access
- References: <479E20A0.1020406@st.com>
Adding a testcase to the patch for the testsuite.
(aborts on sh-superh-elf-gcc),
Regards
-c
2008-01-28 Christian Bruel <christian.bruel@st.com
* gcc.dg/packed-array.c: New testcase.
Christian BRUEL wrote:
The attached test case reduces a misaligned field access from an array
of packed structs. In this example compiled with -O2 the field
wMaxPacketSize is accessed (on sh4) with a mov.w instruction although it
is byte aligned.
The tree-ssa-loop ivopts did not check packed struct offsets indexed by
an induction variable. Thus if the struct size is not aligned, the field
becomes unaligned after the first iteration even if it was aligned from
the base of this structure.
This patch solves this problem by expanding may_be_unaligned_p to check
that a loop carried offset is a multiple of the desired alignment.
This bug impacted STRICT_ALIGNMENT targets. I regtested on sh-superh-elf
and sh4-linux-gnu.
Also bootstraped for i686-pc-linux-gnu.
Thanks you for any feedback and trunk approval if ok.
-c
2008-01-28 Christian Bruel <christian.bruel@st.com>
* tree-ssa-loop-ivopts.c (may_be_unaligned_p): check loop carried
offset.
* (loop_offset_multiple_of): new function.
/* { dg-do run } */
/* { dg-options "-O2 -fno-inline" } */
struct usb_interface_descriptor {
unsigned short wMaxPacketSize;
char e;
} __attribute__ ((packed));
struct usb_device {
int devnum;
struct usb_interface_descriptor if_desc[2];
};
extern int printf (const char *, ...);
void foo (unsigned short a)
{
printf ("%d\n", a);
}
struct usb_device ndev;
void usb_set_maxpacket(int n)
{
int i;
for(i=0; i<n;i++)
foo((&ndev)->if_desc[i].wMaxPacketSize);
}
int
main()
{
usb_set_maxpacket(2);
return 0;
}