public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments
@ 2020-09-27 23:07 mte.zych at gmail dot com
  2020-09-28  0:14 ` [Bug c++/97222] " pinskia at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: mte.zych at gmail dot com @ 2020-09-27 23:07 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 97222
           Summary: GCC discards attributes aligned and may_alias for
                    typedefs passed as template arguments
           Product: gcc
           Version: 10.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mte.zych at gmail dot com
  Target Milestone: ---

Hello!

GCC discards aligned attribute, applied on a typdef, when it's passed as a
template argument.

Compiler Expolorer:
 GCC -> https://godbolt.org/z/bj8v1T

C++ Source Code:
 #include <iostream>

 typedef float vec __attribute__((vector_size(8)));
 typedef float fp  __attribute__((aligned(16)));

 template <typename t> struct identity { typedef t type; };

 int main ()
 {
     std::cout << sizeof(typename identity<vec>::type) << std::endl;
     std::cout << sizeof(vec                         ) << std::endl;

     std::cout << alignof(typename identity<fp>::type) << std::endl;
     std::cout << alignof(fp                         ) << std::endl;
 }

Program Output:
 8
 8
 4
 16

Compilation Log:
 warning: ignoring attributes on template argument 'fp' {aka 'float'}
[-Wignored-attributes]
 13 |     std::cout << alignof(typename identity<fp>::type) << std::endl;
    |                                              ^

The above program shows that alignment of the fp typedef changes, after it's
been
passed through the identity meta-function - it's 4-bytes instead of expected
16-bytes.


What's interesting is not all type attributes are discarded - the type
attribute vector_size
is preserved after being passed through the identity meta-function.

This behavior is required, since removal of the vector_size attribute
would be a semantic change of the vec type, affecting even its size,
because the vec type would represent a single float, instead of a vector of 2
floats.

The same could be said about the aligned attribute - discarding it is also a
semantic change,
since alignment is a fundamental property of a type, affecting among others
code generation,
that is, two types are not equivalent if they have different alignment.

This is the reason why I argue that, passing a typedef as a template argument
should preserve its aligned attribute, instead of discarding it.


Moreover, the Intel C++ compiler implements this behavior correctly.

Compiler Expolorer:
 ICC -> https://godbolt.org/z/9vr9se

Program Output:
 8
 8
 16
 16


The issue described above doesn't apply only to the aligned type attribute,
but also to the may_alias type attribute.

Compiler Expolorer:
 GCC -> https://godbolt.org/z/6EqsnP

C++ Source Code:
 typedef int integer __attribute__((may_alias));

 template <typename t> struct identity { typedef t type; };

 int main ()
 {
     typename identity<integer>::type i;
 }

Compilation Log:
 warning: ignoring attributes on template argument 'integer' {aka 'int'}
[-Wignored-attributes]
     7 |     typename identity<integer>::type i;
       |                              ^

Again, discarding attribute may_alias is a semantic change,
because aliasing rules can affect code generation.


Why this issue is important?
Well, because it prevents generic programming, via C++ templates, using x86
SIMD types.

If we would look at definitions of x86 SIMD types, we will notice that
they are essentially typedefs with attributes vector_size and may_alias applied
on them:

- immintrin.h
    typedef float     __m256  __attribute__((__vector_size__(32),
__may_alias__));

- emmintrin.h
    typedef long long __m128i __attribute__((__vector_size__(16),
__may_alias__));
    typedef double    __m128d __attribute__((__vector_size__(16),
__may_alias__));

- xmmintrin.h
    typedef float     __m128  __attribute__((__vector_size__(16),
__may_alias__)); 

Note that, the may_alias attributes is required and cannot be removed:

- /usr/lib/gcc/x86_64-linux-gnu/10/include/immintrin.h
    /* The Intel API is flexible enough that we must allow aliasing with other
       vector types, and their scalar components.  */

Compiler Expolorer:
 GCC -> https://godbolt.org/z/vz4fWK

C++ Source Code:
 #include <immintrin.h>

 template <typename t> struct identity { typedef t type; };

 int main ()
 {
     typename identity<__m128>::type fvec4;
 }

Compilation Log:
 warning: ignoring attributes on template argument '__m128'
[-Wignored-attributes]
     8 |     typename identity<__m128>::type fvec4;
       |                             ^


What's the root cause of this problem?

Well, the problem is in C++ a typedef is just an alias (a new name) for the old
type,
that is, it does *not* introduce a new type.

Implementing support for attributes vector_size, aligned and may_alias
in C++ typedefs requires an opaque/strong typedef,
introducing a brand new type and storing information about applied attributes.

 typedef float fp __attribute__((aligned(16)));

Think about it - a typedef introducing the fp type has to create a new type,
because even though both fp and float types represent floating point numbers
identically,
the fp type is *not* the float type, because these types have different
alignment requirements.


Note that, the Intel C++ Compiler does not introduce new types for typedefs,
which have attributes aligned or may_alias applied on them.

Compiler Explorer:
 ICC -> https://godbolt.org/z/MjdMqx

C++ Source Code:
 #include <iostream>

 typedef int vectorized_int __attribute__((vector_size(8)));
 typedef int    aligned_int __attribute__((aligned(16)));
 typedef int   aliasing_int __attribute__((may_alias));

 int main ()
 {
     std::cout << typeid(           int).name() << std::endl;
     std::cout << typeid(vectorized_int).name() << std::endl;
     std::cout << typeid(   aligned_int).name() << std::endl;
     std::cout << typeid(  aliasing_int).name() << std::endl;
 }

Program Output:
 i
 Dv2_i
 i
 i


However, this behavior leads to a contradiction,
in which there can exists a single type, which has 2 different alignment
requirements.

Compiler Explorer:
 ICC -> https://godbolt.org/z/4o9o3M

C++ Source Code:
 template <class, class> struct is_same        { static const auto value =
false; };
 template <class T>      struct is_same <T, T> { static const auto value = 
true; };

 typedef float fp __attribute__((aligned(16)));

 template <typename first_type, typename second_type>
 struct check_same
 {
     static_assert(is_same<first_type, second_type>::value    , "");
     static_assert( sizeof(first_type) ==  sizeof(second_type), "");
     static_assert(alignof(first_type) == alignof(second_type), "");
 };

 int main ()
 {
     check_same<int, signed int> { };
     check_same< fp,      float> { };
 }

Compilation Log:
 error: static assertion failed
     static_assert(alignof(first_type) == alignof(second_type), "");
     ^
 detected during instantiation of class
 "check_same<first_type, second_type> [with first_type=fp={float},
second_type=float]"

To avoid these kind of issues, GCC could replicate the behavior of the
vector_size attribute,
that is, introduce a brand new type and store information about applied
attributes.


Thank you, Mateusz Zych

PS. I want to thank Ivo Kabadshow from JSC for helping me with preparing these
code samples!

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

* [Bug c++/97222] GCC discards attributes aligned and may_alias for typedefs passed as template arguments
  2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
@ 2020-09-28  0:14 ` pinskia at gcc dot gnu.org
  2020-09-28  7:27 ` rguenth at gcc dot gnu.org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2020-09-28  0:14 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement
           Keywords|                            |ABI
   Last reconfirmed|                            |2020-09-28
             Status|UNCONFIRMED                 |SUSPENDED
     Ever confirmed|0                           |1

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Actually this is more complex than what is mentioned here.  THIS REQUIRES An
ABI addition.  Due to the way templates cause name managling to come into play.
 There is NO way defined at this point to mange for some attributes including
but not limited to may_alias and alignment.

Suspending until there is a definition of that defined.

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

* [Bug c++/97222] GCC discards attributes aligned and may_alias for typedefs passed as template arguments
  2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
  2020-09-28  0:14 ` [Bug c++/97222] " pinskia at gcc dot gnu.org
@ 2020-09-28  7:27 ` rguenth at gcc dot gnu.org
  2020-09-29  1:12 ` richard-gccbugzilla at metafoo dot co.uk
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-09-28  7:27 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
would be interesting to see how ICC mangles the aligned case

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

* [Bug c++/97222] GCC discards attributes aligned and may_alias for typedefs passed as template arguments
  2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
  2020-09-28  0:14 ` [Bug c++/97222] " pinskia at gcc dot gnu.org
  2020-09-28  7:27 ` rguenth at gcc dot gnu.org
@ 2020-09-29  1:12 ` richard-gccbugzilla at metafoo dot co.uk
  2020-09-29 17:48 ` mte.zych at gmail dot com
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: richard-gccbugzilla at metafoo dot co.uk @ 2020-09-29  1:12 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Smith <richard-gccbugzilla at metafoo dot co.uk> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |richard-gccbugzilla@metafoo
                   |                            |.co.uk

--- Comment #3 from Richard Smith <richard-gccbugzilla at metafoo dot co.uk> ---
> would be interesting to see how ICC mangles the aligned case

It doesn't, it just takes the properties from whichever instantiation happens
to be performed first. On ICC,

     std::cout << alignof(typename identity<float>::type) << std::endl;
     std::cout << alignof(typename identity<fp>::type) << std::endl;

prints 4 4, and 

     std::cout << alignof(typename identity<fp>::type) << std::endl;
     std::cout << alignof(typename identity<float>::type) << std::endl;

prints 16 16. The ICC behavior seems unsound, compared to the GCC / Clang
behavior of (effectively) stripping the attribute from template arguments.

> There is NO way defined at this point to mange for some attributes
> including but not limited to may_alias and alignment.

These can be mangled as <extended-qualifier>s:
http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.qualified-type

Presumably the more problematic part from an ABI perspective is that this will
change a bunch of existing manglings. Similarly from a source compatibility
standpoint, making the alignment override part of the type would be a breaking
change. It'd probably be better to add a new syntax for the new functionality
(please, not based on an attributed typedef this time!) and deprecate the old
way.

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

* [Bug c++/97222] GCC discards attributes aligned and may_alias for typedefs passed as template arguments
  2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
                   ` (2 preceding siblings ...)
  2020-09-29  1:12 ` richard-gccbugzilla at metafoo dot co.uk
@ 2020-09-29 17:48 ` mte.zych at gmail dot com
  2021-12-03 22:05 ` pinskia at gcc dot gnu.org
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: mte.zych at gmail dot com @ 2020-09-29 17:48 UTC (permalink / raw)
  To: gcc-bugs

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

Mateusz Zych <mte.zych at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://bugs.llvm.org/show_
                   |                            |bug.cgi?id=47674

--- Comment #4 from Mateusz Zych <mte.zych at gmail dot com> ---
I just wanted to mention, that I raised issue in the Clang Bugzilla,
since Clang is matching GCC behavior (also discards attributes):

 - https://bugs.llvm.org/show_bug.cgi?id=47674

Thanks, Mateusz

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

* [Bug c++/97222] GCC discards attributes aligned and may_alias for typedefs passed as template arguments
  2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
                   ` (3 preceding siblings ...)
  2020-09-29 17:48 ` mte.zych at gmail dot com
@ 2021-12-03 22:05 ` pinskia at gcc dot gnu.org
  2021-12-04  7:39 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-12-03 22:05 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |myriachan at gmail dot com

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 84415 has been marked as a duplicate of this bug. ***

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

* [Bug c++/97222] GCC discards attributes aligned and may_alias for typedefs passed as template arguments
  2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
                   ` (4 preceding siblings ...)
  2021-12-03 22:05 ` pinskia at gcc dot gnu.org
@ 2021-12-04  7:39 ` pinskia at gcc dot gnu.org
  2021-12-04  7:41 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-12-04  7:39 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |paul.groke at dynatrace dot com

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 82270 has been marked as a duplicate of this bug. ***

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

* [Bug c++/97222] GCC discards attributes aligned and may_alias for typedefs passed as template arguments
  2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
                   ` (5 preceding siblings ...)
  2021-12-04  7:39 ` pinskia at gcc dot gnu.org
@ 2021-12-04  7:41 ` pinskia at gcc dot gnu.org
  2021-12-04  7:41 ` pinskia at gcc dot gnu.org
  2023-01-01 21:30 ` pinskia at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-12-04  7:41 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kip at thevertigo dot com

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 84055 has been marked as a duplicate of this bug. ***

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

* [Bug c++/97222] GCC discards attributes aligned and may_alias for typedefs passed as template arguments
  2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
                   ` (6 preceding siblings ...)
  2021-12-04  7:41 ` pinskia at gcc dot gnu.org
@ 2021-12-04  7:41 ` pinskia at gcc dot gnu.org
  2023-01-01 21:30 ` pinskia at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-12-04  7:41 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |liavonlida at gmail dot com

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 100742 has been marked as a duplicate of this bug. ***

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

* [Bug c++/97222] GCC discards attributes aligned and may_alias for typedefs passed as template arguments
  2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
                   ` (7 preceding siblings ...)
  2021-12-04  7:41 ` pinskia at gcc dot gnu.org
@ 2023-01-01 21:30 ` pinskia at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-01-01 21:30 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ian at geometrian dot com

--- Comment #9 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 108262 has been marked as a duplicate of this bug. ***

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

end of thread, other threads:[~2023-01-01 21:30 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-27 23:07 [Bug c++/97222] New: GCC discards attributes aligned and may_alias for typedefs passed as template arguments mte.zych at gmail dot com
2020-09-28  0:14 ` [Bug c++/97222] " pinskia at gcc dot gnu.org
2020-09-28  7:27 ` rguenth at gcc dot gnu.org
2020-09-29  1:12 ` richard-gccbugzilla at metafoo dot co.uk
2020-09-29 17:48 ` mte.zych at gmail dot com
2021-12-03 22:05 ` pinskia at gcc dot gnu.org
2021-12-04  7:39 ` pinskia at gcc dot gnu.org
2021-12-04  7:41 ` pinskia at gcc dot gnu.org
2021-12-04  7:41 ` pinskia at gcc dot gnu.org
2023-01-01 21:30 ` pinskia at gcc dot gnu.org

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