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).

Reply via email to