| // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=SYSV |
| // RUN: %clang_cc1 -triple x86_64-scei-ps4 -std=c++20 -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=PS |
| // RUN: %clang_cc1 -triple x86_64-sie-ps5 -std=c++20 -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=PS |
| |
| typedef float v8f __attribute__((vector_size(32))); |
| typedef float v16f __attribute__((vector_size(64))); |
| |
| struct S { |
| __attribute__((target("avx"))) |
| v8f m(v8f x) { return x; } |
| }; |
| |
| struct C { |
| v8f field; |
| __attribute__((target("avx"))) |
| C(v8f x) : field(x) {} |
| }; |
| |
| __attribute__((target("avx"))) |
| v8f callm(S *s, v8f x) { |
| return s->m(x); |
| } |
| |
| __attribute__((target("avx"))) |
| v8f callctor(v8f x) { |
| C c(x); |
| return c.field; |
| } |
| |
| __attribute__((target("avx"))) |
| v8f callm_ptr(S *s, v8f x) { |
| v8f (S::*pmf)(v8f) = &S::m; |
| return (s->*pmf)(x); |
| } |
| |
| struct S512 { |
| __attribute__((target("avx512f"))) |
| v16f m512(v16f x) { return x; } |
| }; |
| |
| struct D512 { |
| v16f field; |
| __attribute__((target("avx512f"))) |
| D512(v16f x) : field(x) {} |
| }; |
| |
| __attribute__((target("avx512f"))) |
| v16f callm512(S512 *s, v16f x) { |
| return s->m512(x); |
| } |
| |
| __attribute__((target("avx512f"))) |
| v16f callctor512(v16f x) { |
| D512 c(x); |
| return c.field; |
| } |
| |
| __attribute__((target("avx512f"))) |
| v16f callm512_ptr(S512 *s, v16f x) { |
| v16f (S512::*pmf)(v16f) = &S512::m512; |
| return (s->*pmf)(x); |
| } |
| |
| // Desired ABI behavior: AVX-targeted member functions should pass/return AVX |
| // vectors directly, just like AVX-targeted free functions. |
| // SYSV-LABEL: define dso_local noundef <8 x float> @_Z5callmP1SDv8_f( |
| // SYSV: call noundef <8 x float> @_ZN1S1mEDv8_f(ptr noundef |
| // SYSV-LABEL: define linkonce_odr noundef <8 x float> @_ZN1S1mEDv8_f( |
| // SYSV-SAME: ptr noundef nonnull align 1 dereferenceable(1) %this, <8 x float> noundef %x) |
| // SYSV-LABEL: define dso_local noundef <8 x float> @_Z8callctorDv8_f( |
| // SYSV: call void @_ZN1CC1EDv8_f(ptr noundef nonnull align 32 dereferenceable(32) |
| // SYSV-SAME: <8 x float> noundef |
| // SYSV-LABEL: define linkonce_odr void @_ZN1CC1EDv8_f( |
| // SYSV-SAME: ptr noundef nonnull align 32 dereferenceable(32) %this, <8 x float> noundef %x) |
| // SYSV-LABEL: define dso_local noundef <8 x float> @_Z9callm_ptrP1SDv8_f( |
| // SYSV-SAME: ptr noundef %s, <8 x float> noundef %x) |
| // SYSV: call noundef <8 x float> %{{.*}}(ptr noundef nonnull align 1 dereferenceable(1) %{{.*}}, <8 x float> noundef |
| // SYSV-LABEL: define dso_local noundef <16 x float> @_Z8callm512P4S512Dv16_f( |
| // SYSV: call noundef <16 x float> @_ZN4S5124m512EDv16_f(ptr noundef |
| // SYSV-LABEL: define linkonce_odr noundef <16 x float> @_ZN4S5124m512EDv16_f( |
| // SYSV-SAME: ptr noundef nonnull align 1 dereferenceable(1) %this, <16 x float> noundef %x) |
| // SYSV-LABEL: define dso_local noundef <16 x float> @_Z11callctor512Dv16_f( |
| // SYSV: call void @_ZN4D512C1EDv16_f(ptr noundef nonnull align 64 dereferenceable(64) |
| // SYSV-SAME: <16 x float> noundef |
| // SYSV-LABEL: define linkonce_odr void @_ZN4D512C1EDv16_f( |
| // SYSV-SAME: ptr noundef nonnull align 64 dereferenceable(64) %this, <16 x float> noundef %x) |
| // SYSV-LABEL: define dso_local noundef <16 x float> @_Z12callm512_ptrP4S512Dv16_f( |
| // SYSV-SAME: ptr noundef %s, <16 x float> noundef %x) |
| // SYSV: call noundef <16 x float> %{{.*}}(ptr noundef nonnull align 1 dereferenceable(1) %{{.*}}, <16 x float> noundef |
| // SYSV-LABEL: define linkonce_odr void @_ZN1CC2EDv8_f( |
| // SYSV-SAME: ptr noundef nonnull align 32 dereferenceable(32) %this, <8 x float> noundef %x) |
| // SYSV-LABEL: define linkonce_odr void @_ZN4D512C2EDv16_f( |
| // SYSV-SAME: ptr noundef nonnull align 64 dereferenceable(64) %this, <16 x float> noundef %x) |
| |
| // PlayStation keeps the legacy ABI which always returns AVX vectors in registers & only uses AVX level from module/TU level even with AVX target attributes. |
| // PS-LABEL: define dso_local noundef <8 x float> @_Z5callmP1SDv8_f( |
| // PS: byval(<8 x float>) align 32 |
| // PS: call noundef <8 x float> @_ZN1S1mEDv8_f( |
| // PS-LABEL: define linkonce_odr noundef <8 x float> @_ZN1S1mEDv8_f( |
| // PS: byval(<8 x float>) align 32 |
| // PS-LABEL: define dso_local noundef <8 x float> @_Z8callctorDv8_f( |
| // PS-LABEL: define linkonce_odr void @_ZN1CC1EDv8_f( |
| // PS-SAME: ptr noundef nonnull align 32 dereferenceable(32) %this, ptr noundef byval(<8 x float>) align 32 |
| // PS-LABEL: define dso_local noundef <8 x float> @_Z9callm_ptrP1SDv8_f( |
| // PS-SAME: ptr noundef %s, ptr noundef byval(<8 x float>) align 32 |
| // PS: call noundef <8 x float> %{{.*}}(ptr noundef nonnull align 1 dereferenceable(1) %{{.*}}, ptr noundef byval(<8 x float>) align 32 |
| // PS-LABEL: define dso_local noundef <16 x float> @_Z8callm512P4S512Dv16_f( |
| // PS: byval(<16 x float>) align 64 |
| // PS: call noundef <16 x float> @_ZN4S5124m512EDv16_f( |
| // PS-LABEL: define linkonce_odr noundef <16 x float> @_ZN4S5124m512EDv16_f( |
| // PS: byval(<16 x float>) align 64 |
| // PS-LABEL: define dso_local noundef <16 x float> @_Z11callctor512Dv16_f( |
| // PS-LABEL: define linkonce_odr void @_ZN4D512C1EDv16_f( |
| // PS-SAME: ptr noundef nonnull align 64 dereferenceable(64) %this, ptr noundef byval(<16 x float>) align 64 |
| // PS-LABEL: define dso_local noundef <16 x float> @_Z12callm512_ptrP4S512Dv16_f( |
| // PS-SAME: ptr noundef %s, ptr noundef byval(<16 x float>) align 64 |
| // PS: call noundef <16 x float> %{{.*}}(ptr noundef nonnull align 1 dereferenceable(1) %{{.*}}, ptr noundef byval(<16 x float>) align 64 |
| // PS-LABEL: define linkonce_odr void @_ZN1CC2EDv8_f( |
| // PS-SAME: ptr noundef nonnull align 32 dereferenceable(32) %this, ptr noundef byval(<8 x float>) align 32 |
| // PS-LABEL: define linkonce_odr void @_ZN4D512C2EDv16_f( |
| // PS-SAME: ptr noundef nonnull align 64 dereferenceable(64) %this, ptr noundef byval(<16 x float>) align 64 |