public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/104588] New: user-defined constructor loses alignment information about `*this`
@ 2022-02-18  5:24 lh_mouse at 126 dot com
  2022-02-18  5:38 ` [Bug middle-end/104588] memset loses alignment infomation in some cases pinskia at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: lh_mouse at 126 dot com @ 2022-02-18  5:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104588

            Bug ID: 104588
           Summary: user-defined constructor loses alignment information
                    about `*this`
           Product: gcc
           Version: 11.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lh_mouse at 126 dot com
  Target Milestone: ---
            Target: x86_64-linux-gnu

https://gcc.godbolt.org/z/M3YoaYeEf

```c++
struct alignas(16) foo
  {
    unsigned char a[32];
    foo() : a() { }
  };t

struct alignas(16) bar
  {
    foo f;
    long m,n,p,q;
    bar() : f(),m(),n(),p(),q() { }
  };

constexpr void* operator new(unsigned long, void* p) noexcept { return p;  }
inline void operator delete(void*, void*) noexcept { }

bar* construct(bar* p)
  {
    return new(p) bar();
  }
```


For `bar::bar()` with -O3, GCC generates two `MOVUPS` followed by two `MOVAPS`,
while Clang generates four `MOVAPS`. `MOVUPS` was slow on some older CPUs.


GCC output:

```
construct(bar*):
        pxor    xmm0, xmm0
        mov     rax, rdi
        movups  XMMWORD PTR [rdi], xmm0
        movups  XMMWORD PTR [rdi+16], xmm0
        pxor    xmm0, xmm0
        movaps  XMMWORD PTR [rdi+32], xmm0
        movaps  XMMWORD PTR [rdi+48], xmm0
        ret
```

Clang output:

```
construct(bar*):                      # @construct(bar*)
        mov     rax, rdi
        xorps   xmm0, xmm0
        movaps  xmmword ptr [rdi + 48], xmm0
        movaps  xmmword ptr [rdi + 32], xmm0
        movaps  xmmword ptr [rdi + 16], xmm0
        movaps  xmmword ptr [rdi], xmm0
        ret
```

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug middle-end/104588] memset loses alignment infomation in some cases
  2022-02-18  5:24 [Bug c++/104588] New: user-defined constructor loses alignment information about `*this` lh_mouse at 126 dot com
@ 2022-02-18  5:38 ` pinskia at gcc dot gnu.org
  2022-02-18  7:36 ` [Bug c++/104588] " rguenth at gcc dot gnu.org
  2022-02-18 12:26 ` lh_mouse at 126 dot com
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-02-18  5:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104588

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c++                         |middle-end
   Last reconfirmed|                            |2022-02-18
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
            Summary|user-defined constructor    |memset loses alignment
                   |loses alignment information |infomation in some cases
                   |about `*this`               |

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
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.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c++/104588] memset loses alignment infomation in some cases
  2022-02-18  5:24 [Bug c++/104588] New: user-defined constructor loses alignment information about `*this` lh_mouse at 126 dot com
  2022-02-18  5:38 ` [Bug middle-end/104588] memset loses alignment infomation in some cases pinskia at gcc dot gnu.org
@ 2022-02-18  7:36 ` rguenth at gcc dot gnu.org
  2022-02-18 12:26 ` lh_mouse at 126 dot com
  2 siblings, 0 replies; 4+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-02-18  7:36 UTC (permalink / raw)
  To: gcc-bugs

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c++/104588] memset loses alignment infomation in some cases
  2022-02-18  5:24 [Bug c++/104588] New: user-defined constructor loses alignment information about `*this` lh_mouse at 126 dot com
  2022-02-18  5:38 ` [Bug middle-end/104588] memset loses alignment infomation in some cases pinskia at gcc dot gnu.org
  2022-02-18  7:36 ` [Bug c++/104588] " rguenth at gcc dot gnu.org
@ 2022-02-18 12:26 ` lh_mouse at 126 dot com
  2 siblings, 0 replies; 4+ messages in thread
From: lh_mouse at 126 dot com @ 2022-02-18 12:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104588

--- Comment #3 from LIU Hao <lh_mouse at 126 dot com> ---
Sounds so. Changing `char a[32]` to `long a[4]` or `void* a[4]` makes GCC
generate MOVAPS like Clang, but `int a[8]` or `short a[16]` does not.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-02-18 12:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-18  5:24 [Bug c++/104588] New: user-defined constructor loses alignment information about `*this` lh_mouse at 126 dot com
2022-02-18  5:38 ` [Bug middle-end/104588] memset loses alignment infomation in some cases pinskia at gcc dot gnu.org
2022-02-18  7:36 ` [Bug c++/104588] " rguenth at gcc dot gnu.org
2022-02-18 12:26 ` lh_mouse at 126 dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).