https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80334
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Testcase without STL headers: struct A { alignas(16) char c; }; struct B { A unpacked; char d; } __attribute__((packed)); int main() { alignas(16) B b[3]; for (int i = 0; i < 3; i++) b[i].unpacked.c = 'a' + i; for (int i = 0; i < 3; i++) { auto a = new A(b[i].unpacked); __builtin_printf ("%c\n", a->c); } } Not really sure if this is valid testcase though, by placing it into an array you are violating the alignments of the fields in second and following elements. If you want to align just the start of the array, put the alignas on the array, not on the types. At expansion (and likely already in GIMPLE) we are assuming 128-bit alignment of b[i].unpacked): (mem:TI (reg:DI 105 [ ivtmp.9 ]) [1 MEM[base: _21, offset: 0B]+0 S16 A128])) so this is not STV's pass fault, just that when using vector insns the target behaves as strict alignment rather than forgiving all alignment violations. If you use struct A { long long c; }; struct B { A unpacked; char d; } __attribute__((packed)); int main() { B b[3]; for (int i = 0; i < 3; i++) b[i].unpacked.c = 'a' + i; for (int i = 0; i < 3; i++) { auto a = new A(b[i].unpacked); __builtin_printf ("%c\n", a->c); } } then we assume 64-bit alignment on the b[i].unpacked read too. With struct A { char c __attribute__((aligned (16))); }; struct B { A unpacked; char d; } __attribute__((packed)); int main() { B b[3] __attribute__((aligned (16))); for (int i = 0; i < 3; i++) b[i].unpacked.c = 'a' + i; for (int i = 0; i < 3; i++) { A *a = new A(b[i].unpacked); __builtin_printf ("%c\n", a->c); } } and -O2 I can track the using of A128 in the read from b[i].unpacked to r162001, and r161703 still emits there A8. r161703 in *.optimized still has: D.2157_35 = (void *) ivtmp.10_27; *a_11 = MEM[base: D.2157_35]; and in *.vregs has: (insn 17 16 18 4 pr80334-3.C:10 (set (reg:DI 69) (mem/s:DI (reg:DI 63 [ ivtmp.10 ]) [2 b[i].unpacked+0 S8 A8])) 61 {*movdi_internal_rex64} (nil)) No idea where it discovered the b[i].unpacked! r162001 has in *.optimized: D.2157_35 = (void *) ivtmp.10_27; *a_11 = MEM[(struct B[3] *)D.2157_35]; and in *.vregs: (insn 17 16 18 4 pr80334-3.C:10 (set (reg:DI 69) (mem/s:DI (reg:DI 63 [ ivtmp.10 ]) [3 MEM[(struct B[3] *)D.2157_35]+0 S8 A128])) 61 {*movdi_internal_rex64} (nil)) Unfortunately various revisions between those 2 (don't have that many) just hang on the testcase, so can't bisect it exactly.