https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104588
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org Component|middle-end |c++ --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #1) > Confirmed, > Reduced testcase: > struct alignas(16) foo > { > unsigned char a[32]; > }; > > foo* construct(foo* p) > { > __builtin_memset(p, 0, sizeof(foo)); > return p; > } > > ----- CUT ---- > That is it has nothing to do with the constructors at all but just memset. There's a duplicate about this - in GIMPLE we do not assume that pointers are aligned naturally, only memory accesses behave this way and memset itself has no alignment constraints. The memset for the original testcase is matched by loop distribution: <bb 2> [local count: 32534376]: MEM[(struct bar *)p_1(D) clique 2 base 1] ={v} {CLOBBER}; MEM[(struct foo *)p_1(D) clique 3 base 1] ={v} {CLOBBER}; # PT = nonlocal null _3 = &MEM[(struct foo *)p_1(D)].a; # USE = anything # CLB = anything __builtin_memset (_3, 0, 32); MEM[(struct bar *)p_1(D) clique 2 base 1].m = 0; MEM[(struct bar *)p_1(D) clique 2 base 1].n = 0; MEM[(struct bar *)p_1(D) clique 2 base 1].p = 0; MEM[(struct bar *)p_1(D) clique 2 base 1].q = 0; return p_1(D); Note the C++ frontend emits { <<cleanup_point <<< Unknown tree: expr_stmt (void) *(unsigned char[32] *) unsigned char * D.2382; <<< Unknown tree: expr_stmt (void) (D.2382 = (unsigned char *) &((struct foo *) this)->a) >>>; unsigned char * D.2383; <<< Unknown tree: expr_stmt (void) (D.2383 = D.2382) >>>; TARGET_EXPR <D.2384, 31>; goto <D.2386>; <D.2387>:; <<cleanup_point <<< Unknown tree: expr_stmt *D.2383 = 0;, --D.2384; >>>>>; <<< Unknown tree: expr_stmt (void) ++D.2383 >>>; <D.2386>:; if (D.2384 >= 0) goto <D.2387>; else goto <D.2385>; <D.2385>:; D.2382 >>>>>; } which is a loop iterating with a char * pointer and thus performing char * accesses which does not include alignment info of the base as if it would do this->a[i] and use an array index IV. So it's first of all a C++ frontend issue which fails to expose the maximum possible information at the stores it creates (those we could preserve).