blob: bc3dda8cbac9471caf5b089b05305bb78c842970 [file] [log] [blame]
Ben Clayton27aa57c2022-02-22 23:13:39 +00001// Copyright 2022 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "src/tint/transform/builtin_polyfill.h"
16
17#include <utility>
18
19#include "src/tint/transform/test_helper.h"
20
dan sinclairb5599d32022-04-07 16:55:14 +000021namespace tint::transform {
Ben Clayton27aa57c2022-02-22 23:13:39 +000022namespace {
23
Ben Claytond868e862022-02-23 21:18:09 +000024using Level = BuiltinPolyfill::Level;
25
Ben Clayton27aa57c2022-02-22 23:13:39 +000026using BuiltinPolyfillTest = TransformTest;
27
28TEST_F(BuiltinPolyfillTest, ShouldRunEmptyModule) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000029 auto* src = R"()";
Ben Clayton27aa57c2022-02-22 23:13:39 +000030
dan sinclair41e4d9a2022-05-01 14:40:55 +000031 EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
Ben Clayton27aa57c2022-02-22 23:13:39 +000032}
33
34TEST_F(BuiltinPolyfillTest, EmptyModule) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000035 auto* src = R"()";
Ben Clayton27aa57c2022-02-22 23:13:39 +000036
dan sinclair41e4d9a2022-05-01 14:40:55 +000037 auto* expect = src;
Ben Clayton27aa57c2022-02-22 23:13:39 +000038
dan sinclair41e4d9a2022-05-01 14:40:55 +000039 auto got = Run<BuiltinPolyfill>(src);
Ben Clayton27aa57c2022-02-22 23:13:39 +000040
dan sinclair41e4d9a2022-05-01 14:40:55 +000041 EXPECT_EQ(expect, str(got));
Ben Clayton27aa57c2022-02-22 23:13:39 +000042}
43
44////////////////////////////////////////////////////////////////////////////////
45// countLeadingZeros
46////////////////////////////////////////////////////////////////////////////////
47DataMap polyfillCountLeadingZeros() {
dan sinclair41e4d9a2022-05-01 14:40:55 +000048 BuiltinPolyfill::Builtins builtins;
49 builtins.count_leading_zeros = true;
50 DataMap data;
51 data.Add<BuiltinPolyfill::Config>(builtins);
52 return data;
Ben Clayton27aa57c2022-02-22 23:13:39 +000053}
54
55TEST_F(BuiltinPolyfillTest, ShouldRunCountLeadingZeros) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000056 auto* src = R"(
Ben Clayton27aa57c2022-02-22 23:13:39 +000057fn f() {
58 countLeadingZeros(0xf);
59}
60)";
61
dan sinclair41e4d9a2022-05-01 14:40:55 +000062 EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
63 EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillCountLeadingZeros()));
Ben Clayton27aa57c2022-02-22 23:13:39 +000064}
65
66TEST_F(BuiltinPolyfillTest, CountLeadingZeros_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000067 auto* src = R"(
Ben Clayton27aa57c2022-02-22 23:13:39 +000068fn f() {
69 let r : i32 = countLeadingZeros(15);
70}
71)";
72
dan sinclair41e4d9a2022-05-01 14:40:55 +000073 auto* expect = R"(
Ben Clayton27aa57c2022-02-22 23:13:39 +000074fn tint_count_leading_zeros(v : i32) -> i32 {
75 var x = u32(v);
76 let b16 = select(0u, 16u, (x <= 65535u));
77 x = (x << b16);
78 let b8 = select(0u, 8u, (x <= 16777215u));
79 x = (x << b8);
80 let b4 = select(0u, 4u, (x <= 268435455u));
81 x = (x << b4);
82 let b2 = select(0u, 2u, (x <= 1073741823u));
83 x = (x << b2);
84 let b1 = select(0u, 1u, (x <= 2147483647u));
85 let is_zero = select(0u, 1u, (x == 0u));
86 return i32((((((b16 | b8) | b4) | b2) | b1) + is_zero));
87}
88
89fn f() {
90 let r : i32 = tint_count_leading_zeros(15);
91}
92)";
93
dan sinclair41e4d9a2022-05-01 14:40:55 +000094 auto got = Run<BuiltinPolyfill>(src, polyfillCountLeadingZeros());
Ben Clayton27aa57c2022-02-22 23:13:39 +000095
dan sinclair41e4d9a2022-05-01 14:40:55 +000096 EXPECT_EQ(expect, str(got));
Ben Clayton27aa57c2022-02-22 23:13:39 +000097}
98
99TEST_F(BuiltinPolyfillTest, CountLeadingZeros_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000100 auto* src = R"(
Ben Clayton27aa57c2022-02-22 23:13:39 +0000101fn f() {
102 let r : u32 = countLeadingZeros(15u);
103}
104)";
105
dan sinclair41e4d9a2022-05-01 14:40:55 +0000106 auto* expect = R"(
Ben Clayton27aa57c2022-02-22 23:13:39 +0000107fn tint_count_leading_zeros(v : u32) -> u32 {
108 var x = u32(v);
109 let b16 = select(0u, 16u, (x <= 65535u));
110 x = (x << b16);
111 let b8 = select(0u, 8u, (x <= 16777215u));
112 x = (x << b8);
113 let b4 = select(0u, 4u, (x <= 268435455u));
114 x = (x << b4);
115 let b2 = select(0u, 2u, (x <= 1073741823u));
116 x = (x << b2);
117 let b1 = select(0u, 1u, (x <= 2147483647u));
118 let is_zero = select(0u, 1u, (x == 0u));
119 return u32((((((b16 | b8) | b4) | b2) | b1) + is_zero));
120}
121
122fn f() {
123 let r : u32 = tint_count_leading_zeros(15u);
124}
125)";
126
dan sinclair41e4d9a2022-05-01 14:40:55 +0000127 auto got = Run<BuiltinPolyfill>(src, polyfillCountLeadingZeros());
Ben Clayton27aa57c2022-02-22 23:13:39 +0000128
dan sinclair41e4d9a2022-05-01 14:40:55 +0000129 EXPECT_EQ(expect, str(got));
Ben Clayton27aa57c2022-02-22 23:13:39 +0000130}
131
132TEST_F(BuiltinPolyfillTest, CountLeadingZeros_vec3_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000133 auto* src = R"(
Ben Clayton27aa57c2022-02-22 23:13:39 +0000134fn f() {
135 let r : vec3<i32> = countLeadingZeros(vec3<i32>(15));
136}
137)";
138
dan sinclair41e4d9a2022-05-01 14:40:55 +0000139 auto* expect = R"(
Ben Clayton27aa57c2022-02-22 23:13:39 +0000140fn tint_count_leading_zeros(v : vec3<i32>) -> vec3<i32> {
141 var x = vec3<u32>(v);
142 let b16 = select(vec3<u32>(0u), vec3<u32>(16u), (x <= vec3<u32>(65535u)));
143 x = (x << b16);
144 let b8 = select(vec3<u32>(0u), vec3<u32>(8u), (x <= vec3<u32>(16777215u)));
145 x = (x << b8);
146 let b4 = select(vec3<u32>(0u), vec3<u32>(4u), (x <= vec3<u32>(268435455u)));
147 x = (x << b4);
148 let b2 = select(vec3<u32>(0u), vec3<u32>(2u), (x <= vec3<u32>(1073741823u)));
149 x = (x << b2);
150 let b1 = select(vec3<u32>(0u), vec3<u32>(1u), (x <= vec3<u32>(2147483647u)));
151 let is_zero = select(vec3<u32>(0u), vec3<u32>(1u), (x == vec3<u32>(0u)));
152 return vec3<i32>((((((b16 | b8) | b4) | b2) | b1) + is_zero));
153}
154
155fn f() {
156 let r : vec3<i32> = tint_count_leading_zeros(vec3<i32>(15));
157}
158)";
159
dan sinclair41e4d9a2022-05-01 14:40:55 +0000160 auto got = Run<BuiltinPolyfill>(src, polyfillCountLeadingZeros());
Ben Clayton27aa57c2022-02-22 23:13:39 +0000161
dan sinclair41e4d9a2022-05-01 14:40:55 +0000162 EXPECT_EQ(expect, str(got));
Ben Clayton27aa57c2022-02-22 23:13:39 +0000163}
164
165TEST_F(BuiltinPolyfillTest, CountLeadingZeros_vec3_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000166 auto* src = R"(
Ben Clayton27aa57c2022-02-22 23:13:39 +0000167fn f() {
168 let r : vec3<u32> = countLeadingZeros(vec3<u32>(15u));
169}
170)";
171
dan sinclair41e4d9a2022-05-01 14:40:55 +0000172 auto* expect = R"(
Ben Clayton27aa57c2022-02-22 23:13:39 +0000173fn tint_count_leading_zeros(v : vec3<u32>) -> vec3<u32> {
174 var x = vec3<u32>(v);
175 let b16 = select(vec3<u32>(0u), vec3<u32>(16u), (x <= vec3<u32>(65535u)));
176 x = (x << b16);
177 let b8 = select(vec3<u32>(0u), vec3<u32>(8u), (x <= vec3<u32>(16777215u)));
178 x = (x << b8);
179 let b4 = select(vec3<u32>(0u), vec3<u32>(4u), (x <= vec3<u32>(268435455u)));
180 x = (x << b4);
181 let b2 = select(vec3<u32>(0u), vec3<u32>(2u), (x <= vec3<u32>(1073741823u)));
182 x = (x << b2);
183 let b1 = select(vec3<u32>(0u), vec3<u32>(1u), (x <= vec3<u32>(2147483647u)));
184 let is_zero = select(vec3<u32>(0u), vec3<u32>(1u), (x == vec3<u32>(0u)));
185 return vec3<u32>((((((b16 | b8) | b4) | b2) | b1) + is_zero));
186}
187
188fn f() {
189 let r : vec3<u32> = tint_count_leading_zeros(vec3<u32>(15u));
190}
191)";
192
dan sinclair41e4d9a2022-05-01 14:40:55 +0000193 auto got = Run<BuiltinPolyfill>(src, polyfillCountLeadingZeros());
Ben Clayton27aa57c2022-02-22 23:13:39 +0000194
dan sinclair41e4d9a2022-05-01 14:40:55 +0000195 EXPECT_EQ(expect, str(got));
Ben Clayton27aa57c2022-02-22 23:13:39 +0000196}
197
Ben Claytonf8672d82022-02-22 23:16:39 +0000198////////////////////////////////////////////////////////////////////////////////
199// countTrailingZeros
200////////////////////////////////////////////////////////////////////////////////
201DataMap polyfillCountTrailingZeros() {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000202 BuiltinPolyfill::Builtins builtins;
203 builtins.count_trailing_zeros = true;
204 DataMap data;
205 data.Add<BuiltinPolyfill::Config>(builtins);
206 return data;
Ben Claytonf8672d82022-02-22 23:16:39 +0000207}
208
209TEST_F(BuiltinPolyfillTest, ShouldRunCountTrailingZeros) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000210 auto* src = R"(
Ben Claytonf8672d82022-02-22 23:16:39 +0000211fn f() {
212 countTrailingZeros(0xf);
213}
214)";
215
dan sinclair41e4d9a2022-05-01 14:40:55 +0000216 EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
217 EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillCountTrailingZeros()));
Ben Claytonf8672d82022-02-22 23:16:39 +0000218}
219
220TEST_F(BuiltinPolyfillTest, CountTrailingZeros_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000221 auto* src = R"(
Ben Claytonf8672d82022-02-22 23:16:39 +0000222fn f() {
223 let r : i32 = countTrailingZeros(15);
224}
225)";
226
dan sinclair41e4d9a2022-05-01 14:40:55 +0000227 auto* expect = R"(
Ben Claytonf8672d82022-02-22 23:16:39 +0000228fn tint_count_trailing_zeros(v : i32) -> i32 {
229 var x = u32(v);
230 let b16 = select(16u, 0u, bool((x & 65535u)));
231 x = (x >> b16);
232 let b8 = select(8u, 0u, bool((x & 255u)));
233 x = (x >> b8);
234 let b4 = select(4u, 0u, bool((x & 15u)));
235 x = (x >> b4);
236 let b2 = select(2u, 0u, bool((x & 3u)));
237 x = (x >> b2);
238 let b1 = select(1u, 0u, bool((x & 1u)));
239 let is_zero = select(0u, 1u, (x == 0u));
240 return i32((((((b16 | b8) | b4) | b2) | b1) + is_zero));
241}
242
243fn f() {
244 let r : i32 = tint_count_trailing_zeros(15);
245}
246)";
247
dan sinclair41e4d9a2022-05-01 14:40:55 +0000248 auto got = Run<BuiltinPolyfill>(src, polyfillCountTrailingZeros());
Ben Claytonf8672d82022-02-22 23:16:39 +0000249
dan sinclair41e4d9a2022-05-01 14:40:55 +0000250 EXPECT_EQ(expect, str(got));
Ben Claytonf8672d82022-02-22 23:16:39 +0000251}
252
253TEST_F(BuiltinPolyfillTest, CountTrailingZeros_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000254 auto* src = R"(
Ben Claytonf8672d82022-02-22 23:16:39 +0000255fn f() {
256 let r : u32 = countTrailingZeros(15u);
257}
258)";
259
dan sinclair41e4d9a2022-05-01 14:40:55 +0000260 auto* expect = R"(
Ben Claytonf8672d82022-02-22 23:16:39 +0000261fn tint_count_trailing_zeros(v : u32) -> u32 {
262 var x = u32(v);
263 let b16 = select(16u, 0u, bool((x & 65535u)));
264 x = (x >> b16);
265 let b8 = select(8u, 0u, bool((x & 255u)));
266 x = (x >> b8);
267 let b4 = select(4u, 0u, bool((x & 15u)));
268 x = (x >> b4);
269 let b2 = select(2u, 0u, bool((x & 3u)));
270 x = (x >> b2);
271 let b1 = select(1u, 0u, bool((x & 1u)));
272 let is_zero = select(0u, 1u, (x == 0u));
273 return u32((((((b16 | b8) | b4) | b2) | b1) + is_zero));
274}
275
276fn f() {
277 let r : u32 = tint_count_trailing_zeros(15u);
278}
279)";
280
dan sinclair41e4d9a2022-05-01 14:40:55 +0000281 auto got = Run<BuiltinPolyfill>(src, polyfillCountTrailingZeros());
Ben Claytonf8672d82022-02-22 23:16:39 +0000282
dan sinclair41e4d9a2022-05-01 14:40:55 +0000283 EXPECT_EQ(expect, str(got));
Ben Claytonf8672d82022-02-22 23:16:39 +0000284}
285
286TEST_F(BuiltinPolyfillTest, CountTrailingZeros_vec3_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000287 auto* src = R"(
Ben Claytonf8672d82022-02-22 23:16:39 +0000288fn f() {
289 let r : vec3<i32> = countTrailingZeros(vec3<i32>(15));
290}
291)";
292
dan sinclair41e4d9a2022-05-01 14:40:55 +0000293 auto* expect = R"(
Ben Claytonf8672d82022-02-22 23:16:39 +0000294fn tint_count_trailing_zeros(v : vec3<i32>) -> vec3<i32> {
295 var x = vec3<u32>(v);
296 let b16 = select(vec3<u32>(16u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(65535u))));
297 x = (x >> b16);
298 let b8 = select(vec3<u32>(8u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(255u))));
299 x = (x >> b8);
300 let b4 = select(vec3<u32>(4u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(15u))));
301 x = (x >> b4);
302 let b2 = select(vec3<u32>(2u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(3u))));
303 x = (x >> b2);
304 let b1 = select(vec3<u32>(1u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(1u))));
305 let is_zero = select(vec3<u32>(0u), vec3<u32>(1u), (x == vec3<u32>(0u)));
306 return vec3<i32>((((((b16 | b8) | b4) | b2) | b1) + is_zero));
307}
308
309fn f() {
310 let r : vec3<i32> = tint_count_trailing_zeros(vec3<i32>(15));
311}
312)";
313
dan sinclair41e4d9a2022-05-01 14:40:55 +0000314 auto got = Run<BuiltinPolyfill>(src, polyfillCountTrailingZeros());
Ben Claytonf8672d82022-02-22 23:16:39 +0000315
dan sinclair41e4d9a2022-05-01 14:40:55 +0000316 EXPECT_EQ(expect, str(got));
Ben Claytonf8672d82022-02-22 23:16:39 +0000317}
318
319TEST_F(BuiltinPolyfillTest, CountTrailingZeros_vec3_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000320 auto* src = R"(
Ben Claytonf8672d82022-02-22 23:16:39 +0000321fn f() {
322 let r : vec3<u32> = countTrailingZeros(vec3<u32>(15u));
323}
324)";
325
dan sinclair41e4d9a2022-05-01 14:40:55 +0000326 auto* expect = R"(
Ben Claytonf8672d82022-02-22 23:16:39 +0000327fn tint_count_trailing_zeros(v : vec3<u32>) -> vec3<u32> {
328 var x = vec3<u32>(v);
329 let b16 = select(vec3<u32>(16u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(65535u))));
330 x = (x >> b16);
331 let b8 = select(vec3<u32>(8u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(255u))));
332 x = (x >> b8);
333 let b4 = select(vec3<u32>(4u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(15u))));
334 x = (x >> b4);
335 let b2 = select(vec3<u32>(2u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(3u))));
336 x = (x >> b2);
337 let b1 = select(vec3<u32>(1u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(1u))));
338 let is_zero = select(vec3<u32>(0u), vec3<u32>(1u), (x == vec3<u32>(0u)));
339 return vec3<u32>((((((b16 | b8) | b4) | b2) | b1) + is_zero));
340}
341
342fn f() {
343 let r : vec3<u32> = tint_count_trailing_zeros(vec3<u32>(15u));
344}
345)";
346
dan sinclair41e4d9a2022-05-01 14:40:55 +0000347 auto got = Run<BuiltinPolyfill>(src, polyfillCountTrailingZeros());
Ben Claytonf8672d82022-02-22 23:16:39 +0000348
dan sinclair41e4d9a2022-05-01 14:40:55 +0000349 EXPECT_EQ(expect, str(got));
Ben Claytonf8672d82022-02-22 23:16:39 +0000350}
351
Ben Claytondf3630c2022-02-23 14:32:14 +0000352////////////////////////////////////////////////////////////////////////////////
Ben Claytond868e862022-02-23 21:18:09 +0000353// extractBits
354////////////////////////////////////////////////////////////////////////////////
355DataMap polyfillExtractBits(Level level) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000356 BuiltinPolyfill::Builtins builtins;
357 builtins.extract_bits = level;
358 DataMap data;
359 data.Add<BuiltinPolyfill::Config>(builtins);
360 return data;
Ben Claytond868e862022-02-23 21:18:09 +0000361}
362
363TEST_F(BuiltinPolyfillTest, ShouldRunExtractBits) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000364 auto* src = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000365fn f() {
366 extractBits(1234, 5u, 6u);
367}
368)";
369
dan sinclair41e4d9a2022-05-01 14:40:55 +0000370 EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
371 EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src, polyfillExtractBits(Level::kNone)));
372 EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillExtractBits(Level::kClampParameters)));
373 EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillExtractBits(Level::kFull)));
Ben Claytond868e862022-02-23 21:18:09 +0000374}
375
376TEST_F(BuiltinPolyfillTest, ExtractBits_Full_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000377 auto* src = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000378fn f() {
379 let r : i32 = extractBits(1234, 5u, 6u);
380}
381)";
382
dan sinclair41e4d9a2022-05-01 14:40:55 +0000383 auto* expect = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000384fn tint_extract_bits(v : i32, offset : u32, count : u32) -> i32 {
385 let s = min(offset, 32u);
386 let e = min(32u, (s + count));
387 let shl = (32u - e);
388 let shr = (shl + s);
389 return ((v << shl) >> shr);
390}
391
392fn f() {
393 let r : i32 = tint_extract_bits(1234, 5u, 6u);
394}
395)";
396
dan sinclair41e4d9a2022-05-01 14:40:55 +0000397 auto got = Run<BuiltinPolyfill>(src, polyfillExtractBits(Level::kFull));
Ben Claytond868e862022-02-23 21:18:09 +0000398
dan sinclair41e4d9a2022-05-01 14:40:55 +0000399 EXPECT_EQ(expect, str(got));
Ben Claytond868e862022-02-23 21:18:09 +0000400}
401
402TEST_F(BuiltinPolyfillTest, ExtractBits_Full_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000403 auto* src = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000404fn f() {
405 let r : u32 = extractBits(1234u, 5u, 6u);
406}
407)";
408
dan sinclair41e4d9a2022-05-01 14:40:55 +0000409 auto* expect = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000410fn tint_extract_bits(v : u32, offset : u32, count : u32) -> u32 {
411 let s = min(offset, 32u);
412 let e = min(32u, (s + count));
413 let shl = (32u - e);
414 let shr = (shl + s);
415 return ((v << shl) >> shr);
416}
417
418fn f() {
419 let r : u32 = tint_extract_bits(1234u, 5u, 6u);
420}
421)";
422
dan sinclair41e4d9a2022-05-01 14:40:55 +0000423 auto got = Run<BuiltinPolyfill>(src, polyfillExtractBits(Level::kFull));
Ben Claytond868e862022-02-23 21:18:09 +0000424
dan sinclair41e4d9a2022-05-01 14:40:55 +0000425 EXPECT_EQ(expect, str(got));
Ben Claytond868e862022-02-23 21:18:09 +0000426}
427
428TEST_F(BuiltinPolyfillTest, ExtractBits_Full_vec3_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000429 auto* src = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000430fn f() {
431 let r : vec3<i32> = extractBits(vec3<i32>(1234), 5u, 6u);
432}
433)";
434
dan sinclair41e4d9a2022-05-01 14:40:55 +0000435 auto* expect = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000436fn tint_extract_bits(v : vec3<i32>, offset : u32, count : u32) -> vec3<i32> {
437 let s = min(offset, 32u);
438 let e = min(32u, (s + count));
439 let shl = (32u - e);
440 let shr = (shl + s);
441 return ((v << vec3<u32>(shl)) >> vec3<u32>(shr));
442}
443
444fn f() {
445 let r : vec3<i32> = tint_extract_bits(vec3<i32>(1234), 5u, 6u);
446}
447)";
448
dan sinclair41e4d9a2022-05-01 14:40:55 +0000449 auto got = Run<BuiltinPolyfill>(src, polyfillExtractBits(Level::kFull));
Ben Claytond868e862022-02-23 21:18:09 +0000450
dan sinclair41e4d9a2022-05-01 14:40:55 +0000451 EXPECT_EQ(expect, str(got));
Ben Claytond868e862022-02-23 21:18:09 +0000452}
453
454TEST_F(BuiltinPolyfillTest, ExtractBits_Full_vec3_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000455 auto* src = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000456fn f() {
457 let r : vec3<u32> = extractBits(vec3<u32>(1234u), 5u, 6u);
458}
459)";
460
dan sinclair41e4d9a2022-05-01 14:40:55 +0000461 auto* expect = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000462fn tint_extract_bits(v : vec3<u32>, offset : u32, count : u32) -> vec3<u32> {
463 let s = min(offset, 32u);
464 let e = min(32u, (s + count));
465 let shl = (32u - e);
466 let shr = (shl + s);
467 return ((v << vec3<u32>(shl)) >> vec3<u32>(shr));
468}
469
470fn f() {
471 let r : vec3<u32> = tint_extract_bits(vec3<u32>(1234u), 5u, 6u);
472}
473)";
474
dan sinclair41e4d9a2022-05-01 14:40:55 +0000475 auto got = Run<BuiltinPolyfill>(src, polyfillExtractBits(Level::kFull));
Ben Claytond868e862022-02-23 21:18:09 +0000476
dan sinclair41e4d9a2022-05-01 14:40:55 +0000477 EXPECT_EQ(expect, str(got));
Ben Claytond868e862022-02-23 21:18:09 +0000478}
479
480TEST_F(BuiltinPolyfillTest, ExtractBits_Clamp_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000481 auto* src = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000482fn f() {
483 let r : i32 = extractBits(1234, 5u, 6u);
484}
485)";
486
dan sinclair41e4d9a2022-05-01 14:40:55 +0000487 auto* expect = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000488fn tint_extract_bits(v : i32, offset : u32, count : u32) -> i32 {
489 let s = min(offset, 32u);
490 let e = min(32u, (s + count));
491 return extractBits(v, s, (e - s));
492}
493
494fn f() {
495 let r : i32 = tint_extract_bits(1234, 5u, 6u);
496}
497)";
498
dan sinclair41e4d9a2022-05-01 14:40:55 +0000499 auto got = Run<BuiltinPolyfill>(src, polyfillExtractBits(Level::kClampParameters));
Ben Claytond868e862022-02-23 21:18:09 +0000500
dan sinclair41e4d9a2022-05-01 14:40:55 +0000501 EXPECT_EQ(expect, str(got));
Ben Claytond868e862022-02-23 21:18:09 +0000502}
503
504TEST_F(BuiltinPolyfillTest, ExtractBits_Clamp_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000505 auto* src = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000506fn f() {
507 let r : u32 = extractBits(1234u, 5u, 6u);
508}
509)";
510
dan sinclair41e4d9a2022-05-01 14:40:55 +0000511 auto* expect = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000512fn tint_extract_bits(v : u32, offset : u32, count : u32) -> u32 {
513 let s = min(offset, 32u);
514 let e = min(32u, (s + count));
515 return extractBits(v, s, (e - s));
516}
517
518fn f() {
519 let r : u32 = tint_extract_bits(1234u, 5u, 6u);
520}
521)";
522
dan sinclair41e4d9a2022-05-01 14:40:55 +0000523 auto got = Run<BuiltinPolyfill>(src, polyfillExtractBits(Level::kClampParameters));
Ben Claytond868e862022-02-23 21:18:09 +0000524
dan sinclair41e4d9a2022-05-01 14:40:55 +0000525 EXPECT_EQ(expect, str(got));
Ben Claytond868e862022-02-23 21:18:09 +0000526}
527
528TEST_F(BuiltinPolyfillTest, ExtractBits_Clamp_vec3_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000529 auto* src = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000530fn f() {
531 let r : vec3<i32> = extractBits(vec3<i32>(1234), 5u, 6u);
532}
533)";
534
dan sinclair41e4d9a2022-05-01 14:40:55 +0000535 auto* expect = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000536fn tint_extract_bits(v : vec3<i32>, offset : u32, count : u32) -> vec3<i32> {
537 let s = min(offset, 32u);
538 let e = min(32u, (s + count));
539 return extractBits(v, s, (e - s));
540}
541
542fn f() {
543 let r : vec3<i32> = tint_extract_bits(vec3<i32>(1234), 5u, 6u);
544}
545)";
546
dan sinclair41e4d9a2022-05-01 14:40:55 +0000547 auto got = Run<BuiltinPolyfill>(src, polyfillExtractBits(Level::kClampParameters));
Ben Claytond868e862022-02-23 21:18:09 +0000548
dan sinclair41e4d9a2022-05-01 14:40:55 +0000549 EXPECT_EQ(expect, str(got));
Ben Claytond868e862022-02-23 21:18:09 +0000550}
551
552TEST_F(BuiltinPolyfillTest, ExtractBits_Clamp_vec3_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000553 auto* src = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000554fn f() {
555 let r : vec3<u32> = extractBits(vec3<u32>(1234u), 5u, 6u);
556}
557)";
558
dan sinclair41e4d9a2022-05-01 14:40:55 +0000559 auto* expect = R"(
Ben Claytond868e862022-02-23 21:18:09 +0000560fn tint_extract_bits(v : vec3<u32>, offset : u32, count : u32) -> vec3<u32> {
561 let s = min(offset, 32u);
562 let e = min(32u, (s + count));
563 return extractBits(v, s, (e - s));
564}
565
566fn f() {
567 let r : vec3<u32> = tint_extract_bits(vec3<u32>(1234u), 5u, 6u);
568}
569)";
570
dan sinclair41e4d9a2022-05-01 14:40:55 +0000571 auto got = Run<BuiltinPolyfill>(src, polyfillExtractBits(Level::kClampParameters));
Ben Claytond868e862022-02-23 21:18:09 +0000572
dan sinclair41e4d9a2022-05-01 14:40:55 +0000573 EXPECT_EQ(expect, str(got));
Ben Claytond868e862022-02-23 21:18:09 +0000574}
575
576////////////////////////////////////////////////////////////////////////////////
Ben Clayton81696932022-02-23 18:20:30 +0000577// firstLeadingBit
578////////////////////////////////////////////////////////////////////////////////
579DataMap polyfillFirstLeadingBit() {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000580 BuiltinPolyfill::Builtins builtins;
581 builtins.first_leading_bit = true;
582 DataMap data;
583 data.Add<BuiltinPolyfill::Config>(builtins);
584 return data;
Ben Clayton81696932022-02-23 18:20:30 +0000585}
586
587TEST_F(BuiltinPolyfillTest, ShouldRunFirstLeadingBit) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000588 auto* src = R"(
Ben Clayton81696932022-02-23 18:20:30 +0000589fn f() {
590 firstLeadingBit(0xf);
591}
592)";
593
dan sinclair41e4d9a2022-05-01 14:40:55 +0000594 EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
595 EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillFirstLeadingBit()));
Ben Clayton81696932022-02-23 18:20:30 +0000596}
597
598TEST_F(BuiltinPolyfillTest, FirstLeadingBit_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000599 auto* src = R"(
Ben Clayton81696932022-02-23 18:20:30 +0000600fn f() {
601 let r : i32 = firstLeadingBit(15);
602}
603)";
604
dan sinclair41e4d9a2022-05-01 14:40:55 +0000605 auto* expect = R"(
Ben Clayton81696932022-02-23 18:20:30 +0000606fn tint_first_leading_bit(v : i32) -> i32 {
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000607 var x = select(u32(v), u32(~(v)), (v < 0i));
Ben Clayton81696932022-02-23 18:20:30 +0000608 let b16 = select(0u, 16u, bool((x & 4294901760u)));
609 x = (x >> b16);
610 let b8 = select(0u, 8u, bool((x & 65280u)));
611 x = (x >> b8);
612 let b4 = select(0u, 4u, bool((x & 240u)));
613 x = (x >> b4);
614 let b2 = select(0u, 2u, bool((x & 12u)));
615 x = (x >> b2);
616 let b1 = select(0u, 1u, bool((x & 2u)));
617 let is_zero = select(0u, 4294967295u, (x == 0u));
618 return i32((((((b16 | b8) | b4) | b2) | b1) | is_zero));
619}
620
621fn f() {
622 let r : i32 = tint_first_leading_bit(15);
623}
624)";
625
dan sinclair41e4d9a2022-05-01 14:40:55 +0000626 auto got = Run<BuiltinPolyfill>(src, polyfillFirstLeadingBit());
Ben Clayton81696932022-02-23 18:20:30 +0000627
dan sinclair41e4d9a2022-05-01 14:40:55 +0000628 EXPECT_EQ(expect, str(got));
Ben Clayton81696932022-02-23 18:20:30 +0000629}
630
631TEST_F(BuiltinPolyfillTest, FirstLeadingBit_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000632 auto* src = R"(
Ben Clayton81696932022-02-23 18:20:30 +0000633fn f() {
634 let r : u32 = firstLeadingBit(15u);
635}
636)";
637
dan sinclair41e4d9a2022-05-01 14:40:55 +0000638 auto* expect = R"(
Ben Clayton81696932022-02-23 18:20:30 +0000639fn tint_first_leading_bit(v : u32) -> u32 {
640 var x = v;
641 let b16 = select(0u, 16u, bool((x & 4294901760u)));
642 x = (x >> b16);
643 let b8 = select(0u, 8u, bool((x & 65280u)));
644 x = (x >> b8);
645 let b4 = select(0u, 4u, bool((x & 240u)));
646 x = (x >> b4);
647 let b2 = select(0u, 2u, bool((x & 12u)));
648 x = (x >> b2);
649 let b1 = select(0u, 1u, bool((x & 2u)));
650 let is_zero = select(0u, 4294967295u, (x == 0u));
651 return u32((((((b16 | b8) | b4) | b2) | b1) | is_zero));
652}
653
654fn f() {
655 let r : u32 = tint_first_leading_bit(15u);
656}
657)";
658
dan sinclair41e4d9a2022-05-01 14:40:55 +0000659 auto got = Run<BuiltinPolyfill>(src, polyfillFirstLeadingBit());
Ben Clayton81696932022-02-23 18:20:30 +0000660
dan sinclair41e4d9a2022-05-01 14:40:55 +0000661 EXPECT_EQ(expect, str(got));
Ben Clayton81696932022-02-23 18:20:30 +0000662}
663
664TEST_F(BuiltinPolyfillTest, FirstLeadingBit_vec3_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000665 auto* src = R"(
Ben Clayton81696932022-02-23 18:20:30 +0000666fn f() {
667 let r : vec3<i32> = firstLeadingBit(vec3<i32>(15));
668}
669)";
670
dan sinclair41e4d9a2022-05-01 14:40:55 +0000671 auto* expect = R"(
Ben Clayton81696932022-02-23 18:20:30 +0000672fn tint_first_leading_bit(v : vec3<i32>) -> vec3<i32> {
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000673 var x = select(vec3<u32>(v), vec3<u32>(~(v)), (v < vec3<i32>(0i)));
Ben Clayton81696932022-02-23 18:20:30 +0000674 let b16 = select(vec3<u32>(0u), vec3<u32>(16u), vec3<bool>((x & vec3<u32>(4294901760u))));
675 x = (x >> b16);
676 let b8 = select(vec3<u32>(0u), vec3<u32>(8u), vec3<bool>((x & vec3<u32>(65280u))));
677 x = (x >> b8);
678 let b4 = select(vec3<u32>(0u), vec3<u32>(4u), vec3<bool>((x & vec3<u32>(240u))));
679 x = (x >> b4);
680 let b2 = select(vec3<u32>(0u), vec3<u32>(2u), vec3<bool>((x & vec3<u32>(12u))));
681 x = (x >> b2);
682 let b1 = select(vec3<u32>(0u), vec3<u32>(1u), vec3<bool>((x & vec3<u32>(2u))));
683 let is_zero = select(vec3<u32>(0u), vec3<u32>(4294967295u), (x == vec3<u32>(0u)));
684 return vec3<i32>((((((b16 | b8) | b4) | b2) | b1) | is_zero));
685}
686
687fn f() {
688 let r : vec3<i32> = tint_first_leading_bit(vec3<i32>(15));
689}
690)";
691
dan sinclair41e4d9a2022-05-01 14:40:55 +0000692 auto got = Run<BuiltinPolyfill>(src, polyfillFirstLeadingBit());
Ben Clayton81696932022-02-23 18:20:30 +0000693
dan sinclair41e4d9a2022-05-01 14:40:55 +0000694 EXPECT_EQ(expect, str(got));
Ben Clayton81696932022-02-23 18:20:30 +0000695}
696
697TEST_F(BuiltinPolyfillTest, FirstLeadingBit_vec3_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000698 auto* src = R"(
Ben Clayton81696932022-02-23 18:20:30 +0000699fn f() {
700 let r : vec3<u32> = firstLeadingBit(vec3<u32>(15u));
701}
702)";
703
dan sinclair41e4d9a2022-05-01 14:40:55 +0000704 auto* expect = R"(
Ben Clayton81696932022-02-23 18:20:30 +0000705fn tint_first_leading_bit(v : vec3<u32>) -> vec3<u32> {
706 var x = v;
707 let b16 = select(vec3<u32>(0u), vec3<u32>(16u), vec3<bool>((x & vec3<u32>(4294901760u))));
708 x = (x >> b16);
709 let b8 = select(vec3<u32>(0u), vec3<u32>(8u), vec3<bool>((x & vec3<u32>(65280u))));
710 x = (x >> b8);
711 let b4 = select(vec3<u32>(0u), vec3<u32>(4u), vec3<bool>((x & vec3<u32>(240u))));
712 x = (x >> b4);
713 let b2 = select(vec3<u32>(0u), vec3<u32>(2u), vec3<bool>((x & vec3<u32>(12u))));
714 x = (x >> b2);
715 let b1 = select(vec3<u32>(0u), vec3<u32>(1u), vec3<bool>((x & vec3<u32>(2u))));
716 let is_zero = select(vec3<u32>(0u), vec3<u32>(4294967295u), (x == vec3<u32>(0u)));
717 return vec3<u32>((((((b16 | b8) | b4) | b2) | b1) | is_zero));
718}
719
720fn f() {
721 let r : vec3<u32> = tint_first_leading_bit(vec3<u32>(15u));
722}
723)";
724
dan sinclair41e4d9a2022-05-01 14:40:55 +0000725 auto got = Run<BuiltinPolyfill>(src, polyfillFirstLeadingBit());
Ben Clayton81696932022-02-23 18:20:30 +0000726
dan sinclair41e4d9a2022-05-01 14:40:55 +0000727 EXPECT_EQ(expect, str(got));
Ben Clayton81696932022-02-23 18:20:30 +0000728}
729
730////////////////////////////////////////////////////////////////////////////////
Ben Claytondf3630c2022-02-23 14:32:14 +0000731// firstTrailingBit
732////////////////////////////////////////////////////////////////////////////////
733DataMap polyfillFirstTrailingBit() {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000734 BuiltinPolyfill::Builtins builtins;
735 builtins.first_trailing_bit = true;
736 DataMap data;
737 data.Add<BuiltinPolyfill::Config>(builtins);
738 return data;
Ben Claytondf3630c2022-02-23 14:32:14 +0000739}
740
741TEST_F(BuiltinPolyfillTest, ShouldRunFirstTrailingBit) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000742 auto* src = R"(
Ben Claytondf3630c2022-02-23 14:32:14 +0000743fn f() {
744 firstTrailingBit(0xf);
745}
746)";
747
dan sinclair41e4d9a2022-05-01 14:40:55 +0000748 EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
749 EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillFirstTrailingBit()));
Ben Claytondf3630c2022-02-23 14:32:14 +0000750}
751
752TEST_F(BuiltinPolyfillTest, FirstTrailingBit_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000753 auto* src = R"(
Ben Claytondf3630c2022-02-23 14:32:14 +0000754fn f() {
755 let r : i32 = firstTrailingBit(15);
756}
757)";
758
dan sinclair41e4d9a2022-05-01 14:40:55 +0000759 auto* expect = R"(
Ben Claytondf3630c2022-02-23 14:32:14 +0000760fn tint_first_trailing_bit(v : i32) -> i32 {
761 var x = u32(v);
762 let b16 = select(16u, 0u, bool((x & 65535u)));
763 x = (x >> b16);
764 let b8 = select(8u, 0u, bool((x & 255u)));
765 x = (x >> b8);
766 let b4 = select(4u, 0u, bool((x & 15u)));
767 x = (x >> b4);
768 let b2 = select(2u, 0u, bool((x & 3u)));
769 x = (x >> b2);
770 let b1 = select(1u, 0u, bool((x & 1u)));
771 let is_zero = select(0u, 4294967295u, (x == 0u));
772 return i32((((((b16 | b8) | b4) | b2) | b1) | is_zero));
773}
774
775fn f() {
776 let r : i32 = tint_first_trailing_bit(15);
777}
778)";
779
dan sinclair41e4d9a2022-05-01 14:40:55 +0000780 auto got = Run<BuiltinPolyfill>(src, polyfillFirstTrailingBit());
Ben Claytondf3630c2022-02-23 14:32:14 +0000781
dan sinclair41e4d9a2022-05-01 14:40:55 +0000782 EXPECT_EQ(expect, str(got));
Ben Claytondf3630c2022-02-23 14:32:14 +0000783}
784
785TEST_F(BuiltinPolyfillTest, FirstTrailingBit_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000786 auto* src = R"(
Ben Claytondf3630c2022-02-23 14:32:14 +0000787fn f() {
788 let r : u32 = firstTrailingBit(15u);
789}
790)";
791
dan sinclair41e4d9a2022-05-01 14:40:55 +0000792 auto* expect = R"(
Ben Claytondf3630c2022-02-23 14:32:14 +0000793fn tint_first_trailing_bit(v : u32) -> u32 {
794 var x = u32(v);
795 let b16 = select(16u, 0u, bool((x & 65535u)));
796 x = (x >> b16);
797 let b8 = select(8u, 0u, bool((x & 255u)));
798 x = (x >> b8);
799 let b4 = select(4u, 0u, bool((x & 15u)));
800 x = (x >> b4);
801 let b2 = select(2u, 0u, bool((x & 3u)));
802 x = (x >> b2);
803 let b1 = select(1u, 0u, bool((x & 1u)));
804 let is_zero = select(0u, 4294967295u, (x == 0u));
805 return u32((((((b16 | b8) | b4) | b2) | b1) | is_zero));
806}
807
808fn f() {
809 let r : u32 = tint_first_trailing_bit(15u);
810}
811)";
812
dan sinclair41e4d9a2022-05-01 14:40:55 +0000813 auto got = Run<BuiltinPolyfill>(src, polyfillFirstTrailingBit());
Ben Claytondf3630c2022-02-23 14:32:14 +0000814
dan sinclair41e4d9a2022-05-01 14:40:55 +0000815 EXPECT_EQ(expect, str(got));
Ben Claytondf3630c2022-02-23 14:32:14 +0000816}
817
818TEST_F(BuiltinPolyfillTest, FirstTrailingBit_vec3_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000819 auto* src = R"(
Ben Claytondf3630c2022-02-23 14:32:14 +0000820fn f() {
821 let r : vec3<i32> = firstTrailingBit(vec3<i32>(15));
822}
823)";
824
dan sinclair41e4d9a2022-05-01 14:40:55 +0000825 auto* expect = R"(
Ben Claytondf3630c2022-02-23 14:32:14 +0000826fn tint_first_trailing_bit(v : vec3<i32>) -> vec3<i32> {
827 var x = vec3<u32>(v);
828 let b16 = select(vec3<u32>(16u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(65535u))));
829 x = (x >> b16);
830 let b8 = select(vec3<u32>(8u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(255u))));
831 x = (x >> b8);
832 let b4 = select(vec3<u32>(4u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(15u))));
833 x = (x >> b4);
834 let b2 = select(vec3<u32>(2u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(3u))));
835 x = (x >> b2);
836 let b1 = select(vec3<u32>(1u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(1u))));
837 let is_zero = select(vec3<u32>(0u), vec3<u32>(4294967295u), (x == vec3<u32>(0u)));
838 return vec3<i32>((((((b16 | b8) | b4) | b2) | b1) | is_zero));
839}
840
841fn f() {
842 let r : vec3<i32> = tint_first_trailing_bit(vec3<i32>(15));
843}
844)";
845
dan sinclair41e4d9a2022-05-01 14:40:55 +0000846 auto got = Run<BuiltinPolyfill>(src, polyfillFirstTrailingBit());
Ben Claytondf3630c2022-02-23 14:32:14 +0000847
dan sinclair41e4d9a2022-05-01 14:40:55 +0000848 EXPECT_EQ(expect, str(got));
Ben Claytondf3630c2022-02-23 14:32:14 +0000849}
850
851TEST_F(BuiltinPolyfillTest, FirstTrailingBit_vec3_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000852 auto* src = R"(
Ben Claytondf3630c2022-02-23 14:32:14 +0000853fn f() {
854 let r : vec3<u32> = firstTrailingBit(vec3<u32>(15u));
855}
856)";
857
dan sinclair41e4d9a2022-05-01 14:40:55 +0000858 auto* expect = R"(
Ben Claytondf3630c2022-02-23 14:32:14 +0000859fn tint_first_trailing_bit(v : vec3<u32>) -> vec3<u32> {
860 var x = vec3<u32>(v);
861 let b16 = select(vec3<u32>(16u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(65535u))));
862 x = (x >> b16);
863 let b8 = select(vec3<u32>(8u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(255u))));
864 x = (x >> b8);
865 let b4 = select(vec3<u32>(4u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(15u))));
866 x = (x >> b4);
867 let b2 = select(vec3<u32>(2u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(3u))));
868 x = (x >> b2);
869 let b1 = select(vec3<u32>(1u), vec3<u32>(0u), vec3<bool>((x & vec3<u32>(1u))));
870 let is_zero = select(vec3<u32>(0u), vec3<u32>(4294967295u), (x == vec3<u32>(0u)));
871 return vec3<u32>((((((b16 | b8) | b4) | b2) | b1) | is_zero));
872}
873
874fn f() {
875 let r : vec3<u32> = tint_first_trailing_bit(vec3<u32>(15u));
876}
877)";
878
dan sinclair41e4d9a2022-05-01 14:40:55 +0000879 auto got = Run<BuiltinPolyfill>(src, polyfillFirstTrailingBit());
Ben Claytondf3630c2022-02-23 14:32:14 +0000880
dan sinclair41e4d9a2022-05-01 14:40:55 +0000881 EXPECT_EQ(expect, str(got));
Ben Claytondf3630c2022-02-23 14:32:14 +0000882}
883
Ben Claytonfe08ba42022-02-23 21:18:09 +0000884////////////////////////////////////////////////////////////////////////////////
885// insertBits
886////////////////////////////////////////////////////////////////////////////////
887DataMap polyfillInsertBits(Level level) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000888 BuiltinPolyfill::Builtins builtins;
889 builtins.insert_bits = level;
890 DataMap data;
891 data.Add<BuiltinPolyfill::Config>(builtins);
892 return data;
Ben Claytonfe08ba42022-02-23 21:18:09 +0000893}
894
895TEST_F(BuiltinPolyfillTest, ShouldRunInsertBits) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000896 auto* src = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +0000897fn f() {
898 insertBits(1234, 5678, 5u, 6u);
899}
900)";
901
dan sinclair41e4d9a2022-05-01 14:40:55 +0000902 EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src));
903 EXPECT_FALSE(ShouldRun<BuiltinPolyfill>(src, polyfillInsertBits(Level::kNone)));
904 EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillInsertBits(Level::kClampParameters)));
905 EXPECT_TRUE(ShouldRun<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull)));
Ben Claytonfe08ba42022-02-23 21:18:09 +0000906}
907
908TEST_F(BuiltinPolyfillTest, InsertBits_Full_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000909 auto* src = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +0000910fn f() {
911 let r : i32 = insertBits(1234, 5678, 5u, 6u);
912}
913)";
914
dan sinclair41e4d9a2022-05-01 14:40:55 +0000915 auto* expect = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +0000916fn tint_insert_bits(v : i32, n : i32, offset : u32, count : u32) -> i32 {
917 let s = min(offset, 32u);
918 let e = min(32u, (s + count));
919 let mask = (((1u << s) - 1u) ^ ((1u << e) - 1u));
920 return (((n << s) & i32(mask)) | (v & i32(~(mask))));
921}
922
923fn f() {
924 let r : i32 = tint_insert_bits(1234, 5678, 5u, 6u);
925}
926)";
927
dan sinclair41e4d9a2022-05-01 14:40:55 +0000928 auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull));
Ben Claytonfe08ba42022-02-23 21:18:09 +0000929
dan sinclair41e4d9a2022-05-01 14:40:55 +0000930 EXPECT_EQ(expect, str(got));
Ben Claytonfe08ba42022-02-23 21:18:09 +0000931}
932
933TEST_F(BuiltinPolyfillTest, InsertBits_Full_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000934 auto* src = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +0000935fn f() {
936 let r : u32 = insertBits(1234u, 5678u, 5u, 6u);
937}
938)";
939
dan sinclair41e4d9a2022-05-01 14:40:55 +0000940 auto* expect = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +0000941fn tint_insert_bits(v : u32, n : u32, offset : u32, count : u32) -> u32 {
942 let s = min(offset, 32u);
943 let e = min(32u, (s + count));
944 let mask = (((1u << s) - 1u) ^ ((1u << e) - 1u));
945 return (((n << s) & mask) | (v & ~(mask)));
946}
947
948fn f() {
949 let r : u32 = tint_insert_bits(1234u, 5678u, 5u, 6u);
950}
951)";
952
dan sinclair41e4d9a2022-05-01 14:40:55 +0000953 auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull));
Ben Claytonfe08ba42022-02-23 21:18:09 +0000954
dan sinclair41e4d9a2022-05-01 14:40:55 +0000955 EXPECT_EQ(expect, str(got));
Ben Claytonfe08ba42022-02-23 21:18:09 +0000956}
957
958TEST_F(BuiltinPolyfillTest, InsertBits_Full_vec3_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000959 auto* src = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +0000960fn f() {
961 let r : vec3<i32> = insertBits(vec3<i32>(1234), vec3<i32>(5678), 5u, 6u);
962}
963)";
964
dan sinclair41e4d9a2022-05-01 14:40:55 +0000965 auto* expect = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +0000966fn tint_insert_bits(v : vec3<i32>, n : vec3<i32>, offset : u32, count : u32) -> vec3<i32> {
967 let s = min(offset, 32u);
968 let e = min(32u, (s + count));
969 let mask = (((1u << s) - 1u) ^ ((1u << e) - 1u));
970 return (((n << vec3<u32>(s)) & vec3<i32>(i32(mask))) | (v & vec3<i32>(i32(~(mask)))));
971}
972
973fn f() {
974 let r : vec3<i32> = tint_insert_bits(vec3<i32>(1234), vec3<i32>(5678), 5u, 6u);
975}
976)";
977
dan sinclair41e4d9a2022-05-01 14:40:55 +0000978 auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull));
Ben Claytonfe08ba42022-02-23 21:18:09 +0000979
dan sinclair41e4d9a2022-05-01 14:40:55 +0000980 EXPECT_EQ(expect, str(got));
Ben Claytonfe08ba42022-02-23 21:18:09 +0000981}
982
983TEST_F(BuiltinPolyfillTest, InsertBits_Full_vec3_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000984 auto* src = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +0000985fn f() {
986 let r : vec3<u32> = insertBits(vec3<u32>(1234u), vec3<u32>(5678u), 5u, 6u);
987}
988)";
989
dan sinclair41e4d9a2022-05-01 14:40:55 +0000990 auto* expect = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +0000991fn tint_insert_bits(v : vec3<u32>, n : vec3<u32>, offset : u32, count : u32) -> vec3<u32> {
992 let s = min(offset, 32u);
993 let e = min(32u, (s + count));
994 let mask = (((1u << s) - 1u) ^ ((1u << e) - 1u));
995 return (((n << vec3<u32>(s)) & vec3<u32>(mask)) | (v & vec3<u32>(~(mask))));
996}
997
998fn f() {
999 let r : vec3<u32> = tint_insert_bits(vec3<u32>(1234u), vec3<u32>(5678u), 5u, 6u);
1000}
1001)";
1002
dan sinclair41e4d9a2022-05-01 14:40:55 +00001003 auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kFull));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001004
dan sinclair41e4d9a2022-05-01 14:40:55 +00001005 EXPECT_EQ(expect, str(got));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001006}
1007
1008TEST_F(BuiltinPolyfillTest, InsertBits_Clamp_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +00001009 auto* src = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +00001010fn f() {
1011 let r : i32 = insertBits(1234, 5678, 5u, 6u);
1012}
1013)";
1014
dan sinclair41e4d9a2022-05-01 14:40:55 +00001015 auto* expect = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +00001016fn tint_insert_bits(v : i32, n : i32, offset : u32, count : u32) -> i32 {
1017 let s = min(offset, 32u);
1018 let e = min(32u, (s + count));
1019 return insertBits(v, n, s, (e - s));
1020}
1021
1022fn f() {
1023 let r : i32 = tint_insert_bits(1234, 5678, 5u, 6u);
1024}
1025)";
1026
dan sinclair41e4d9a2022-05-01 14:40:55 +00001027 auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kClampParameters));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001028
dan sinclair41e4d9a2022-05-01 14:40:55 +00001029 EXPECT_EQ(expect, str(got));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001030}
1031
1032TEST_F(BuiltinPolyfillTest, InsertBits_Clamp_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +00001033 auto* src = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +00001034fn f() {
1035 let r : u32 = insertBits(1234u, 5678u, 5u, 6u);
1036}
1037)";
1038
dan sinclair41e4d9a2022-05-01 14:40:55 +00001039 auto* expect = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +00001040fn tint_insert_bits(v : u32, n : u32, offset : u32, count : u32) -> u32 {
1041 let s = min(offset, 32u);
1042 let e = min(32u, (s + count));
1043 return insertBits(v, n, s, (e - s));
1044}
1045
1046fn f() {
1047 let r : u32 = tint_insert_bits(1234u, 5678u, 5u, 6u);
1048}
1049)";
1050
dan sinclair41e4d9a2022-05-01 14:40:55 +00001051 auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kClampParameters));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001052
dan sinclair41e4d9a2022-05-01 14:40:55 +00001053 EXPECT_EQ(expect, str(got));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001054}
1055
1056TEST_F(BuiltinPolyfillTest, InsertBits_Clamp_vec3_i32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +00001057 auto* src = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +00001058fn f() {
1059 let r : vec3<i32> = insertBits(vec3<i32>(1234), vec3<i32>(5678), 5u, 6u);
1060}
1061)";
1062
dan sinclair41e4d9a2022-05-01 14:40:55 +00001063 auto* expect = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +00001064fn tint_insert_bits(v : vec3<i32>, n : vec3<i32>, offset : u32, count : u32) -> vec3<i32> {
1065 let s = min(offset, 32u);
1066 let e = min(32u, (s + count));
1067 return insertBits(v, n, s, (e - s));
1068}
1069
1070fn f() {
1071 let r : vec3<i32> = tint_insert_bits(vec3<i32>(1234), vec3<i32>(5678), 5u, 6u);
1072}
1073)";
1074
dan sinclair41e4d9a2022-05-01 14:40:55 +00001075 auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kClampParameters));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001076
dan sinclair41e4d9a2022-05-01 14:40:55 +00001077 EXPECT_EQ(expect, str(got));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001078}
1079
1080TEST_F(BuiltinPolyfillTest, InsertBits_Clamp_vec3_u32) {
dan sinclair41e4d9a2022-05-01 14:40:55 +00001081 auto* src = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +00001082fn f() {
1083 let r : vec3<u32> = insertBits(vec3<u32>(1234u), vec3<u32>(5678u), 5u, 6u);
1084}
1085)";
1086
dan sinclair41e4d9a2022-05-01 14:40:55 +00001087 auto* expect = R"(
Ben Claytonfe08ba42022-02-23 21:18:09 +00001088fn tint_insert_bits(v : vec3<u32>, n : vec3<u32>, offset : u32, count : u32) -> vec3<u32> {
1089 let s = min(offset, 32u);
1090 let e = min(32u, (s + count));
1091 return insertBits(v, n, s, (e - s));
1092}
1093
1094fn f() {
1095 let r : vec3<u32> = tint_insert_bits(vec3<u32>(1234u), vec3<u32>(5678u), 5u, 6u);
1096}
1097)";
1098
dan sinclair41e4d9a2022-05-01 14:40:55 +00001099 auto got = Run<BuiltinPolyfill>(src, polyfillInsertBits(Level::kClampParameters));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001100
dan sinclair41e4d9a2022-05-01 14:40:55 +00001101 EXPECT_EQ(expect, str(got));
Ben Claytonfe08ba42022-02-23 21:18:09 +00001102}
1103
Ben Clayton27aa57c2022-02-22 23:13:39 +00001104} // namespace
dan sinclairb5599d32022-04-07 16:55:14 +00001105} // namespace tint::transform