I hope this is the right fix for the issue.
I've regtested for arm-none-eabi on top of r15-11320-g7909a9f85f30b6 and it 
applies cleanly on trunk.
The new test is derived from 
libstdc++-v3/testsuite/experimental/simd/pr115454_find_last_set.cc.

Ok for trunk, releases/gcc-16 and releases/gcc-15?

--

When testing r15-10798-gae573c9d0e7f1c, I noticed that the
experimental/simd/pr115454_find_last_set.cc was failing due to that the
GNU vector type was used instead of the NEON intrinsic type.

        PR libstdc++/122981

libstdc++-v3/ChangeLog:

        * include/experimental/bits/simd_neon.h: Convert AArch32 NEON
        vpadd_* operands to intrinsic types.
        * testsuite/experimental/simd/pr122981_find_last_set_neon.cc: New test.

Signed-off-by: Torbjörn SVENSSON <[email protected]>
---
 .../include/experimental/bits/simd_neon.h     | 31 +++++++-----
 .../simd/pr122981_find_last_set_neon.cc       | 50 +++++++++++++++++++
 2 files changed, 69 insertions(+), 12 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/experimental/simd/pr122981_find_last_set_neon.cc

diff --git a/libstdc++-v3/include/experimental/bits/simd_neon.h 
b/libstdc++-v3/include/experimental/bits/simd_neon.h
index d3785db2bfd..23c205f3dc9 100644
--- a/libstdc++-v3/include/experimental/bits/simd_neon.h
+++ b/libstdc++-v3/include/experimental/bits/simd_neon.h
@@ -297,9 +297,10 @@ struct _MaskImplNeonMixin
                          __zero))[0];
 #else
              return __vector_bitcast<_UShort>(
-               vpadd_s8(vpadd_s8(vpadd_s8(__lo64(__asint), __hi64(__asint)),
-                                 __zero),
-                        __zero))[0];
+               vpadd_s8(vpadd_s8(vpadd_s8(__to_intrin(__lo64(__asint)),
+                                           __to_intrin(__hi64(__asint))),
+                                 __to_intrin(__zero)),
+                        __to_intrin(__zero)))[0];
 #endif
            }
          else if constexpr (sizeof(_Tp) == 2)
@@ -313,9 +314,10 @@ struct _MaskImplNeonMixin
 #ifdef __aarch64__
              return vaddvq_s16(__asint);
 #else
-             return vpadd_s16(
-               vpadd_s16(vpadd_s16(__lo64(__asint), __hi64(__asint)), __zero),
-               __zero)[0];
+             return vpadd_s16(vpadd_s16(vpadd_s16(__to_intrin(__lo64(__asint)),
+                                                  
__to_intrin(__hi64(__asint))),
+                                        __to_intrin(__zero)),
+                              __to_intrin(__zero))[0];
 #endif
            }
          else if constexpr (sizeof(_Tp) == 4)
@@ -329,8 +331,9 @@ struct _MaskImplNeonMixin
 #ifdef __aarch64__
              return vaddvq_s32(__asint);
 #else
-             return vpadd_s32(vpadd_s32(__lo64(__asint), __hi64(__asint)),
-                              __zero)[0];
+             return vpadd_s32(vpadd_s32(__to_intrin(__lo64(__asint)),
+                                        __to_intrin(__hi64(__asint))),
+                              __to_intrin(__zero))[0];
 #endif
            }
          else if constexpr (sizeof(_Tp) == 8)
@@ -353,8 +356,10 @@ struct _MaskImplNeonMixin
 #ifdef __aarch64__
              return vaddv_s8(__asint);
 #else
-             return vpadd_s8(vpadd_s8(vpadd_s8(__asint, __zero), __zero),
-                             __zero)[0];
+             return vpadd_s8(vpadd_s8(vpadd_s8(__to_intrin(__asint),
+                                               __to_intrin(__zero)),
+                                      __to_intrin(__zero)),
+                             __to_intrin(__zero))[0];
 #endif
            }
          else if constexpr (sizeof(_Tp) == 2)
@@ -368,7 +373,9 @@ struct _MaskImplNeonMixin
 #ifdef __aarch64__
              return vaddv_s16(__asint);
 #else
-             return vpadd_s16(vpadd_s16(__asint, __zero), __zero)[0];
+             return vpadd_s16(vpadd_s16(__to_intrin(__asint),
+                                        __to_intrin(__zero)),
+                              __to_intrin(__zero))[0];
 #endif
            }
          else if constexpr (sizeof(_Tp) == 4)
@@ -377,7 +384,7 @@ struct _MaskImplNeonMixin
 #ifdef __aarch64__
              return vaddv_s32(__asint);
 #else
-             return vpadd_s32(__asint, __zero)[0];
+             return vpadd_s32(__to_intrin(__asint), __to_intrin(__zero))[0];
 #endif
            }
          else
diff --git 
a/libstdc++-v3/testsuite/experimental/simd/pr122981_find_last_set_neon.cc 
b/libstdc++-v3/testsuite/experimental/simd/pr122981_find_last_set_neon.cc
new file mode 100644
index 00000000000..f7f79166ae6
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/simd/pr122981_find_last_set_neon.cc
@@ -0,0 +1,50 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+// { dg-require-effective-target arm_neon_ok }
+// { dg-add-options arm_neon }
+// { dg-require-cmath "" }
+
+#include <experimental/simd>
+
+namespace stdx = std::experimental;
+
+template <typename U, int N>
+using V = stdx::simd<U, stdx::simd_abi::deduce_t<U, N>>;
+
+template <typename U, int N>
+[[gnu::noinline, gnu::noipa]]
+int reduce(typename V<U, N>::mask_type x)
+{
+  using M = typename V<U, N>::mask_type;
+  static_assert(stdx::find_last_set(M(true)) == N - 1);
+  return stdx::find_last_set(x);
+}
+
+int main()
+{
+  // 16 bytes: 16 int8_t lanes, 8 int16_t lanes, 4 int32_t lanes.
+  const int r_int8_16 = reduce<std::int8_t, 16>(typename V<std::int8_t, 
16>::mask_type(true));
+  if (r_int8_16 != 15)
+    __builtin_abort();
+
+  const int r_int16_8 = reduce<std::int16_t, 8>(typename V<std::int16_t, 
8>::mask_type(true));
+  if (r_int16_8 != 7)
+    __builtin_abort();
+
+  const int r_int32_4 = reduce<std::int32_t, 4>(typename V<std::int32_t, 
4>::mask_type(true));
+  if (r_int32_4 != 3)
+    __builtin_abort();
+
+  // 8 bytes: 8 int8_t lanes, 4 int16_t lanes, 2 int32_t lanes.
+  const int r_int8_8 = reduce<std::int8_t, 8>(typename V<std::int8_t, 
8>::mask_type(true));
+  if (r_int8_8 != 7)
+    __builtin_abort();
+
+  const int r_int16_4 = reduce<std::int16_t, 4>(typename V<std::int16_t, 
4>::mask_type(true));
+  if (r_int16_4 != 3)
+    __builtin_abort();
+
+  const int r_int32_2 = reduce<std::int32_t, 2>(typename V<std::int32_t, 
2>::mask_type(true));
+  if (r_int32_2 != 1)
+    __builtin_abort();
+}
-- 
2.43.0

Reply via email to