[Bug target/36533] New: [4.3/4.4 Regression] Incorrectly assumed aligned_operand
jakub at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Fri Jun 13 21:32:00 GMT 2008
The following testcase is miscompiled on i?86 -m32 -Os:
/* { dg-options "-Os" } */
typedef struct S1
{
unsigned long s1;
struct S1 *s2;
char *s3;
} S1;
typedef struct
{
unsigned int s4;
unsigned int s5;
int s6;
unsigned int *s7;
} S2;
typedef struct
{
unsigned int s8;
unsigned short s9;
unsigned char s10;
unsigned char s11;
char s12[255];
} S3;
typedef struct
{
unsigned int s4;
unsigned short s13;
unsigned short s14;
} S4;
typedef struct
{
char s15[16];
unsigned long s16;
} S5;
typedef struct
{
char s15[48];
S5 *s17;
} S6;
typedef struct
{
S1 *s18;
} S7;
extern __attribute__((regparm (3))) int fn1 (const char *x, void *y, S1 *z);
extern __attribute__((regparm (3))) int fn2 (const char *x, int y, S2 *z);
static inline __attribute__ ((always_inline)) unsigned int
fn4 (unsigned short x)
{
unsigned len = x;
if (len == ((1 << 16) - 1))
return 1 << 16;
return len;
}
static inline __attribute__ ((always_inline)) S3 *
fn3 (S3 *p)
{
return (S3 *) ((char *) p + fn4 (p->s9));
}
extern __attribute__((regparm (3))) int fn5 (void);
static inline __attribute__ ((always_inline)) int
fn6 (S3 *w, int x, S2 *y, S4 *z)
{
int a = 0;
char *b = (char *) w;
S2 c = *y;
while ((char *) w < b + x)
{
if (w->s10 && w->s8)
{
fn2 (w->s12, w->s10, &c);
z--;
z->s4 = c.s4;
z->s13 = (unsigned short) ((char *) w - b);
z->s14 = w->s9;
a++;
fn5 ();
}
w = fn3 (w);
}
return a;
}
__attribute__((regparm (3))) unsigned int
test (void *u, S6 *v, S1 **w, S7 *x, S2 *y, S1 *z)
{
unsigned b = v->s17->s16;
unsigned a;
S4 *c;
unsigned d, e, f, i;
fn1 (__func__, u, x->s18);
c = (S4 *) (z->s3 + b);
a = fn6 ((S3 *) (*w)->s3, b, y, c);
c -= a;
f = 0;
e = 0;
for (i = a - 1; ; i--)
{
if (f + (unsigned short) (c[i].s14 / 2) > b / 2)
break;
f += c[i].s14;
e++;
}
d = a - e;
return c[d].s4;
}
since the PR28690 backport. The c[i].s14 read is done using
movl (%ecx), %edi # <variable>.s14, D.1321
rather than
movw (%ecx), %di
which is wrong in this case, as %ecx is provably not 32-bit aligned (%ecx - 6
is
known to be 32-bit aligned). Shouldn't be hard to transform this into an
executable testcase (put the array of S14 at the end of mmaped page such that
the last c[i].s14 is right before end of page).
This is a regression since 4.3.0.
--
Summary: [4.3/4.4 Regression] Incorrectly assumed aligned_operand
Product: gcc
Version: 4.3.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: jakub at gcc dot gnu dot org
GCC target triplet: i686-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36533
More information about the Gcc-bugs
mailing list