Repository navigation
Inlining drops a parameter's aligned(1) pointee type: _mm_loadu_si128 becomes an aligned load #439
Description
Issue Summary
The conversion from const v2di * to const v2di_u * produces no cast node, because EDG treats the two types as the same type. For an unmodified parameter with a constant-valued argument, the inliner remaps the parameter to the argument expression itself (vrk_constant_expr, inline.c:476). Inside the
inlined body, *p then dereferences the caller's const v2di *, and gcc assumes the 16-byte alignment of v2di.
The typedef itself is emitted correctly:
typedef long long __m128i_u __attribute((vector_size(16))) attribute((aligned(1))) attribute((may_alias));
Just above, at inline.c:453-470, there is already a special case for gcc and clang targets: it uses a temporary when a function-pointer cast's type isn't identical. This case needs a similar check. When the parameter's type and the argument's type differ in a way that matters to gcc (pointee alignment or
may_alias coming from a typedef), cast the argument to the parameter type or use a temporary of the parameter type.
Reproducing Source Code
typedef long long v2di __attribute__((__vector_size__(16)));
typedef long long v2di_u __attribute__((__vector_size__(16), __may_alias__, __aligned__(1)));
static inline __attribute__((__always_inline__)) v2di load(const v2di_u *p) { return *p; }
v2di inl(const v2di *p) { return load((const v2di_u *)p); } // OK
v2di inl2(const v2di *p) { return load(p); } // wrong
Command-line Options
cpfe --c++17 --gnu_version=150301
Type of Issue
[Front End] This code SHOULD compile with these options.
Additional Details
v2di _Z3inlPKDv2_x( const v2di *p) { return *((const v2di_u *)p); } /* OK */
v2di _Z4inl2PKDv2_x( const v2di *p) { return *p; } /* aligned(1) lost */
With --no_inlining, load keeps its const v2di_u * parameter and the code is correct.
inl2 is exactly how the intrinsic is used. GCC's <emmintrin.h> defines _mm_loadu_si128(__m128i_u const *__P) { return *__P; }, and callers pass a __m128i const *. The same applies to the other loadu and storeu intrinsics, from SSE through AVX-512.
Reproducing (Standard) Configuration(s)
No response
Reproducing (Non-standard) Configuration
No response
I acknowledge that:
- I have checked open issues and existing discussions before filing this report.
- The reproducing source code that I have provided does not depend on headers that I have not included with my submission.
- I have reduced the reproducing source code to the best of my ability.
- I have selected at least one standard configuration or uploaded a non-standard configuration dump.
- I understand code shared via this form is NOT confidential.
- I have permission to share the reproducing source code and grant permission for the project to use the source code (or derivatives of the source code) to create tests.
- I agree that any tests created using the reproducing source code (or deriatives of it) will be licensed under project license unless I included a
LICENSE.txtfile in my.zipor.tar.gzupload. If I included aLICENSE.txtfile, any tests created using the reproducing source code will be governed by the terms of the license I provided instead.
Activity