Author: Farzon Lotfi
Date: 2026-08-31T15:47:53-04:00
New Revision: af7309d38251ff7ae250429107e7d0b4efa490ee

URL: 
https://github.com/llvm/llvm-project/commit/af7309d38251ff7ae250429107e7d0b4efa490ee
DIFF: 
https://github.com/llvm/llvm-project/commit/af7309d38251ff7ae250429107e7d0b4efa490ee.diff

LOG: [HLSL][LongVec] Add support for select (#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.

Added: 
    

Modified: 
    clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
    clang/lib/Headers/hlsl/hlsl_detail.h
    clang/test/CodeGenHLSL/builtins/select.hlsl

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index 54ff0771bc2ce..772e740c264fd 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,39 +170,24 @@ 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>
-_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>
+template <typename T, int N>
 _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,
+/// \fn vector<T,Sz> select(vector<bool,Sz> Conds, T TrueVals,
 ///                         T FalseVal)
 /// \brief ternary operator for vectors. All vectors must be the same size.
 /// \param Conds The Condition input values.
 /// \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 T, typename U, 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 bc9d23af95c17..922b381eb8d79 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