@@ -226,24 +226,42 @@ simd_call_helper(const void *obj_ptr,
226
226
return f (simd_args...);
227
227
};
228
228
229
+ #ifdef _GLIBCXX_RELEASE
230
+ #if _GLIBCXX_RELEASE < 10
231
+ #define __INVOKE_SIMD_USE_STD_IS_FUNCTION_WA
232
+ #endif // _GLIBCXX_RELEASE < 10
233
+ #endif // _GLIBCXX_RELEASE
234
+
235
+ #ifdef __INVOKE_SIMD_USE_STD_IS_FUNCTION_WA
229
236
// TODO This is a workaround for libstdc++ version 9 buggy behavior which
230
237
// returns false in the code below. Version 10 works fine. Once required
231
238
// minimum libstdc++ version is bumped to 10, this w/a should be removed.
232
239
// template <class F> bool foo(F &&f) {
233
240
// return std::is_function_v<std::remove_reference_t<F>>;
234
241
// }
235
242
// where F is a function type with __regcall.
236
- template <class F > struct is_regcall_function : std::false_type {};
243
+ template <class F > struct is_regcall_function_ptr_or_ref_v : std::false_type {};
237
244
238
245
template <class Ret , class ... Args>
239
- struct is_regcall_function <Ret(__regcall *)(Args...)> : std::true_type {};
246
+ struct is_regcall_function_ptr_or_ref_v <Ret(__regcall &)(Args...)>
247
+ : std::true_type {};
240
248
241
249
template <class Ret , class ... Args>
242
- struct is_regcall_function <Ret(__regcall &)(Args...)> : std::true_type {};
250
+ struct is_regcall_function_ptr_or_ref_v <Ret(__regcall *)(Args...)>
251
+ : std::true_type {};
243
252
244
253
template <class F >
245
- static constexpr bool is_regcall_function_v = is_regcall_function<F>::value;
246
-
254
+ static constexpr bool is_regcall_function_ptr_or_ref_v =
255
+ is_regcall_function_ptr_or_ref_v<F>::value;
256
+ #endif // __INVOKE_SIMD_USE_STD_IS_FUNCTION_WA
257
+
258
+ template <class Callable >
259
+ static constexpr bool is_function_ptr_or_ref_v =
260
+ std::is_function_v<std::remove_pointer_t <std::remove_reference_t <Callable>>>
261
+ #ifdef __INVOKE_SIMD_USE_STD_IS_FUNCTION_WA
262
+ || is_regcall_function_ptr_or_ref_v<Callable>
263
+ #endif // __INVOKE_SIMD_USE_STD_IS_FUNCTION_WA
264
+ ;
247
265
} // namespace detail
248
266
249
267
// --- The main API
@@ -274,11 +292,7 @@ __attribute__((always_inline)) auto invoke_simd(sycl::sub_group sg,
274
292
// is fine in this case.
275
293
constexpr int N = detail::get_sg_size<Callable, T...>();
276
294
using RetSpmd = detail::SpmdRetType<N, Callable, T...>;
277
-
278
- using CallableNoRef = std::remove_reference_t <Callable>;
279
- using CallableNoRefNoPtr = std::remove_pointer_t <CallableNoRef>;
280
- constexpr bool is_function = std::is_function_v<CallableNoRefNoPtr> ||
281
- detail::is_regcall_function_v<Callable>;
295
+ constexpr bool is_function = detail::is_function_ptr_or_ref_v<Callable>;
282
296
283
297
if constexpr (is_function) {
284
298
return __builtin_invoke_simd<is_function, RetSpmd>(
0 commit comments