[clang] [clang] Introduce __builtin_splatvector (PR #212758)

Paul Osmialowski via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 30 07:31:58 PDT 2026


pawosm-arm wrote:

> > > Is there even a platform-generic type for scalable vectors yet?
> > 
> > 
> > Sadly, no.
> 
> That seems like the thing we should solve first. After that I wouldn't be surprised if we didn't need this builtin at all.

With this patch applied, you can already do something along this lines:

```
#include <cstddef>
#include <cstdint>
#include <type_traits>

template <size_t N>
constexpr bool is_scalable_size_v = !N;

template <size_t N>
constexpr bool is_not_scalable_size_v = !!N;

template <size_t N>
using enable_if_scalable_size_t = std::enable_if_t<is_scalable_size_v<N>, bool>;

template <size_t N>
using enable_if_not_scalable_size_t = std::enable_if_t<is_not_scalable_size_v<N>, bool>;

template <typename T, size_t N>
using ext_simd = T [[clang::ext_vector_type(N)]];

#if defined SVE

template <typename T>
using sizeless_simd = typename std::conditional<std::is_same_v<T, bool>, __SVBool_t,
                                typename std::conditional<std::is_same_v<T, int8_t>, __SVInt8_t,
                                typename std::conditional<std::is_same_v<T, int16_t>, __SVInt16_t,
                                typename std::conditional<std::is_same_v<T, int32_t>, __SVInt32_t,
                                typename std::conditional<std::is_same_v<T, int64_t>, __SVInt64_t,
                                typename std::conditional<std::is_same_v<T, uint8_t>, __SVUint8_t,
                                typename std::conditional<std::is_same_v<T, uint16_t>, __SVUint16_t,
                                typename std::conditional<std::is_same_v<T, uint32_t>, __SVUint32_t,
                                typename std::conditional<std::is_same_v<T, uint64_t>, __SVUint64_t,
                                typename std::conditional<std::is_same_v<T, float>, __SVFloat32_t,
                                typename std::conditional<std::is_same_v<T, double>, __SVFloat64_t,
                                typename std::conditional<std::is_same_v<T, float _Complex>, __clang_svfloat32x2_t,
                                typename std::conditional<std::is_same_v<T, double _Complex>, __clang_svfloat64x2_t,
                                void >::type>::type>::type>::type>::type>::type>::type>::type>::type>::type>::type>::type>::type;

#elif defined RVV

// Fill it in with RVV type mappings

#else

template <typename T>
using sizeless_simd = typename std::conditional<std::is_same_v<T, bool>, void>::type;

#endif

template <typename T, size_t N = 0U>
using simd = typename std::conditional<is_not_scalable_size_v<N>, ext_simd<T, is_scalable_size_v<N> ? 1 : N>, sizeless_simd<T>>::type;

template <typename T, size_t N,
          enable_if_not_scalable_size_t<N> = 0>
constexpr static simd<T, N> splat(T v) {
  return simd<T, N>(v);
}
template <typename T, size_t N = 0U,
          enable_if_scalable_size_t<N> = 0>
static simd<T, N> splat(T v) {
  return __builtin_splatvector(v, simd<T, N>);
}

const auto vi32x8 = splat<int, 8U>(3);

double fun(void) {
  const auto sv = splat<double>(123);
  return sv[0];
}
```

https://github.com/llvm/llvm-project/pull/212758


More information about the cfe-commits mailing list