[Bug middle-end/93764] [10 Regression] lzo 2.10 test suite fails with -O2 and -O3
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Feb 17 12:28:00 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93764
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|RESOLVED |REOPENED
Last reconfirmed| |2020-02-17
CC| |jakub at gcc dot gnu.org
Resolution|INVALID |---
Ever confirmed|0 |1
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I've bisected this (well, lzo 2.08) to src/lzo_init.c, -O2 -fno-strict-aliasing
it still works, with -O2 it fails, and at least in the past lzo has been known
to violate strict aliasing even in this TU.
The "miscompilation" started with
r10-514-gc6b84edb6110dd2b4fb654c53c0a9979e0532ffe and the difference between
r10-513 and r10-514 is:
_lzo_config_check:
pushq %r15
xorl %esi, %esi
pushq %r14
pushq %r13
pushq %r12
pushq %rbp
pushq %rbx
movabsq $4398046511107, %rbx
subq $24, %rsp
movq %rsp, %rdi
movq $0, (%rsp)
movq $0, 8(%rsp)
call u2p
movl $1, %esi
cmpb $0, (%rax)
- movb $-128, (%rsp)
sete %dl
cmpq $128, (%rax)
- movq $33554433, (%rsp)
+ movb $1, (%rsp)
sete %r13b
+ movb $2, 3(%rsp)
call u2p
where 33554433 is 0x02000001, so the difference is that the 1(%rsp) and 2(%rsp)
bytes are no longer initialized after the first u2p call.
Slightly reduced testcase for -O2:
typedef unsigned short int __attribute__((__may_alias__)) lzo_memops_TU2;
typedef unsigned int __attribute__((__may_alias__)) lzo_memops_TU4;
typedef unsigned long int __attribute__((__may_alias__)) lzo_memops_TU8;
union lzo_config_check_union {
unsigned long a[2];
unsigned char b[2*((8) >= (sizeof(unsigned long)) ? (8) : (sizeof(unsigned
long)))];
unsigned long int c[2];
};
static __attribute__((noinline, noclone)) void * u2p(void * ptr, unsigned long
off)
{
return (void *) ((unsigned char *) ptr + off);
}
__attribute__((noipa)) int
lzo_config_check(void)
{
union lzo_config_check_union u;
void *p;
unsigned r = 1;
u.a[0] = u.a[1] = 0;
p = u2p(&u, 0);
r &= ((* (unsigned char *) p) == 0);
u.a[0] = u.a[1] = 0; u.b[0] = 128;
p = u2p(&u, 0);
r &= ((* (unsigned long *) p) == 128);
u.a[0] = u.a[1] = 0;
u.b[0] = 1; u.b[3] = 2;
p = u2p(&u, 1);
r &= * (const volatile lzo_memops_TU2 *) (const void *) (p) == 0;
r &= * (const volatile lzo_memops_TU2 *) (const void *) (p) == 0;
u.b[1] = 128;
r &= * (const volatile lzo_memops_TU2 *) (const void *) (p) == 128;
u.b[2] = 129;
r &= * (const volatile lzo_memops_TU2 *) (const void *) (p) == (0x8180U);
r &= * (const volatile lzo_memops_TU2 *) (const void *) (p) == (0x8180U);
u.a[0] = u.a[1] = 0;
u.b[0] = 3; u.b[5] = 4;
p = u2p(&u, 1);
r &= * (const volatile lzo_memops_TU4 *) (const void *) (p) == 0;
r &= * (const volatile lzo_memops_TU4 *) (const void *) (p) == 0;
u.b[1] = 128;
r &= * (const volatile lzo_memops_TU4 *) (const void *) (p) == 128;
u.b[2] = 129; u.b[3] = 130; u.b[4] = 131;
r &= * (const volatile lzo_memops_TU4 *) (const void *) (p) == (0x83828180U);
r &= * (const volatile lzo_memops_TU4 *) (const void *) (p) == (0x83828180U);
u.c[0] = u.c[1] = 0;
u.b[0] = 5; u.b[9] = 6;
p = u2p(&u, 1);
u.c[0] = u.c[1] = 0;
r &= * (const volatile lzo_memops_TU8 *) (const void *) (p) == 0;
r &= * (const volatile lzo_memops_TU8 *) (const void *) (p) == 0;
u.b[1] = 128;
r &= * (const volatile lzo_memops_TU8 *) (const void *) (p) == 128;
return r == 1 ? 0 : (-1);
}
int
main ()
{
if (lzo_config_check ())
__builtin_abort ();
return 0;
}
Now, with the casts to may_alias types I wonder if this isn't actually valid.
More information about the Gcc-bugs
mailing list