This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/80561] Missed optimization: std::array data is aligned if array is aligned


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

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, the reason is that the actual memory reference does not expose this
alignment.
The vectorizer sees

  MEM[(const value_type &)v2_7(D)][_1]

 <array_ref 0x7ffff56ac540
    type <real_type 0x7ffff68cee70 double readonly type_6 DF
        size <integer_cst 0x7ffff68a2eb8 constant 64>
        unit size <integer_cst 0x7ffff68a2ed0 constant 8>
        align 64 symtab 0 alias set -1 canonical type 0x7ffff68cee70 precision
64
        pointer_to_this <pointer_type 0x7ffff68cef18> reference_to_this
<reference_type 0x7ffff5d335e8>>
    readonly
    arg 0 <mem_ref 0x7ffff56ae410
        type <array_type 0x7ffff5817b28 _Type type <real_type 0x7ffff68cee70
double>
            BLK
            size <integer_cst 0x7ffff61c9eb8 constant 512>
            unit size <integer_cst 0x7ffff61c9ee8 constant 64>
            align 64 symtab 0 alias set -1 canonical type 0x7ffff5817a80 domain
<integer_type 0x7ffff6759738>
            pointer_to_this <pointer_type 0x7ffff596eb28> reference_to_this
<reference_type 0x7ffff5817bd0>>
        tree_0
        arg 0 <ssa_name 0x7ffff5688cf0 type <reference_type 0x7ffff5816348>
            visited var <parm_decl 0x7ffff5811a00 v2>

where the MEM_REF is of an array type with natural alignment and the
function parameter as of GCCs own rule doesn't have any special
alignment just because of its type (see other PRs).

The FE presents us with

  (void) (*SAVE_EXPR <std::array<double, 8>::operator[] ((struct Vec *) v1,
(size_type) i)> = TARGET_EXPR <D.25081, NON_LVALUE_EXPR <*std::array<double,
8>::operator[] ((const struct Vec *) v2, (size_type) i)>>;, *SAVE_EXPR
<std::array<double, 8>::operator[] ((struct Vec *) v1, (size_type) i)> +
D.25081;) >>>>>;

and inside libstdc++ the actual memory access is of course formed not
taking into accout alignment of the std::array object itself (of course?).

Workaround:

#include <array>

static constexpr size_t my_elements = 8;

typedef std::array<double, my_elements> Vec __attribute__((aligned(32)));
// typedef double Vec[my_elements] __attribute__((aligned(32)));

void func(Vec& __restrict__ v1, const Vec& v2)
{
  Vec *vv1 = (Vec *)__builtin_assume_aligned (&v1, 32);
  Vec *vv2 = (Vec *)__builtin_assume_aligned (&v2, 32);
    for (unsigned i = 0; i < my_elements; ++i)
    {
        (*vv1)[i] += (*vv2)[i];
    }
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]