summaryrefslogtreecommitdiff
path: root/prelude
diff options
context:
space:
mode:
authorsricker-nvidia <115114531+sricker-nvidia@users.noreply.github.com>2025-05-05 15:30:33 -0700
committerGitHub <noreply@github.com>2025-05-05 22:30:33 +0000
commit50d9781b7387b0f7f56d19c72afcf390cca72b72 (patch)
tree7b6f1401f7a8257fa378930a052ca63f0fda91f4 /prelude
parent698e43372cefe0fff13150925aeb7f389c21a938 (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.h97
-rw-r--r--prelude/slang-cuda-prelude.h97
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)