Skip to content

Commit 6e2dcdb

Browse files
authored
Fix implicit truncation of select non-bool vector conditions (#166279)
Fixes #164018. The problem is that we're unable to do an implicit conversion sequence on a template deduced argument, so the current vector templates can't reconcile `vector<int, 4>` with `vector<bool, Sz>`. This PR separates the vector templates into size-specific ones, getting rid of the `Sz` deduction and allowing for the implicit conversion to be done.
1 parent 9703bda commit 6e2dcdb

File tree

3 files changed

+93
-25
lines changed

3 files changed

+93
-25
lines changed

clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2111,9 +2111,17 @@ T select(bool, T, T);
21112111
/// \param FalseVals The vector values are chosen from when conditions are
21122112
/// false.
21132113

2114-
template <typename T, int Sz>
2114+
template <typename T>
2115+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2116+
vector<T, 2> select(vector<bool, 2>, vector<T, 2>, vector<T, 2>);
2117+
2118+
template <typename T>
2119+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2120+
vector<T, 3> select(vector<bool, 3>, vector<T, 3>, vector<T, 3>);
2121+
2122+
template <typename T>
21152123
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2116-
vector<T, Sz> select(vector<bool, Sz>, vector<T, Sz>, vector<T, Sz>);
2124+
vector<T, 4> select(vector<bool, 4>, vector<T, 4>, vector<T, 4>);
21172125

21182126
/// \fn vector<T,Sz> select(vector<bool,Sz> Conds, T TrueVal,
21192127
/// vector<T,Sz> FalseVals)
@@ -2123,9 +2131,17 @@ vector<T, Sz> select(vector<bool, Sz>, vector<T, Sz>, vector<T, Sz>);
21232131
/// \param FalseVals The vector values are chosen from when conditions are
21242132
/// false.
21252133

2126-
template <typename T, int Sz>
2134+
template <typename T>
2135+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2136+
vector<T, 2> select(vector<bool, 2>, T, vector<T, 2>);
2137+
2138+
template <typename T>
2139+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2140+
vector<T, 3> select(vector<bool, 3>, T, vector<T, 3>);
2141+
2142+
template <typename T>
21272143
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2128-
vector<T, Sz> select(vector<bool, Sz>, T, vector<T, Sz>);
2144+
vector<T, 4> select(vector<bool, 4>, T, vector<T, 4>);
21292145

21302146
/// \fn vector<T,Sz> select(vector<bool,Sz> Conds, vector<T,Sz> TrueVals,
21312147
/// T FalseVal)
@@ -2134,9 +2150,17 @@ vector<T, Sz> select(vector<bool, Sz>, T, vector<T, Sz>);
21342150
/// \param TrueVals The vector values are chosen from when conditions are true.
21352151
/// \param FalseVal The scalar value to splat from when conditions are false.
21362152

2137-
template <typename T, int Sz>
2153+
template <typename T>
2154+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2155+
vector<T, 2> select(vector<bool, 2>, vector<T, 2>, T);
2156+
2157+
template <typename T>
2158+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2159+
vector<T, 3> select(vector<bool, 3>, vector<T, 3>, T);
2160+
2161+
template <typename T>
21382162
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2139-
vector<T, Sz> select(vector<bool, Sz>, vector<T, Sz>, T);
2163+
vector<T, 4> select(vector<bool, 4>, vector<T, 4>, T);
21402164

21412165
/// \fn vector<T,Sz> select(vector<bool,Sz> Conds, vector<T,Sz> TrueVals,
21422166
/// T FalseVal)
@@ -2145,10 +2169,20 @@ vector<T, Sz> select(vector<bool, Sz>, vector<T, Sz>, T);
21452169
/// \param TrueVal The scalar value to splat from when conditions are true.
21462170
/// \param FalseVal The scalar value to splat from when conditions are false.
21472171

2148-
template <typename T, int Sz>
2172+
template <typename T>
2173+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2174+
__detail::enable_if_t<__detail::is_arithmetic<T>::Value, vector<T, 2>> select(
2175+
vector<bool, 2>, T, T);
2176+
2177+
template <typename T>
2178+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2179+
__detail::enable_if_t<__detail::is_arithmetic<T>::Value, vector<T, 3>> select(
2180+
vector<bool, 3>, T, T);
2181+
2182+
template <typename T>
21492183
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_select)
2150-
__detail::enable_if_t<__detail::is_arithmetic<T>::Value, vector<T, Sz>> select(
2151-
vector<bool, Sz>, T, T);
2184+
__detail::enable_if_t<__detail::is_arithmetic<T>::Value, vector<T, 4>> select(
2185+
vector<bool, 4>, T, T);
21522186

21532187
//===----------------------------------------------------------------------===//
21542188
// sin builtins

clang/test/CodeGenHLSL/builtins/select.hlsl

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,6 @@ struct S test_select_infer_struct(bool cond0, struct S tVal, struct S fVal) {
2020
return select(cond0, tVal, fVal);
2121
}
2222

23-
// CHECK-LABEL: test_select_infer_array
24-
// CHECK: [[TRUE_VAL:%.*]] = load [3 x i32], ptr {{%.*}}, align 4
25-
// CHECK: [[FALSE_VAL:%.*]] = load [3 x i32], ptr {{%.*}}, align 4
26-
// CHECK: [[SELECT:%.*]] = select i1 {{%.*}}, [3 x i32] [[TRUE_VAL]], [3 x i32] [[FALSE_VAL]]
27-
// CHECK: store [3 x i32] [[SELECT]], ptr {{%.*}}, align 4
28-
// CHECK: ret void
29-
int test_select_infer_array(bool cond, int tVal[3], int fVal[3])[3] {
30-
return select(cond, tVal, fVal);
31-
}
32-
3323
// CHECK-LABEL: test_select_bool_vector
3424
// CHECK: [[SELECT:%.*]] = select i1 {{%.*}}, <2 x i32> {{%.*}}, <2 x i32> {{%.*}}
3525
// CHECK: ret <2 x i32> [[SELECT]]
@@ -38,24 +28,24 @@ int2 test_select_bool_vector(bool cond0, int2 tVal, int2 fVal) {
3828
}
3929

4030
// CHECK-LABEL: test_select_vector_1
41-
// CHECK: [[SELECT:%.*]] = select <1 x i1> {{%.*}}, <1 x i32> {{%.*}}, <1 x i32> {{%.*}}
31+
// CHECK: [[SELECT:%.*]] = select i1 {{%.*}}, <1 x i32> {{%.*}}, <1 x i32> {{%.*}}
4232
// CHECK: ret <1 x i32> [[SELECT]]
4333
int1 test_select_vector_1(bool1 cond0, int1 tVals, int1 fVals) {
44-
return select<int,1>(cond0, tVals, fVals);
34+
return select(cond0, tVals, fVals);
4535
}
4636

4737
// CHECK-LABEL: test_select_vector_2
4838
// CHECK: [[SELECT:%.*]] = select <2 x i1> {{%.*}}, <2 x i32> {{%.*}}, <2 x i32> {{%.*}}
4939
// CHECK: ret <2 x i32> [[SELECT]]
5040
int2 test_select_vector_2(bool2 cond0, int2 tVals, int2 fVals) {
51-
return select<int,2>(cond0, tVals, fVals);
41+
return select(cond0, tVals, fVals);
5242
}
5343

5444
// CHECK-LABEL: test_select_vector_3
5545
// CHECK: [[SELECT:%.*]] = select <3 x i1> {{%.*}}, <3 x i32> {{%.*}}, <3 x i32> {{%.*}}
5646
// CHECK: ret <3 x i32> [[SELECT]]
5747
int3 test_select_vector_3(bool3 cond0, int3 tVals, int3 fVals) {
58-
return select<int,3>(cond0, tVals, fVals);
48+
return select(cond0, tVals, fVals);
5949
}
6050

6151
// CHECK-LABEL: test_select_vector_4
@@ -86,10 +76,54 @@ int4 test_select_vector_vector_scalar(bool4 cond0, int4 tVals, int fVal) {
8676
// CHECK-LABEL: test_select_vector_scalar_scalar
8777
// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0
8878
// CHECK: [[SPLAT1:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC1]], <4 x i32> poison, <4 x i32> zeroinitializer
89-
// CHECK: [[SPLAT_SRC2:%.*]] = insertelement <4 x i32> poison, i32 %3, i64 0
79+
// CHECK: [[SPLAT_SRC2:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0
9080
// CHECK: [[SPLAT2:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC2]], <4 x i32> poison, <4 x i32> zeroinitializer
9181
// CHECK: [[SELECT:%.*]] = select <4 x i1> {{%.*}}, <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]]
9282
// CHECK: ret <4 x i32> [[SELECT]]
9383
int4 test_select_vector_scalar_scalar(bool4 cond0, int tVal, int fVal) {
9484
return select(cond0, tVal, fVal);
9585
}
86+
87+
// CHECK-LABEL: test_select_nonbool_cond_vector_4
88+
// CHECK: [[TMP0:%.*]] = load <4 x i32>, ptr %cond0.addr, align 16
89+
// CHECK: [[TOBOOL:%.*]] = icmp ne <4 x i32> [[TMP0]], zeroinitializer
90+
// CHECK: [[SELECT:%.*]] = select <4 x i1> [[TOBOOL]], <4 x i1> {{%.*}}, <4 x i1> {{%.*}}
91+
// CHECK: ret <4 x i1> [[SELECT]]
92+
bool4 test_select_nonbool_cond_vector_4(int4 cond0, bool4 tVal, bool4 fVal) {
93+
return select(cond0, tVal, fVal);
94+
}
95+
96+
// CHECK-LABEL: test_select_nonbool_cond_vector_scalar_vector
97+
// CHECK: [[TMP0:%.*]] = load <3 x i32>, ptr %cond0.addr, align 16
98+
// CHECK: [[TOBOOL:%.*]] = icmp ne <3 x i32> [[TMP0]], zeroinitializer
99+
// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <3 x i32> poison, i32 {{%.*}}, i64 0
100+
// CHECK: [[SPLAT1:%.*]] = shufflevector <3 x i32> [[SPLAT_SRC1]], <3 x i32> poison, <3 x i32> zeroinitializer
101+
// CHECK: [[SELECT:%.*]] = select <3 x i1> [[TOBOOL]], <3 x i32> [[SPLAT1]], <3 x i32> {{%.*}}
102+
// CHECK: ret <3 x i32> [[SELECT]]
103+
int3 test_select_nonbool_cond_vector_scalar_vector(int3 cond0, int tVal, int3 fVal) {
104+
return select(cond0, tVal, fVal);
105+
}
106+
107+
// CHECK-LABEL: test_select_nonbool_cond_vector_vector_scalar
108+
// CHECK: [[TMP0:%.*]] = load <2 x i32>, ptr %cond0.addr, align 8
109+
// CHECK: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP0]], zeroinitializer
110+
// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <2 x i32> poison, i32 {{%.*}}, i64 0
111+
// CHECK: [[SPLAT1:%.*]] = shufflevector <2 x i32> [[SPLAT_SRC1]], <2 x i32> poison, <2 x i32> zeroinitializer
112+
// CHECK: [[SELECT:%.*]] = select <2 x i1> [[TOBOOL]], <2 x i32> {{%.*}}, <2 x i32> [[SPLAT1]]
113+
// CHECK: ret <2 x i32> [[SELECT]]
114+
int2 test_select_nonbool_cond_vector_vector_scalar(int2 cond0, int2 tVal, int fVal) {
115+
return select(cond0, tVal, fVal);
116+
}
117+
118+
// CHECK-LABEL: test_select_nonbool_cond_vector_scalar_scalar
119+
// CHECK: [[TMP0:%.*]] = load <4 x i32>, ptr %cond0.addr, align 16
120+
// CHECK: [[TOBOOL:%.*]] = icmp ne <4 x i32> [[TMP0]], zeroinitializer
121+
// CHECK: [[SPLAT_SRC1:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0
122+
// CHECK: [[SPLAT1:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC1]], <4 x i32> poison, <4 x i32> zeroinitializer
123+
// CHECK: [[SPLAT_SRC2:%.*]] = insertelement <4 x i32> poison, i32 {{%.*}}, i64 0
124+
// CHECK: [[SPLAT2:%.*]] = shufflevector <4 x i32> [[SPLAT_SRC2]], <4 x i32> poison, <4 x i32> zeroinitializer
125+
// CHECK: [[SELECT:%.*]] = select <4 x i1> [[TOBOOL]], <4 x i32> [[SPLAT1]], <4 x i32> [[SPLAT2]]
126+
// CHECK: ret <4 x i32> [[SELECT]]
127+
int4 test_select_nonbool_cond_vector_scalar_scalar(int4 cond0, int tVal, int fVal) {
128+
return select(cond0, tVal, fVal);
129+
}

clang/test/SemaHLSL/BuiltIns/select-errors.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ int2 test_select_vector_vals_not_vecs(bool2 p0, int t0,
1515
}
1616

1717
int1 test_select_vector_vals_wrong_size(bool2 p0, int1 t0, int1 f0) {
18-
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)}}
18+
return select<int1>(p0, t0, f0); // No diagnostic expected.
1919
}
2020

2121
int test_select_no_args() {

0 commit comments

Comments
 (0)