public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Make std::experimental::simd (more) usable with Clang
@ 2023-03-21  9:22 Matthias Kretz
  2023-03-21  9:23 ` [PATCH 1/2] libstdc++: Fix simd test compilation " Matthias Kretz
  2023-03-21  9:23 ` [PATCH 2/2] libstdc++: Fix simd " Matthias Kretz
  0 siblings, 2 replies; 6+ messages in thread
From: Matthias Kretz @ 2023-03-21  9:22 UTC (permalink / raw)
  To: gcc-patches, libstdc++

Up to now, compiling std::experimental::simd with Clang would lead to wrong 
code, not compiling, or ICEs. After these patches I hope it's only ICEs.

Tested on x86_64-pc-linux-gnu.

Matthias Kretz (2):
  libstdc++: Fix simd test compilation with Clang
  libstdc++: Fix simd compilation with Clang

 .../include/experimental/bits/simd_detail.h   |  2 +-
 .../include/experimental/bits/simd_x86.h      | 59 +++++++++++++++++--
 .../experimental/simd/tests/operators.cc      |  9 ++-
 3 files changed, 64 insertions(+), 6 deletions(-)

-- 
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
 stdₓ::simd
──────────────────────────────────────────────────────────────────────────


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

* [PATCH 1/2] libstdc++: Fix simd test compilation with Clang
  2023-03-21  9:22 [PATCH 0/2] Make std::experimental::simd (more) usable with Clang Matthias Kretz
@ 2023-03-21  9:23 ` Matthias Kretz
  2023-03-21 11:16   ` Jonathan Wakely
  2023-03-21  9:23 ` [PATCH 2/2] libstdc++: Fix simd " Matthias Kretz
  1 sibling, 1 reply; 6+ messages in thread
From: Matthias Kretz @ 2023-03-21  9:23 UTC (permalink / raw)
  To: gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 929 bytes --]



Signed-off-by: Matthias Kretz <m.kretz@gsi.de>

libstdc++-v3/ChangeLog:

	* testsuite/experimental/simd/tests/operators.cc: Clang doesn't
	define __GCC_IEC_559. Use __STDC_IEC_559__ instead.
---
 .../testsuite/experimental/simd/tests/operators.cc       | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)


--
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
 stdₓ::simd
──────────────────────────────────────────────────────────────────────────

[-- Attachment #2: 0001-libstdc-Fix-simd-test-compilation-with-Clang.patch --]
[-- Type: text/x-patch, Size: 720 bytes --]

diff --git a/libstdc++-v3/testsuite/experimental/simd/tests/operators.cc b/libstdc++-v3/testsuite/experimental/simd/tests/operators.cc
index c4d91fa5d2b..72af7061c73 100644
--- a/libstdc++-v3/testsuite/experimental/simd/tests/operators.cc
+++ b/libstdc++-v3/testsuite/experimental/simd/tests/operators.cc
@@ -211,7 +211,14 @@ test()
     }
 
     // divides
-    constexpr bool is_iec559 = __GCC_IEC_559 >= 2;
+    constexpr bool is_iec559 =
+#ifdef __GCC_IEC_559
+      __GCC_IEC_559 >= 2;
+#elif defined __STDC_IEC_559__
+      true;
+#else
+      false;
+#endif
     if constexpr (std::is_floating_point_v<T> && !is_iec559)
       { // avoid testing subnormals and expect minor deltas for non-IEC559 float
 	V x = 2;

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

* [PATCH 2/2] libstdc++: Fix simd compilation with Clang
  2023-03-21  9:22 [PATCH 0/2] Make std::experimental::simd (more) usable with Clang Matthias Kretz
  2023-03-21  9:23 ` [PATCH 1/2] libstdc++: Fix simd test compilation " Matthias Kretz
@ 2023-03-21  9:23 ` Matthias Kretz
  2023-03-21 11:19   ` Jonathan Wakely
  1 sibling, 1 reply; 6+ messages in thread
From: Matthias Kretz @ 2023-03-21  9:23 UTC (permalink / raw)
  To: gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 1720 bytes --]



Clang fails to compile some constant expressions involving simd.
Therefore, just disable this non-conforming extension for clang.

Fix AVX512 blend implementation for Clang. It was converting the bitmask
to bool before, which is obviously wrong. Instead use a Clang builtin to
convert the bitmask to vector-mask before using a vector blend ?:. A
similar change is required for the masked unary implementation, because
the GCC builtins do not exist on Clang.

Signed-off-by: Matthias Kretz <m.kretz@gsi.de>

libstdc++-v3/ChangeLog:

	* include/experimental/bits/simd_detail.h: Don't declare the
	simd API as constexpr with Clang.
	* include/experimental/bits/simd_x86.h (__movm): New.
	(_S_blend_avx512): Resolve FIXME. Implement blend using __movm
	and ?:.
	(_SimdImplX86::_S_masked_unary): Clang does not implement the
	same builtins. Implement the function using __movm, ?:, and -
	operators on vector_size types instead.
---
 .../include/experimental/bits/simd_detail.h   |  2 +-
 .../include/experimental/bits/simd_x86.h      | 59 +++++++++++++++++--
 2 files changed, 56 insertions(+), 5 deletions(-)


--
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
 stdₓ::simd
──────────────────────────────────────────────────────────────────────────

[-- Attachment #2: 0002-libstdc-Fix-simd-compilation-with-Clang.patch --]
[-- Type: text/x-patch, Size: 4087 bytes --]

diff --git a/libstdc++-v3/include/experimental/bits/simd_detail.h b/libstdc++-v3/include/experimental/bits/simd_detail.h
index 30cc1ef0eef..f3745bf3e4c 100644
--- a/libstdc++-v3/include/experimental/bits/simd_detail.h
+++ b/libstdc++-v3/include/experimental/bits/simd_detail.h
@@ -267,7 +267,7 @@ namespace experimental
 #define _GLIBCXX_SIMD_IS_UNLIKELY(__x) __builtin_expect(__x, 0)
 #define _GLIBCXX_SIMD_IS_LIKELY(__x) __builtin_expect(__x, 1)
 
-#if defined __STRICT_ANSI__ && __STRICT_ANSI__
+#if (defined __STRICT_ANSI__ && __STRICT_ANSI__) || defined __clang__
 #define _GLIBCXX_SIMD_CONSTEXPR
 #define _GLIBCXX_SIMD_USE_CONSTEXPR_API const
 #else
diff --git a/libstdc++-v3/include/experimental/bits/simd_x86.h b/libstdc++-v3/include/experimental/bits/simd_x86.h
index 608918542c6..165738c4e2c 100644
--- a/libstdc++-v3/include/experimental/bits/simd_x86.h
+++ b/libstdc++-v3/include/experimental/bits/simd_x86.h
@@ -363,6 +363,53 @@ __maskload_pd(const double* __ptr, _Tp __k)
 
 // }}}
 
+#ifdef __clang__
+template <size_t _Np, typename _Tp, typename _Kp>
+  _GLIBCXX_SIMD_INTRINSIC constexpr auto
+  __movm(_Kp __k) noexcept
+  {
+    static_assert(is_unsigned_v<_Kp>);
+    if constexpr (sizeof(_Tp) == 1 && __have_avx512bw)
+      {
+	if constexpr (_Np <= 16 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2b128(__k);
+	else if constexpr (_Np <= 32 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2b256(__k);
+	else
+	  return __builtin_ia32_cvtmask2b512(__k);
+      }
+    else if constexpr (sizeof(_Tp) == 2 && __have_avx512bw)
+      {
+	if constexpr (_Np <= 8 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2w128(__k);
+	else if constexpr (_Np <= 16 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2w256(__k);
+	else
+	  return __builtin_ia32_cvtmask2w512(__k);
+      }
+    else if constexpr (sizeof(_Tp) == 4 && __have_avx512dq)
+      {
+	if constexpr (_Np <= 4 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2d128(__k);
+	else if constexpr (_Np <= 8 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2d256(__k);
+	else
+	  return __builtin_ia32_cvtmask2d512(__k);
+      }
+    else if constexpr (sizeof(_Tp) == 8 && __have_avx512dq)
+      {
+	if constexpr (_Np <= 2 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2q128(__k);
+	else if constexpr (_Np <= 4 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2q256(__k);
+	else
+	  return __builtin_ia32_cvtmask2q512(__k);
+      }
+    else
+      __assert_unreachable<_Tp>();
+  }
+#endif // __clang__
+
 #ifdef _GLIBCXX_SIMD_WORKAROUND_PR85048
 #include "simd_x86_conversions.h"
 #endif
@@ -619,14 +666,13 @@ _pdep_u32(
     _GLIBCXX_SIMD_INTRINSIC static _TV
     _S_blend_avx512(const _Kp __k, const _TV __a, const _TV __b) noexcept
     {
-#ifdef __clang__
-      // FIXME: this does a boolean choice, not a blend
-      return __k ? __a : __b;
-#else
       static_assert(__is_vector_type_v<_TV>);
       using _Tp = typename _VectorTraits<_TV>::value_type;
       static_assert(sizeof(_TV) >= 16);
       static_assert(sizeof(_Tp) <= 8);
+#ifdef __clang__
+      return __movm<_VectorTraits<_TV>::_S_full_size, _Tp>(__k) ? __b : __a;
+#else
       using _IntT
 	= conditional_t<(sizeof(_Tp) > 2),
 			conditional_t<sizeof(_Tp) == 4, int, long long>,
@@ -3483,6 +3529,10 @@ _S_masked_unary(const _SimdWrapper<_K, _Np> __k, const _SimdWrapper<_Tp, _Np> __
 	    // optimize masked unary increment and decrement as masked sub +/-1
 	    constexpr int __pm_one
 	      = is_same_v<_Op<void>, __increment<void>> ? -1 : 1;
+#ifdef __clang__
+	    return __vector_bitcast<_Tp, _Np>(__movm<_Np, _Tp>(__k._M_data))
+		     ? __v._M_data - __pm_one : __v._M_data;
+#else // __clang__
 	    if constexpr (is_integral_v<_Tp>)
 	      {
 		constexpr bool __lp64 = sizeof(long) == sizeof(long long);
@@ -3526,6 +3576,7 @@ _S_masked_unary(const _SimdWrapper<_K, _Np> __k, const _SimdWrapper<_Tp, _Np> __
 		_GLIBCXX_SIMD_MASK_SUB(8, 16, subpd128);
 #undef _GLIBCXX_SIMD_MASK_SUB
 	      }
+#endif // __clang__
 	  }
 	else
 	  return _Base::template _S_masked_unary<_Op>(__k, __v);

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

* Re: [PATCH 1/2] libstdc++: Fix simd test compilation with Clang
  2023-03-21  9:23 ` [PATCH 1/2] libstdc++: Fix simd test compilation " Matthias Kretz
@ 2023-03-21 11:16   ` Jonathan Wakely
  0 siblings, 0 replies; 6+ messages in thread
From: Jonathan Wakely @ 2023-03-21 11:16 UTC (permalink / raw)
  To: Matthias Kretz; +Cc: gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 327 bytes --]

On Tue, 21 Mar 2023 at 09:24, Matthias Kretz via Libstdc++ <
libstdc++@gcc.gnu.org> wrote:

>
>
> Signed-off-by: Matthias Kretz <m.kretz@gsi.de>
>
> libstdc++-v3/ChangeLog:
>
>         * testsuite/experimental/simd/tests/operators.cc: Clang doesn't
>         define __GCC_IEC_559. Use __STDC_IEC_559__ instead.
>


OK, thanks.

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

* Re: [PATCH 2/2] libstdc++: Fix simd compilation with Clang
  2023-03-21  9:23 ` [PATCH 2/2] libstdc++: Fix simd " Matthias Kretz
@ 2023-03-21 11:19   ` Jonathan Wakely
  2023-03-21 17:01     ` [committed] " Matthias Kretz
  0 siblings, 1 reply; 6+ messages in thread
From: Jonathan Wakely @ 2023-03-21 11:19 UTC (permalink / raw)
  To: Matthias Kretz; +Cc: gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 1338 bytes --]

On Tue, 21 Mar 2023 at 09:24, Matthias Kretz via Libstdc++ <
libstdc++@gcc.gnu.org> wrote:

>
>
> Clang fails to compile some constant expressions involving simd.
> Therefore, just disable this non-conforming extension for clang.
>
> Fix AVX512 blend implementation for Clang. It was converting the bitmask
> to bool before, which is obviously wrong. Instead use a Clang builtin to
> convert the bitmask to vector-mask before using a vector blend ?:. A
> similar change is required for the masked unary implementation, because
> the GCC builtins do not exist on Clang.
>
> Signed-off-by: Matthias Kretz <m.kretz@gsi.de>
>
> libstdc++-v3/ChangeLog:
>
>         * include/experimental/bits/simd_detail.h: Don't declare the
>         simd API as constexpr with Clang.
>         * include/experimental/bits/simd_x86.h (__movm): New.
>         (_S_blend_avx512): Resolve FIXME. Implement blend using __movm
>         and ?:.
>         (_SimdImplX86::_S_masked_unary): Clang does not implement the
>         same builtins. Implement the function using __movm, ?:, and -
>         operators on vector_size types instead.
>


+#if (defined __STRICT_ANSI__ && __STRICT_ANSI__) || defined __clang__

We don't generally are about -Wundef so this could be simplified to:

#if __STRICT_ANSI__ || defined __clang__

But it's OK as it is. OK for trunk.

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

* [committed] libstdc++: Fix simd compilation with Clang
  2023-03-21 11:19   ` Jonathan Wakely
@ 2023-03-21 17:01     ` Matthias Kretz
  0 siblings, 0 replies; 6+ messages in thread
From: Matthias Kretz @ 2023-03-21 17:01 UTC (permalink / raw)
  To: gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 1879 bytes --]

Slightly modified patch. I had to fix floating-point AVX512 blending on 
Clang by removing a cast. While at it I cleaned up the -Wundef noise.

----- 8< ------

Clang fails to compile some constant expressions involving simd.
Therefore, just disable this non-conforming extension for clang.

Fix AVX512 blend implementation for Clang. It was converting the bitmask
to bool before, which is obviously wrong. Instead use a Clang builtin to
convert the bitmask to vector-mask before using a vector blend ?:. A
similar change is required for the masked unary implementation, because
the GCC builtins do not exist on Clang.

Signed-off-by: Matthias Kretz <m.kretz@gsi.de>

libstdc++-v3/ChangeLog:

	* include/experimental/bits/simd_detail.h: Don't declare the
	simd API as constexpr with Clang.
	* include/experimental/bits/simd_x86.h (__movm): New.
	(_S_blend_avx512): Resolve FIXME. Implement blend using __movm
	and ?:.
	(_SimdImplX86::_S_masked_unary): Clang does not implement the
	same builtins. Implement the function using __movm, ?:, and -
	operators on vector_size types instead.
---
 .../include/experimental/bits/simd_detail.h   |  2 +-
 .../include/experimental/bits/simd_x86.h      | 58 +++++++++++++++++--
 2 files changed, 55 insertions(+), 5 deletions(-)


--
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
 stdₓ::simd
──────────────────────────────────────────────────────────────────────────

[-- Attachment #2: 0001-libstdc-Fix-simd-compilation-with-Clang.patch --]
[-- Type: text/x-patch, Size: 4021 bytes --]

diff --git a/libstdc++-v3/include/experimental/bits/simd_detail.h b/libstdc++-v3/include/experimental/bits/simd_detail.h
index 30cc1ef0eef..49b94decf0a 100644
--- a/libstdc++-v3/include/experimental/bits/simd_detail.h
+++ b/libstdc++-v3/include/experimental/bits/simd_detail.h
@@ -267,7 +267,7 @@ namespace experimental
 #define _GLIBCXX_SIMD_IS_UNLIKELY(__x) __builtin_expect(__x, 0)
 #define _GLIBCXX_SIMD_IS_LIKELY(__x) __builtin_expect(__x, 1)
 
-#if defined __STRICT_ANSI__ && __STRICT_ANSI__
+#if __STRICT_ANSI__ || defined __clang__
 #define _GLIBCXX_SIMD_CONSTEXPR
 #define _GLIBCXX_SIMD_USE_CONSTEXPR_API const
 #else
diff --git a/libstdc++-v3/include/experimental/bits/simd_x86.h b/libstdc++-v3/include/experimental/bits/simd_x86.h
index 608918542c6..7b8f1c664b3 100644
--- a/libstdc++-v3/include/experimental/bits/simd_x86.h
+++ b/libstdc++-v3/include/experimental/bits/simd_x86.h
@@ -363,6 +363,53 @@ __maskload_pd(const double* __ptr, _Tp __k)
 
 // }}}
 
+#ifdef __clang__
+template <size_t _Np, typename _Tp, typename _Kp>
+  _GLIBCXX_SIMD_INTRINSIC constexpr auto
+  __movm(_Kp __k) noexcept
+  {
+    static_assert(is_unsigned_v<_Kp>);
+    if constexpr (sizeof(_Tp) == 1 && __have_avx512bw)
+      {
+	if constexpr (_Np <= 16 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2b128(__k);
+	else if constexpr (_Np <= 32 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2b256(__k);
+	else
+	  return __builtin_ia32_cvtmask2b512(__k);
+      }
+    else if constexpr (sizeof(_Tp) == 2 && __have_avx512bw)
+      {
+	if constexpr (_Np <= 8 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2w128(__k);
+	else if constexpr (_Np <= 16 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2w256(__k);
+	else
+	  return __builtin_ia32_cvtmask2w512(__k);
+      }
+    else if constexpr (sizeof(_Tp) == 4 && __have_avx512dq)
+      {
+	if constexpr (_Np <= 4 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2d128(__k);
+	else if constexpr (_Np <= 8 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2d256(__k);
+	else
+	  return __builtin_ia32_cvtmask2d512(__k);
+      }
+    else if constexpr (sizeof(_Tp) == 8 && __have_avx512dq)
+      {
+	if constexpr (_Np <= 2 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2q128(__k);
+	else if constexpr (_Np <= 4 && __have_avx512vl)
+	  return __builtin_ia32_cvtmask2q256(__k);
+	else
+	  return __builtin_ia32_cvtmask2q512(__k);
+      }
+    else
+      __assert_unreachable<_Tp>();
+  }
+#endif // __clang__
+
 #ifdef _GLIBCXX_SIMD_WORKAROUND_PR85048
 #include "simd_x86_conversions.h"
 #endif
@@ -619,14 +666,13 @@ _pdep_u32(
     _GLIBCXX_SIMD_INTRINSIC static _TV
     _S_blend_avx512(const _Kp __k, const _TV __a, const _TV __b) noexcept
     {
-#ifdef __clang__
-      // FIXME: this does a boolean choice, not a blend
-      return __k ? __a : __b;
-#else
       static_assert(__is_vector_type_v<_TV>);
       using _Tp = typename _VectorTraits<_TV>::value_type;
       static_assert(sizeof(_TV) >= 16);
       static_assert(sizeof(_Tp) <= 8);
+#ifdef __clang__
+      return __movm<_VectorTraits<_TV>::_S_full_size, _Tp>(__k) ? __b : __a;
+#else
       using _IntT
 	= conditional_t<(sizeof(_Tp) > 2),
 			conditional_t<sizeof(_Tp) == 4, int, long long>,
@@ -3483,6 +3529,9 @@ _S_masked_unary(const _SimdWrapper<_K, _Np> __k, const _SimdWrapper<_Tp, _Np> __
 	    // optimize masked unary increment and decrement as masked sub +/-1
 	    constexpr int __pm_one
 	      = is_same_v<_Op<void>, __increment<void>> ? -1 : 1;
+#ifdef __clang__
+	    return __movm<_Np, _Tp>(__k._M_data) ? __v._M_data - __pm_one : __v._M_data;
+#else // __clang__
 	    if constexpr (is_integral_v<_Tp>)
 	      {
 		constexpr bool __lp64 = sizeof(long) == sizeof(long long);
@@ -3526,6 +3575,7 @@ _S_masked_unary(const _SimdWrapper<_K, _Np> __k, const _SimdWrapper<_Tp, _Np> __
 		_GLIBCXX_SIMD_MASK_SUB(8, 16, subpd128);
 #undef _GLIBCXX_SIMD_MASK_SUB
 	      }
+#endif // __clang__
 	  }
 	else
 	  return _Base::template _S_masked_unary<_Op>(__k, __v);

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

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

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-21  9:22 [PATCH 0/2] Make std::experimental::simd (more) usable with Clang Matthias Kretz
2023-03-21  9:23 ` [PATCH 1/2] libstdc++: Fix simd test compilation " Matthias Kretz
2023-03-21 11:16   ` Jonathan Wakely
2023-03-21  9:23 ` [PATCH 2/2] libstdc++: Fix simd " Matthias Kretz
2023-03-21 11:19   ` Jonathan Wakely
2023-03-21 17:01     ` [committed] " Matthias Kretz

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