diff options
| author | sricker-nvidia <115114531+sricker-nvidia@users.noreply.github.com> | 2025-05-05 15:30:33 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-05 22:30:33 +0000 |
| commit | 50d9781b7387b0f7f56d19c72afcf390cca72b72 (patch) | |
| tree | 7b6f1401f7a8257fa378930a052ca63f0fda91f4 /prelude | |
| parent | 698e43372cefe0fff13150925aeb7f389c21a938 (diff) | |
Add countbits 16-bit and 8-bit support (#6433) (#6897)
Change adds 16-bit and 8-bit support for countbits intrinsic. In
cases where a backend's native counbits lacks support, support
is emulated.
New tests are added for 16-bit and 8-bit support. Additional testing
added for 32-bit and minor updates made to 64-bit countbits.
Diffstat (limited to 'prelude')
| -rw-r--r-- | prelude/slang-cpp-scalar-intrinsics.h | 97 | ||||
| -rw-r--r-- | prelude/slang-cuda-prelude.h | 97 |
2 files changed, 124 insertions, 70 deletions
diff --git a/prelude/slang-cpp-scalar-intrinsics.h b/prelude/slang-cpp-scalar-intrinsics.h index 0a19eb327..9b045941a 100644 --- a/prelude/slang-cpp-scalar-intrinsics.h +++ b/prelude/slang-cpp-scalar-intrinsics.h @@ -628,45 +628,13 @@ SLANG_FORCE_INLINE double F64_calcSafeRadians(double radians) return (a * (SLANG_PRELUDE_PI * 2)); } -// ----------------------------- I32 ----------------------------------------- - -SLANG_FORCE_INLINE int32_t I32_abs(int32_t f) -{ - return (f < 0) ? -f : f; -} - -SLANG_FORCE_INLINE int32_t I32_min(int32_t a, int32_t b) -{ - return a < b ? a : b; -} -SLANG_FORCE_INLINE int32_t I32_max(int32_t a, int32_t b) -{ - return a > b ? a : b; -} - -SLANG_FORCE_INLINE float I32_asfloat(int32_t x) -{ - Union32 u; - u.i = x; - return u.f; -} -SLANG_FORCE_INLINE uint32_t I32_asuint(int32_t x) -{ - return uint32_t(x); -} -SLANG_FORCE_INLINE double I32_asdouble(int32_t low, int32_t hi) -{ - Union64 u; - u.u = (uint64_t(hi) << 32) | uint32_t(low); - return u.d; -} - -SLANG_FORCE_INLINE uint32_t I32_countbits(int32_t v) +// ----------------------------- U16 ----------------------------------------- +SLANG_FORCE_INLINE uint32_t U16_countbits(uint16_t v) { #if SLANG_GCC_FAMILY && !defined(SLANG_LLVM) return __builtin_popcount(uint32_t(v)); #elif SLANG_PROCESSOR_X86_64 && SLANG_VC - return __popcnt(uint32_t(v)); + return __popcnt16(v); #else uint32_t c = 0; while (v) @@ -678,6 +646,25 @@ SLANG_FORCE_INLINE uint32_t I32_countbits(int32_t v) #endif } +// ----------------------------- I16 ----------------------------------------- +SLANG_FORCE_INLINE uint32_t I16_countbits(int16_t v) +{ + return U16_countbits(uint16_t(v)); +} + +// ----------------------------- U8 ----------------------------------------- +SLANG_FORCE_INLINE uint32_t U8_countbits(uint8_t v) +{ + // No native 8bit __popcnt yet, just cast and use 16bit variant + return U16_countbits(uint16_t(v)); +} + +// ----------------------------- I8 ----------------------------------------- +SLANG_FORCE_INLINE uint32_t I8_countbits(int16_t v) +{ + return U8_countbits(uint8_t(v)); +} + // ----------------------------- U32 ----------------------------------------- SLANG_FORCE_INLINE uint32_t U32_abs(uint32_t f) @@ -730,6 +717,44 @@ SLANG_FORCE_INLINE uint32_t U32_countbits(uint32_t v) #endif } +// ----------------------------- I32 ----------------------------------------- + +SLANG_FORCE_INLINE int32_t I32_abs(int32_t f) +{ + return (f < 0) ? -f : f; +} + +SLANG_FORCE_INLINE int32_t I32_min(int32_t a, int32_t b) +{ + return a < b ? a : b; +} +SLANG_FORCE_INLINE int32_t I32_max(int32_t a, int32_t b) +{ + return a > b ? a : b; +} + +SLANG_FORCE_INLINE float I32_asfloat(int32_t x) +{ + Union32 u; + u.i = x; + return u.f; +} +SLANG_FORCE_INLINE uint32_t I32_asuint(int32_t x) +{ + return uint32_t(x); +} +SLANG_FORCE_INLINE double I32_asdouble(int32_t low, int32_t hi) +{ + Union64 u; + u.u = (uint64_t(hi) << 32) | uint32_t(low); + return u.d; +} + +SLANG_FORCE_INLINE uint32_t I32_countbits(int32_t v) +{ + return U32_countbits(uint32_t(v)); +} + // ----------------------------- U64 ----------------------------------------- SLANG_FORCE_INLINE uint64_t U64_abs(uint64_t f) @@ -749,7 +774,7 @@ SLANG_FORCE_INLINE uint64_t U64_max(uint64_t a, uint64_t b) SLANG_FORCE_INLINE uint32_t U64_countbits(uint64_t v) { #if SLANG_GCC_FAMILY && !defined(SLANG_LLVM) - return uint32_t(__builtin_popcountl(v)); + return uint32_t(__builtin_popcountll(v)); #elif SLANG_PROCESSOR_X86_64 && SLANG_VC return uint32_t(__popcnt64(v)); #else diff --git a/prelude/slang-cuda-prelude.h b/prelude/slang-cuda-prelude.h index 738f2fa16..91ff98a17 100644 --- a/prelude/slang-cuda-prelude.h +++ b/prelude/slang-cuda-prelude.h @@ -1788,44 +1788,34 @@ SLANG_FORCE_INLINE SLANG_CUDA_CALL double F64_fma(double a, double b, double c) return ::fma(a, b, c); } -// ----------------------------- I32 ----------------------------------------- +// ----------------------------- U8 ----------------------------------------- -// Unary -SLANG_FORCE_INLINE SLANG_CUDA_CALL int32_t I32_abs(int32_t f) +SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t U8_countbits(uint8_t v) { - return (f < 0) ? -f : f; + // No native 8bit popc yet, just cast and use 32bit variant + return __popc(uint32_t(v)); } -// Binary -SLANG_FORCE_INLINE SLANG_CUDA_CALL int32_t I32_min(int32_t a, int32_t b) -{ - return a < b ? a : b; -} -SLANG_FORCE_INLINE SLANG_CUDA_CALL int32_t I32_max(int32_t a, int32_t b) -{ - return a > b ? a : b; -} +// ----------------------------- I8 ----------------------------------------- -SLANG_FORCE_INLINE SLANG_CUDA_CALL float I32_asfloat(int32_t x) +SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t I8_countbits(int8_t v) { - Union32 u; - u.i = x; - return u.f; + return U8_countbits(uint8_t(v)); } -SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t I32_asuint(int32_t x) -{ - return uint32_t(x); -} -SLANG_FORCE_INLINE SLANG_CUDA_CALL double I32_asdouble(int32_t low, int32_t hi) + +// ----------------------------- U16 ----------------------------------------- + +SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t U16_countbits(uint16_t v) { - Union64 u; - u.u = (uint64_t(hi) << 32) | uint32_t(low); - return u.d; + // No native 16bit popc yet, just cast and use 32bit variant + return __popc(uint32_t(v)); } -SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t I32_countbits(int32_t v) +// ----------------------------- I16 ----------------------------------------- + +SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t I16_countbits(int16_t v) { - return __popc(uint32_t(v)); + return U16_countbits(uint16_t(v)); } // ----------------------------- U32 ----------------------------------------- @@ -1870,26 +1860,44 @@ SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t U32_countbits(uint32_t v) return __popc(v); } +// ----------------------------- I32 ----------------------------------------- -// ----------------------------- I64 ----------------------------------------- - -SLANG_FORCE_INLINE SLANG_CUDA_CALL int64_t I64_abs(int64_t f) +// Unary +SLANG_FORCE_INLINE SLANG_CUDA_CALL int32_t I32_abs(int32_t f) { return (f < 0) ? -f : f; } -SLANG_FORCE_INLINE SLANG_CUDA_CALL int64_t I64_min(int64_t a, int64_t b) +// Binary +SLANG_FORCE_INLINE SLANG_CUDA_CALL int32_t I32_min(int32_t a, int32_t b) { return a < b ? a : b; } -SLANG_FORCE_INLINE SLANG_CUDA_CALL int64_t I64_max(int64_t a, int64_t b) +SLANG_FORCE_INLINE SLANG_CUDA_CALL int32_t I32_max(int32_t a, int32_t b) { return a > b ? a : b; } -SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t I64_countbits(int64_t v) +SLANG_FORCE_INLINE SLANG_CUDA_CALL float I32_asfloat(int32_t x) +{ + Union32 u; + u.i = x; + return u.f; +} +SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t I32_asuint(int32_t x) +{ + return uint32_t(x); +} +SLANG_FORCE_INLINE SLANG_CUDA_CALL double I32_asdouble(int32_t low, int32_t hi) +{ + Union64 u; + u.u = (uint64_t(hi) << 32) | uint32_t(low); + return u.d; +} + +SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t I32_countbits(int32_t v) { - return __popcll(uint64_t(v)); + return U32_countbits(uint32_t(v)); } // ----------------------------- U64 ----------------------------------------- @@ -1914,6 +1922,27 @@ SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t U64_countbits(uint64_t v) return __popcll(v); } +// ----------------------------- I64 ----------------------------------------- + +SLANG_FORCE_INLINE SLANG_CUDA_CALL int64_t I64_abs(int64_t f) +{ + return (f < 0) ? -f : f; +} + +SLANG_FORCE_INLINE SLANG_CUDA_CALL int64_t I64_min(int64_t a, int64_t b) +{ + return a < b ? a : b; +} +SLANG_FORCE_INLINE SLANG_CUDA_CALL int64_t I64_max(int64_t a, int64_t b) +{ + return a > b ? a : b; +} + +SLANG_FORCE_INLINE SLANG_CUDA_CALL uint32_t I64_countbits(int64_t v) +{ + return U64_countbits(uint64_t(v)); +} + // ----------------------------- IPTR ----------------------------------------- SLANG_FORCE_INLINE SLANG_CUDA_CALL intptr_t IPTR_abs(intptr_t f) |
