Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 43 additions & 9 deletions clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -2090,9 +2090,17 @@ T select(bool, T, T);
/// \param FalseVals The vector values are chosen from when conditions are
/// false.

template <typename T, int Sz>
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>
_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, Sz> select(vector<bool, Sz>, vector<T, Sz>, vector<T, Sz>);
vector<T, 4> select(vector<bool, 4>, vector<T, 4>, vector<T, 4>);

/// \fn vector<T,Sz> select(vector<bool,Sz> Conds, T TrueVal,
/// vector<T,Sz> FalseVals)
Expand All @@ -2102,9 +2110,17 @@ vector<T, Sz> select(vector<bool, Sz>, vector<T, Sz>, vector<T, Sz>);
/// \param FalseVals The vector values are chosen from when conditions are
/// false.

template <typename T, int Sz>
template <typename T>
_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, Sz> select(vector<bool, Sz>, T, vector<T, Sz>);
vector<T, 4> select(vector<bool, 4>, T, vector<T, 4>);

/// \fn vector<T,Sz> select(vector<bool,Sz> Conds, vector<T,Sz> TrueVals,
/// T FalseVal)
Expand All @@ -2113,9 +2129,17 @@ vector<T, Sz> select(vector<bool, Sz>, T, vector<T, Sz>);
/// \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, int Sz>
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>
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
vector<T, Sz> select(vector<bool, Sz>, vector<T, Sz>, T);
vector<T, 4> select(vector<bool, 4>, vector<T, 4>, T);

/// \fn vector<T,Sz> select(vector<bool,Sz> Conds, vector<T,Sz> TrueVals,
/// T FalseVal)
Expand All @@ -2124,10 +2148,20 @@ vector<T, Sz> select(vector<bool, Sz>, vector<T, Sz>, 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, int Sz>
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, Sz>> select(
vector<bool, Sz>, T, T);
__detail::enable_if_t<__detail::is_arithmetic<T>::Value, vector<T, 4>> select(
vector<bool, 4>, T, T);

//===----------------------------------------------------------------------===//
// sin builtins
Expand Down
64 changes: 49 additions & 15 deletions clang/test/CodeGenHLSL/builtins/select.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,6 @@ struct S test_select_infer_struct(bool cond0, struct S tVal, struct S fVal) {
return select(cond0, tVal, fVal);
}

// CHECK-LABEL: test_select_infer_array
// CHECK: [[TRUE_VAL:%.*]] = load [3 x i32], ptr {{%.*}}, align 4
// CHECK: [[FALSE_VAL:%.*]] = load [3 x i32], ptr {{%.*}}, align 4
// CHECK: [[SELECT:%.*]] = select i1 {{%.*}}, [3 x i32] [[TRUE_VAL]], [3 x i32] [[FALSE_VAL]]
// CHECK: store [3 x i32] [[SELECT]], ptr {{%.*}}, align 4
// CHECK: ret void
int test_select_infer_array(bool cond, int tVal[3], int fVal[3])[3] {
return select(cond, tVal, fVal);
}

// CHECK-LABEL: test_select_bool_vector
// CHECK: [[SELECT:%.*]] = select i1 {{%.*}}, <2 x i32> {{%.*}}, <2 x i32> {{%.*}}
// CHECK: ret <2 x i32> [[SELECT]]
Expand All @@ -38,24 +28,24 @@ int2 test_select_bool_vector(bool cond0, int2 tVal, int2 fVal) {
}

// CHECK-LABEL: test_select_vector_1
// CHECK: [[SELECT:%.*]] = select <1 x i1> {{%.*}}, <1 x i32> {{%.*}}, <1 x i32> {{%.*}}
// CHECK: [[SELECT:%.*]] = select 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<int,1>(cond0, tVals, fVals);
return select(cond0, tVals, fVals);
}

// CHECK-LABEL: test_select_vector_2
// CHECK: [[SELECT:%.*]] = select <2 x i1> {{%.*}}, <2 x i32> {{%.*}}, <2 x i32> {{%.*}}
// CHECK: ret <2 x i32> [[SELECT]]
int2 test_select_vector_2(bool2 cond0, int2 tVals, int2 fVals) {
return select<int,2>(cond0, tVals, fVals);
return select(cond0, tVals, fVals);
}

// CHECK-LABEL: test_select_vector_3
// CHECK: [[SELECT:%.*]] = select <3 x i1> {{%.*}}, <3 x i32> {{%.*}}, <3 x i32> {{%.*}}
// CHECK: ret <3 x i32> [[SELECT]]
int3 test_select_vector_3(bool3 cond0, int3 tVals, int3 fVals) {
return select<int,3>(cond0, tVals, fVals);
return select(cond0, tVals, fVals);
}

// CHECK-LABEL: test_select_vector_4
Expand Down Expand Up @@ -86,10 +76,54 @@ int4 test_select_vector_vector_scalar(bool4 cond0, int4 tVals, int fVal) {
// CHECK-LABEL: test_select_vector_scalar_scalar
// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0
// CHECK: [[SPLAT1:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC1]], <4 x i32> poison, <4 x i32> zeroinitializer
// CHECK: [[SPLAT_SRC2:%.*]] = insertelement <4 x i32> poison, i32 %3, i64 0
// CHECK: [[SPLAT_SRC2:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0
// CHECK: [[SPLAT2:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC2]], <4 x i32> poison, <4 x i32> zeroinitializer
// CHECK: [[SELECT:%.*]] = select <4 x i1> {{%.*}}, <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]]
// CHECK: ret <4 x i32> [[SELECT]]
int4 test_select_vector_scalar_scalar(bool4 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 16
// CHECK: [[TOBOOL:%.*]] = icmp ne <4 x i32> [[TMP0]], zeroinitializer
// CHECK: [[SELECT:%.*]] = select <4 x i1> [[TOBOOL]], <4 x i1> {{%.*}}, <4 x i1> {{%.*}}
// CHECK: ret <4 x i1> [[SELECT]]
bool4 test_select_nonbool_cond_vector_4(int4 cond0, bool4 tVal, bool4 fVal) {
return select(cond0, tVal, fVal);
}

// CHECK-LABEL: test_select_nonbool_cond_vector_scalar_vector
// CHECK: [[TMP0:%.*]] = load <3 x i32>, ptr %cond0.addr, align 16
// CHECK: [[TOBOOL:%.*]] = icmp ne <3 x i32> [[TMP0]], zeroinitializer
// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <3 x i32> poison, i32 {{%.*}}, i64 0
// CHECK: [[SPLAT1:%.*]] = shufflevector <3 x i32> [[SPLAT_SRC1]], <3 x i32> poison, <3 x i32> zeroinitializer
// CHECK: [[SELECT:%.*]] = select <3 x i1> [[TOBOOL]], <3 x i32> [[SPLAT1]], <3 x i32> {{%.*}}
// CHECK: ret <3 x i32> [[SELECT]]
int3 test_select_nonbool_cond_vector_scalar_vector(int3 cond0, int tVal, int3 fVal) {
return select(cond0, tVal, fVal);
}

// CHECK-LABEL: test_select_nonbool_cond_vector_vector_scalar
// CHECK: [[TMP0:%.*]] = load <2 x i32>, ptr %cond0.addr, align 8
// CHECK: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP0]], zeroinitializer
// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <2 x i32> poison, i32 {{%.*}}, i64 0
// CHECK: [[SPLAT1:%.*]] = shufflevector <2 x i32> [[SPLAT_SRC1]], <2 x i32> poison, <2 x i32> zeroinitializer
// CHECK: [[SELECT:%.*]] = select <2 x i1> [[TOBOOL]], <2 x i32> {{%.*}}, <2 x i32> [[SPLAT1]]
// CHECK: ret <2 x i32> [[SELECT]]
int2 test_select_nonbool_cond_vector_vector_scalar(int2 cond0, int2 tVal, int fVal) {
return select(cond0, tVal, fVal);
}

// CHECK-LABEL: test_select_nonbool_cond_vector_scalar_scalar
// CHECK: [[TMP0:%.*]] = load <4 x i32>, ptr %cond0.addr, align 16
// CHECK: [[TOBOOL:%.*]] = icmp ne <4 x i32> [[TMP0]], zeroinitializer
// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0
// CHECK: [[SPLAT1:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC1]], <4 x i32> poison, <4 x i32> zeroinitializer
// CHECK: [[SPLAT_SRC2:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0
// CHECK: [[SPLAT2:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC2]], <4 x i32> poison, <4 x i32> zeroinitializer
// CHECK: [[SELECT:%.*]] = select <4 x i1> [[TOBOOL]], <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]]
// CHECK: ret <4 x i32> [[SELECT]]
int4 test_select_nonbool_cond_vector_scalar_scalar(int4 cond0, int tVal, int fVal) {
return select(cond0, tVal, fVal);
}
2 changes: 1 addition & 1 deletion clang/test/SemaHLSL/BuiltIns/select-errors.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ int2 test_select_vector_vals_not_vecs(bool2 p0, int t0,
}

int1 test_select_vector_vals_wrong_size(bool2 p0, int1 t0, int1 f0) {
return select<int,1>(p0, t0, f0); // expected-warning{{implicit conversion truncates vector: 'bool2' (aka 'vector<bool, 2>') to 'vector<bool, 1>' (vector of 1 'bool' value)}}
return select<int1>(p0, t0, f0); // No diagnostic expected.
}

int test_select_no_args() {
Expand Down