https://github.com/farzonl created 
https://github.com/llvm/llvm-project/pull/219603

resolves #219592

Some of our pure HLSL intrinsics use the select intrinsic. We can't convert 
those intrinsics until select is done first.

Since we need long vectors we can rewrite all the select overloads into a 
single template per argument type.

For scalar/scalar, I replaced vector size overloads with a forwarding template 
that:
- Deduces N from vector<U, N> Conds
- Converts conditions to vector<boo,N>

For Vector Scalar, Scalar Vector, and Vector Vector we needed a type identity 
trait since the first argument is a boolean vector for select. I use it only 
around the condition parameter for overloads where N is already deduced from a 
vector value operand.

>From 9fbd9fc953dbf77b4432ed37dc3bf68435697056 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <[email protected]>
Date: Fri, 28 Aug 2026 19:25:11 -0400
Subject: [PATCH] [HLSL][LongVec] Add support for select

resolves #219592

Some of our pure HLSL intrinsics use the select intrinsic.
We can't convert those intrinsics until select is done first.

Since we need long vectors we can rewrite all the select overloads
into a single template per argument type.

For scalar/scalar, I replaced vector size overloads with a forwarding
template that:
- Deduces N from vector<U, N> Conds
- Converts conditions to vector<boo,N>

For Vector Scalar, Scalar Vector, and Vector Vector we needed a
type identity trait since the first argument is a boolean vector for
select. I use it only around the condition parameter for
overloads where N is already deduced from a vector value operand.
---
 .../lib/Headers/hlsl/hlsl_alias_intrinsics.h  | 59 +++++--------------
 clang/lib/Headers/hlsl/hlsl_detail.h          |  6 ++
 clang/test/CodeGenHLSL/builtins/select.hlsl   | 41 ++++++++++++-
 3 files changed, 61 insertions(+), 45 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index 54ff0771bc2ce..f6bc07cd76f74 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -145,17 +145,10 @@ T select(bool, T, T);
 /// \param FalseVals The vector values are chosen from when conditions are
 /// false.
 
-template <typename T>
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector<T, 2> select(vector<bool, 2>, vector<T, 2>, vector<T, 2>);
-
-template <typename T>
+template <typename T, int N>
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector<T, 3> select(vector<bool, 3>, vector<T, 3>, vector<T, 3>);
-
-template <typename T>
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector<T, 4> select(vector<bool, 4>, vector<T, 4>, vector<T, 4>);
+vector<T, N> select(__detail::type_identity_t<vector<bool, N>>, vector<T, N>,
+                    vector<T, N>);
 
 /// \fn vector<T,Sz> select(vector<bool,Sz> Conds, T TrueVal,
 ///                         vector<T,Sz> FalseVals)
@@ -165,17 +158,10 @@ vector<T, 4> select(vector<bool, 4>, vector<T, 4>, 
vector<T, 4>);
 /// \param FalseVals The vector values are chosen from when conditions are
 /// false.
 
-template <typename T>
+template <typename T, int N>
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector<T, 2> select(vector<bool, 2>, T, vector<T, 2>);
-
-template <typename T>
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector<T, 3> select(vector<bool, 3>, T, vector<T, 3>);
-
-template <typename T>
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector<T, 4> select(vector<bool, 4>, T, vector<T, 4>);
+vector<T, N> select(__detail::type_identity_t<vector<bool, N>>, T,
+                    vector<T, N>);
 
 /// \fn vector<T,Sz> select(vector<bool,Sz> Conds, vector<T,Sz> TrueVals,
 ///                         T FalseVal)
@@ -184,17 +170,10 @@ vector<T, 4> select(vector<bool, 4>, T, vector<T, 4>);
 /// \param TrueVals The vector values are chosen from when conditions are true.
 /// \param FalseVal The scalar value to splat from when conditions are false.
 
-template <typename T>
+template <typename T, int N>
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector<T, 2> select(vector<bool, 2>, vector<T, 2>, T);
-
-template <typename T>
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector<T, 3> select(vector<bool, 3>, vector<T, 3>, T);
-
-template <typename T>
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-vector<T, 4> select(vector<bool, 4>, vector<T, 4>, T);
+vector<T, N> select(__detail::type_identity_t<vector<bool, N>>, vector<T, N>,
+                    T);
 
 /// \fn vector<T,Sz> select(vector<bool,Sz> Conds, vector<T,Sz> TrueVals,
 ///                         T FalseVal)
@@ -203,20 +182,12 @@ vector<T, 4> select(vector<bool, 4>, vector<T, 4>, T);
 /// \param TrueVal The scalar value to splat from when conditions are true.
 /// \param FalseVal The scalar value to splat from when conditions are false.
 
-template <typename T>
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-__detail::enable_if_t<__detail::is_arithmetic<T>::Value, vector<T, 2>> select(
-    vector<bool, 2>, T, T);
-
-template <typename T>
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-__detail::enable_if_t<__detail::is_arithmetic<T>::Value, vector<T, 3>> select(
-    vector<bool, 3>, T, T);
-
-template <typename T>
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
-__detail::enable_if_t<__detail::is_arithmetic<T>::Value, vector<T, 4>> select(
-    vector<bool, 4>, T, T);
+template <typename U, typename T, int N>
+__detail::enable_if_t<(N > 1 && __detail::is_arithmetic<T>::Value),
+                      vector<T, N>>
+select(vector<U, N> Conds, T TrueVal, T FalseVal) {
+  return __builtin_hlsl_select((vector<bool, N>)Conds, TrueVal, FalseVal);
+}
 
 } // namespace hlsl
 #endif //_HLSL_HLSL_ALIAS_INTRINSICS_H_
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h 
b/clang/lib/Headers/hlsl/hlsl_detail.h
index 8ce925bb8fbe4..6261eb09fad74 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -32,6 +32,12 @@ template <typename T> struct enable_if<true, T> {
 template <bool B, class T = void>
 using enable_if_t = typename enable_if<B, T>::Type;
 
+template <typename T> struct type_identity {
+  using Type = T;
+};
+
+template <typename T> using type_identity_t = typename type_identity<T>::Type;
+
 template <typename U, typename T, int R, int C>
 constexpr enable_if_t<sizeof(U) == sizeof(T), matrix<U, R, C>>
 bit_cast(matrix<T, R, C> M) {
diff --git a/clang/test/CodeGenHLSL/builtins/select.hlsl 
b/clang/test/CodeGenHLSL/builtins/select.hlsl
index dd74589af30c6..238beea0d4155 100644
--- a/clang/test/CodeGenHLSL/builtins/select.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/select.hlsl
@@ -28,7 +28,7 @@ int2 test_select_bool_vector(bool cond0, int2 tVal, int2 
fVal) {
 }
 
 // CHECK-LABEL: test_select_vector_1
-// CHECK: [[SELECT:%.*]] = select i1 {{%.*}}, <1 x i32> {{%.*}}, <1 x i32> 
{{%.*}}
+// CHECK: [[SELECT:%.*]] = select <1 x i1> {{%.*}}, <1 x i32> {{%.*}}, <1 x 
i32> {{%.*}}
 // CHECK: ret <1 x i32> [[SELECT]]
 int1 test_select_vector_1(bool1 cond0, int1 tVals, int1 fVals) {
   return select(cond0, tVals, fVals);
@@ -84,6 +84,45 @@ int4 test_select_vector_scalar_scalar(bool4 cond0, int tVal, 
int fVal) {
   return select(cond0, tVal, fVal);
 }
 
+// CHECK-LABEL: test_select_vector_17
+// CHECK: [[SELECT:%.*]] = select <17 x i1> {{%.*}}, <17 x i32> {{%.*}}, <17 x 
i32> {{%.*}}
+// CHECK: ret <17 x i32> [[SELECT]]
+vector<int, 17> test_select_vector_17(vector<bool, 17> cond0,
+                                   vector<int, 17> tVals,
+                                   vector<int, 17> fVals) {
+  return select(cond0, tVals, fVals);
+}
+
+// CHECK-LABEL: test_select_vector_5_scalar_vector
+// CHECK: [[COND:%.*]] = load <5 x i32>, ptr %cond0.addr, align 4
+// CHECK: [[TOBOOL:%.*]] = icmp ne <5 x i32> [[COND]], zeroinitializer
+// CHECK: [[SELECT:%.*]] = select <5 x i1> [[TOBOOL]], <5 x i32> {{%.*}}, <5 x 
i32> {{%.*}}
+// CHECK: ret <5 x i32> [[SELECT]]
+vector<int, 5> test_select_vector_5_scalar_vector(vector<int, 5> cond0,
+                                                 int tVal,
+                                                 vector<int, 5> fVals) {
+  return select(cond0, tVal, fVals);
+}
+
+// CHECK-LABEL: test_select_vector_20_vector_scalar
+// CHECK: [[SELECT:%.*]] = select <20 x i1> {{%.*}}, <20 x i32> {{%.*}}, <20 x 
i32> {{%.*}}
+// CHECK: ret <20 x i32> [[SELECT]]
+vector<int, 20> test_select_vector_20_vector_scalar(vector<bool, 20> cond0,
+                                                 vector<int, 20> tVals,
+                                                 int fVal) {
+  return select(cond0, tVals, fVal);
+}
+
+// CHECK-LABEL: test_select_vector_8_scalar_scalar
+// CHECK: [[COND:%.*]] = load <8 x i32>, ptr %cond0.addr, align 4
+// CHECK: [[TOBOOL:%.*]] = icmp ne <8 x i32> [[COND]], zeroinitializer
+// CHECK: [[SELECT:%.*]] = select <8 x i1> [[TOBOOL]], <8 x i32> {{%.*}}, <8 x 
i32> {{%.*}}
+// CHECK: ret <8 x i32> [[SELECT]]
+vector<int, 8> test_select_vector_8_scalar_scalar(vector<int, 8> cond0,
+                                                 int tVal, int fVal) {
+  return select(cond0, tVal, fVal);
+}
+
 // CHECK-LABEL: test_select_nonbool_cond_vector_4
 // CHECK: [[TMP0:%.*]] = load <4 x i32>, ptr %cond0.addr, align 4
 // CHECK: [[TOBOOL:%.*]] = icmp ne <4 x i32> [[TMP0]], zeroinitializer

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to