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