http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57748
--- Comment #27 from Bernd Edlinger <bernd.edlinger at hotmail dot de> ---
(In reply to Martin Jambor from comment #22)
> Created attachment 30732 [details]
> Another attempt at a fix
>
> I simply moved the decision whether to go the misalignp path or not a
> bit down in the function, below the address adjustments done for
> non-NULL offset, strict volatile bit fields etc. and ran the
> testsuite, expecting some fallout. But there was none the patch even
> survives a bootstrap on x86_64-linux. I'm hesitant to call it the
> fix, I'd like to have a second look at it after the weekend but if
> someone wants to test meanwhile, such input would be highly welcome.
Martin, this patch is wrong:
consider this test example:
/* PR middle-end/57748 */
/* { dg-do run } */
#include <stdlib.h>
extern void abort (void);
typedef long long V
__attribute__ ((vector_size (2 * sizeof (long long)), may_alias));
typedef double V1
__attribute__ ((vector_size (1 * sizeof (double)), may_alias));
typedef struct S { V a; V1 b[0]; } P __attribute__((aligned (1)));
struct __attribute__((packed)) T { char c; P s; };
void __attribute__((noinline, noclone))
check (struct T *t)
{
if (t->s.b[0][0] != 3)
abort ();
}
int __attribute__((noinline, noclone))
get_i (void)
{
return 0;
}
void __attribute__((noinline, noclone))
foo (P *p)
{
V1 a = { 3 };
int i = get_i();
p->b[i] = a;
}
int
main ()
{
struct T *t = (struct T *) malloc (128);
foo (&t->s);
check (t);
return 0;
}
this example is designed to go thru the
if (bitsize != GET_MODE_BITSIZE (mode)) path.
Because the struct mode is derived from V but the bitsize
is from V1, only half of V.
the resulting code from this patch accesses out of bounds:
foo:
.LFB9:
.cfi_startproc
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
movq %rdi, %rbx
subq $16, %rsp
.cfi_def_cfa_offset 32
call get_i
cltq
movq .LC1(%rip), %xmm1
addq $2, %rax
movdqu (%rbx,%rax,8), %xmm0
psrldq $8, %xmm0
punpcklqdq %xmm0, %xmm1
movdqu %xmm1, (%rbx,%rax,8)
addq $16, %rsp
.cfi_def_cfa_offset 16
popq %rbx
.cfi_def_cfa_offset 8
ret
.cfi_endproc
while my latest patch (which meanwhile was boot-straped without regressions)
generates this:
foo:
.LFB9:
.cfi_startproc
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
movq %rdi, %rbx
call get_i
movsd .LC0(%rip), %xmm0
cltq
movsd %xmm0, 16(%rbx,%rax,8)
popq %rbx
.cfi_def_cfa_offset 8
ret
.cfi_endproc