1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker
15*03ce13f7SAndroid Build Coastguard Worker #include "Assert.hpp"
16*03ce13f7SAndroid Build Coastguard Worker #include "Coroutine.hpp"
17*03ce13f7SAndroid Build Coastguard Worker #include "Print.hpp"
18*03ce13f7SAndroid Build Coastguard Worker #include "Reactor.hpp"
19*03ce13f7SAndroid Build Coastguard Worker
20*03ce13f7SAndroid Build Coastguard Worker #include "gtest/gtest.h"
21*03ce13f7SAndroid Build Coastguard Worker
22*03ce13f7SAndroid Build Coastguard Worker #include <array>
23*03ce13f7SAndroid Build Coastguard Worker #include <cmath>
24*03ce13f7SAndroid Build Coastguard Worker #include <filesystem>
25*03ce13f7SAndroid Build Coastguard Worker #include <fstream>
26*03ce13f7SAndroid Build Coastguard Worker #include <thread>
27*03ce13f7SAndroid Build Coastguard Worker #include <tuple>
28*03ce13f7SAndroid Build Coastguard Worker
29*03ce13f7SAndroid Build Coastguard Worker using namespace rr;
30*03ce13f7SAndroid Build Coastguard Worker
31*03ce13f7SAndroid Build Coastguard Worker using float4 = float[4];
32*03ce13f7SAndroid Build Coastguard Worker using int4 = int[4];
33*03ce13f7SAndroid Build Coastguard Worker
testName()34*03ce13f7SAndroid Build Coastguard Worker static std::string testName()
35*03ce13f7SAndroid Build Coastguard Worker {
36*03ce13f7SAndroid Build Coastguard Worker auto info = ::testing::UnitTest::GetInstance()->current_test_info();
37*03ce13f7SAndroid Build Coastguard Worker return std::string{ info->test_suite_name() } + "_" + info->name();
38*03ce13f7SAndroid Build Coastguard Worker }
39*03ce13f7SAndroid Build Coastguard Worker
reference(int * p,int y)40*03ce13f7SAndroid Build Coastguard Worker int reference(int *p, int y)
41*03ce13f7SAndroid Build Coastguard Worker {
42*03ce13f7SAndroid Build Coastguard Worker int x = p[-1];
43*03ce13f7SAndroid Build Coastguard Worker int z = 4;
44*03ce13f7SAndroid Build Coastguard Worker
45*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 10; i++)
46*03ce13f7SAndroid Build Coastguard Worker {
47*03ce13f7SAndroid Build Coastguard Worker z += (2 << i) - (i / 3);
48*03ce13f7SAndroid Build Coastguard Worker }
49*03ce13f7SAndroid Build Coastguard Worker
50*03ce13f7SAndroid Build Coastguard Worker int sum = x + y + z;
51*03ce13f7SAndroid Build Coastguard Worker
52*03ce13f7SAndroid Build Coastguard Worker return sum;
53*03ce13f7SAndroid Build Coastguard Worker }
54*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Sample)55*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Sample)
56*03ce13f7SAndroid Build Coastguard Worker {
57*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int *, int)> function;
58*03ce13f7SAndroid Build Coastguard Worker {
59*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p = function.Arg<0>();
60*03ce13f7SAndroid Build Coastguard Worker Int x = p[-1];
61*03ce13f7SAndroid Build Coastguard Worker Int y = function.Arg<1>();
62*03ce13f7SAndroid Build Coastguard Worker Int z = 4;
63*03ce13f7SAndroid Build Coastguard Worker
64*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < 10, i++)
65*03ce13f7SAndroid Build Coastguard Worker {
66*03ce13f7SAndroid Build Coastguard Worker z += (2 << i) - (i / 3);
67*03ce13f7SAndroid Build Coastguard Worker }
68*03ce13f7SAndroid Build Coastguard Worker
69*03ce13f7SAndroid Build Coastguard Worker Float4 v;
70*03ce13f7SAndroid Build Coastguard Worker v.z = As<Float>(z);
71*03ce13f7SAndroid Build Coastguard Worker z = As<Int>(Float(Float4(v.xzxx).y));
72*03ce13f7SAndroid Build Coastguard Worker
73*03ce13f7SAndroid Build Coastguard Worker Int sum = x + y + z;
74*03ce13f7SAndroid Build Coastguard Worker
75*03ce13f7SAndroid Build Coastguard Worker Return(sum);
76*03ce13f7SAndroid Build Coastguard Worker }
77*03ce13f7SAndroid Build Coastguard Worker
78*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
79*03ce13f7SAndroid Build Coastguard Worker
80*03ce13f7SAndroid Build Coastguard Worker int one[2] = { 1, 0 };
81*03ce13f7SAndroid Build Coastguard Worker int result = routine(&one[1], 2);
82*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, reference(&one[1], 2));
83*03ce13f7SAndroid Build Coastguard Worker }
84*03ce13f7SAndroid Build Coastguard Worker
85*03ce13f7SAndroid Build Coastguard Worker // This test demonstrates the use of a 'trampoline', where a routine calls
86*03ce13f7SAndroid Build Coastguard Worker // a static function which then generates another routine during the execution
87*03ce13f7SAndroid Build Coastguard Worker // of the first routine. Also note the code generated for the second routine
88*03ce13f7SAndroid Build Coastguard Worker // depends on a parameter passed to the first routine.
TEST(ReactorUnitTests,Trampoline)89*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Trampoline)
90*03ce13f7SAndroid Build Coastguard Worker {
91*03ce13f7SAndroid Build Coastguard Worker using SecondaryFunc = int(int, int);
92*03ce13f7SAndroid Build Coastguard Worker
93*03ce13f7SAndroid Build Coastguard Worker static auto generateSecondary = [](int upDown) {
94*03ce13f7SAndroid Build Coastguard Worker FunctionT<SecondaryFunc> secondary;
95*03ce13f7SAndroid Build Coastguard Worker {
96*03ce13f7SAndroid Build Coastguard Worker Int x = secondary.Arg<0>();
97*03ce13f7SAndroid Build Coastguard Worker Int y = secondary.Arg<1>();
98*03ce13f7SAndroid Build Coastguard Worker Int r;
99*03ce13f7SAndroid Build Coastguard Worker
100*03ce13f7SAndroid Build Coastguard Worker if(upDown > 0)
101*03ce13f7SAndroid Build Coastguard Worker {
102*03ce13f7SAndroid Build Coastguard Worker r = x + y;
103*03ce13f7SAndroid Build Coastguard Worker }
104*03ce13f7SAndroid Build Coastguard Worker else if(upDown < 0)
105*03ce13f7SAndroid Build Coastguard Worker {
106*03ce13f7SAndroid Build Coastguard Worker r = x - y;
107*03ce13f7SAndroid Build Coastguard Worker }
108*03ce13f7SAndroid Build Coastguard Worker else
109*03ce13f7SAndroid Build Coastguard Worker {
110*03ce13f7SAndroid Build Coastguard Worker r = 0;
111*03ce13f7SAndroid Build Coastguard Worker }
112*03ce13f7SAndroid Build Coastguard Worker
113*03ce13f7SAndroid Build Coastguard Worker Return(r);
114*03ce13f7SAndroid Build Coastguard Worker }
115*03ce13f7SAndroid Build Coastguard Worker
116*03ce13f7SAndroid Build Coastguard Worker static auto routine = secondary((testName() + "_secondary").c_str());
117*03ce13f7SAndroid Build Coastguard Worker return routine.getEntry();
118*03ce13f7SAndroid Build Coastguard Worker };
119*03ce13f7SAndroid Build Coastguard Worker
120*03ce13f7SAndroid Build Coastguard Worker using SecondaryGeneratorFunc = SecondaryFunc *(*)(int);
121*03ce13f7SAndroid Build Coastguard Worker SecondaryGeneratorFunc secondaryGenerator = (SecondaryGeneratorFunc)generateSecondary;
122*03ce13f7SAndroid Build Coastguard Worker
123*03ce13f7SAndroid Build Coastguard Worker using PrimaryFunc = int(int, int, int);
124*03ce13f7SAndroid Build Coastguard Worker
125*03ce13f7SAndroid Build Coastguard Worker FunctionT<PrimaryFunc> primary;
126*03ce13f7SAndroid Build Coastguard Worker {
127*03ce13f7SAndroid Build Coastguard Worker Int x = primary.Arg<0>();
128*03ce13f7SAndroid Build Coastguard Worker Int y = primary.Arg<1>();
129*03ce13f7SAndroid Build Coastguard Worker Int z = primary.Arg<2>();
130*03ce13f7SAndroid Build Coastguard Worker
131*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> secondary = Call(secondaryGenerator, z);
132*03ce13f7SAndroid Build Coastguard Worker Int r = Call<SecondaryFunc>(secondary, x, y);
133*03ce13f7SAndroid Build Coastguard Worker
134*03ce13f7SAndroid Build Coastguard Worker Return(r);
135*03ce13f7SAndroid Build Coastguard Worker }
136*03ce13f7SAndroid Build Coastguard Worker
137*03ce13f7SAndroid Build Coastguard Worker auto routine = primary((testName() + "_primary").c_str());
138*03ce13f7SAndroid Build Coastguard Worker
139*03ce13f7SAndroid Build Coastguard Worker int result = routine(100, 20, -3);
140*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 80);
141*03ce13f7SAndroid Build Coastguard Worker }
142*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Uninitialized)143*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Uninitialized)
144*03ce13f7SAndroid Build Coastguard Worker {
145*03ce13f7SAndroid Build Coastguard Worker #if __has_feature(memory_sanitizer)
146*03ce13f7SAndroid Build Coastguard Worker // Building the static C++ code with MemorySanitizer enabled does not
147*03ce13f7SAndroid Build Coastguard Worker // automatically enable MemorySanitizer instrumentation for Reactor
148*03ce13f7SAndroid Build Coastguard Worker // routines. False positives can also be prevented by unpoisoning all
149*03ce13f7SAndroid Build Coastguard Worker // memory writes. This Pragma ensures proper instrumentation is enabled.
150*03ce13f7SAndroid Build Coastguard Worker Pragma(MemorySanitizerInstrumentation, true);
151*03ce13f7SAndroid Build Coastguard Worker #endif
152*03ce13f7SAndroid Build Coastguard Worker
153*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
154*03ce13f7SAndroid Build Coastguard Worker {
155*03ce13f7SAndroid Build Coastguard Worker Int a;
156*03ce13f7SAndroid Build Coastguard Worker Int z = 4;
157*03ce13f7SAndroid Build Coastguard Worker Int q;
158*03ce13f7SAndroid Build Coastguard Worker Int c;
159*03ce13f7SAndroid Build Coastguard Worker Int p;
160*03ce13f7SAndroid Build Coastguard Worker Bool b;
161*03ce13f7SAndroid Build Coastguard Worker
162*03ce13f7SAndroid Build Coastguard Worker q += q;
163*03ce13f7SAndroid Build Coastguard Worker
164*03ce13f7SAndroid Build Coastguard Worker If(b)
165*03ce13f7SAndroid Build Coastguard Worker {
166*03ce13f7SAndroid Build Coastguard Worker c = p;
167*03ce13f7SAndroid Build Coastguard Worker }
168*03ce13f7SAndroid Build Coastguard Worker
169*03ce13f7SAndroid Build Coastguard Worker Return(a + z + q + c);
170*03ce13f7SAndroid Build Coastguard Worker }
171*03ce13f7SAndroid Build Coastguard Worker
172*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
173*03ce13f7SAndroid Build Coastguard Worker
174*03ce13f7SAndroid Build Coastguard Worker if(!__has_feature(memory_sanitizer))
175*03ce13f7SAndroid Build Coastguard Worker {
176*03ce13f7SAndroid Build Coastguard Worker int result = routine();
177*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, result); // Anything is fine, just don't crash
178*03ce13f7SAndroid Build Coastguard Worker }
179*03ce13f7SAndroid Build Coastguard Worker else
180*03ce13f7SAndroid Build Coastguard Worker {
181*03ce13f7SAndroid Build Coastguard Worker // Optimizations may turn the conditional If() in the Reactor code
182*03ce13f7SAndroid Build Coastguard Worker // into a conditional move or arithmetic operations, which would not
183*03ce13f7SAndroid Build Coastguard Worker // trigger a MemorySanitizer error. However, in that case the equals
184*03ce13f7SAndroid Build Coastguard Worker // operator below should trigger it before the abort is reached.
185*03ce13f7SAndroid Build Coastguard Worker EXPECT_DEATH(
186*03ce13f7SAndroid Build Coastguard Worker {
187*03ce13f7SAndroid Build Coastguard Worker int result = routine();
188*03ce13f7SAndroid Build Coastguard Worker if(result == 0) abort();
189*03ce13f7SAndroid Build Coastguard Worker },
190*03ce13f7SAndroid Build Coastguard Worker "MemorySanitizer: use-of-uninitialized-value");
191*03ce13f7SAndroid Build Coastguard Worker }
192*03ce13f7SAndroid Build Coastguard Worker
193*03ce13f7SAndroid Build Coastguard Worker Pragma(MemorySanitizerInstrumentation, false);
194*03ce13f7SAndroid Build Coastguard Worker }
195*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Unreachable)196*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Unreachable)
197*03ce13f7SAndroid Build Coastguard Worker {
198*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
199*03ce13f7SAndroid Build Coastguard Worker {
200*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
201*03ce13f7SAndroid Build Coastguard Worker Int z = 4;
202*03ce13f7SAndroid Build Coastguard Worker
203*03ce13f7SAndroid Build Coastguard Worker Return(a + z);
204*03ce13f7SAndroid Build Coastguard Worker
205*03ce13f7SAndroid Build Coastguard Worker // Code beyond this point is unreachable but should not cause any
206*03ce13f7SAndroid Build Coastguard Worker // compilation issues.
207*03ce13f7SAndroid Build Coastguard Worker
208*03ce13f7SAndroid Build Coastguard Worker z += a;
209*03ce13f7SAndroid Build Coastguard Worker }
210*03ce13f7SAndroid Build Coastguard Worker
211*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
212*03ce13f7SAndroid Build Coastguard Worker
213*03ce13f7SAndroid Build Coastguard Worker int result = routine(16);
214*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 20);
215*03ce13f7SAndroid Build Coastguard Worker }
216*03ce13f7SAndroid Build Coastguard Worker
217*03ce13f7SAndroid Build Coastguard Worker // Stopping in the middle of a `Function<>` is supported and should not affect
218*03ce13f7SAndroid Build Coastguard Worker // subsequent complete ones.
TEST(ReactorUnitTests,UnfinishedFunction)219*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, UnfinishedFunction)
220*03ce13f7SAndroid Build Coastguard Worker {
221*03ce13f7SAndroid Build Coastguard Worker do
222*03ce13f7SAndroid Build Coastguard Worker {
223*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
224*03ce13f7SAndroid Build Coastguard Worker {
225*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
226*03ce13f7SAndroid Build Coastguard Worker Int z = 4;
227*03ce13f7SAndroid Build Coastguard Worker
228*03ce13f7SAndroid Build Coastguard Worker if((true)) break; // Terminate do-while early.
229*03ce13f7SAndroid Build Coastguard Worker
230*03ce13f7SAndroid Build Coastguard Worker Return(a + z);
231*03ce13f7SAndroid Build Coastguard Worker }
232*03ce13f7SAndroid Build Coastguard Worker } while(true);
233*03ce13f7SAndroid Build Coastguard Worker
234*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
235*03ce13f7SAndroid Build Coastguard Worker {
236*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
237*03ce13f7SAndroid Build Coastguard Worker Int z = 4;
238*03ce13f7SAndroid Build Coastguard Worker
239*03ce13f7SAndroid Build Coastguard Worker Return(a - z);
240*03ce13f7SAndroid Build Coastguard Worker }
241*03ce13f7SAndroid Build Coastguard Worker
242*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
243*03ce13f7SAndroid Build Coastguard Worker
244*03ce13f7SAndroid Build Coastguard Worker int result = routine(16);
245*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 12);
246*03ce13f7SAndroid Build Coastguard Worker }
247*03ce13f7SAndroid Build Coastguard Worker
248*03ce13f7SAndroid Build Coastguard Worker // Deriving from `Function<>` and using Reactor variables as members can be a
249*03ce13f7SAndroid Build Coastguard Worker // convenient way to 'name' function arguments and compose complex functions
250*03ce13f7SAndroid Build Coastguard Worker // with helper methods. This test checks the interactions between the lifetime
251*03ce13f7SAndroid Build Coastguard Worker // of the `Function<>` and the variables belonging to the derived class.
252*03ce13f7SAndroid Build Coastguard Worker struct FunctionMembers : FunctionT<int(int)>
253*03ce13f7SAndroid Build Coastguard Worker {
FunctionMembersFunctionMembers254*03ce13f7SAndroid Build Coastguard Worker FunctionMembers()
255*03ce13f7SAndroid Build Coastguard Worker : level(Arg<0>())
256*03ce13f7SAndroid Build Coastguard Worker {
257*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < 3, i++)
258*03ce13f7SAndroid Build Coastguard Worker {
259*03ce13f7SAndroid Build Coastguard Worker pourSomeMore();
260*03ce13f7SAndroid Build Coastguard Worker }
261*03ce13f7SAndroid Build Coastguard Worker
262*03ce13f7SAndroid Build Coastguard Worker Return(level);
263*03ce13f7SAndroid Build Coastguard Worker }
264*03ce13f7SAndroid Build Coastguard Worker
pourSomeMoreFunctionMembers265*03ce13f7SAndroid Build Coastguard Worker void pourSomeMore()
266*03ce13f7SAndroid Build Coastguard Worker {
267*03ce13f7SAndroid Build Coastguard Worker level += 2;
268*03ce13f7SAndroid Build Coastguard Worker }
269*03ce13f7SAndroid Build Coastguard Worker
270*03ce13f7SAndroid Build Coastguard Worker Int level;
271*03ce13f7SAndroid Build Coastguard Worker };
272*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,FunctionMembers)273*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, FunctionMembers)
274*03ce13f7SAndroid Build Coastguard Worker {
275*03ce13f7SAndroid Build Coastguard Worker FunctionMembers function;
276*03ce13f7SAndroid Build Coastguard Worker
277*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
278*03ce13f7SAndroid Build Coastguard Worker
279*03ce13f7SAndroid Build Coastguard Worker int result = routine(3);
280*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 9);
281*03ce13f7SAndroid Build Coastguard Worker }
282*03ce13f7SAndroid Build Coastguard Worker
283*03ce13f7SAndroid Build Coastguard Worker // This test excercises modifying the value of a local variable through a
284*03ce13f7SAndroid Build Coastguard Worker // pointer to it.
TEST(ReactorUnitTests,VariableAddress)285*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, VariableAddress)
286*03ce13f7SAndroid Build Coastguard Worker {
287*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
288*03ce13f7SAndroid Build Coastguard Worker {
289*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
290*03ce13f7SAndroid Build Coastguard Worker Int z = 0;
291*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p = &z;
292*03ce13f7SAndroid Build Coastguard Worker *p = 4;
293*03ce13f7SAndroid Build Coastguard Worker
294*03ce13f7SAndroid Build Coastguard Worker Return(a + z);
295*03ce13f7SAndroid Build Coastguard Worker }
296*03ce13f7SAndroid Build Coastguard Worker
297*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
298*03ce13f7SAndroid Build Coastguard Worker
299*03ce13f7SAndroid Build Coastguard Worker int result = routine(16);
300*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 20);
301*03ce13f7SAndroid Build Coastguard Worker }
302*03ce13f7SAndroid Build Coastguard Worker
303*03ce13f7SAndroid Build Coastguard Worker // This test exercises taking the address of a local varible at the end of a
304*03ce13f7SAndroid Build Coastguard Worker // loop and modifying its value through the pointer in the second iteration.
TEST(ReactorUnitTests,LateVariableAddress)305*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, LateVariableAddress)
306*03ce13f7SAndroid Build Coastguard Worker {
307*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void)> function;
308*03ce13f7SAndroid Build Coastguard Worker {
309*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p = nullptr;
310*03ce13f7SAndroid Build Coastguard Worker Int a = 0;
311*03ce13f7SAndroid Build Coastguard Worker
312*03ce13f7SAndroid Build Coastguard Worker While(a == 0)
313*03ce13f7SAndroid Build Coastguard Worker {
314*03ce13f7SAndroid Build Coastguard Worker If(p != Pointer<Int>(nullptr))
315*03ce13f7SAndroid Build Coastguard Worker {
316*03ce13f7SAndroid Build Coastguard Worker *p = 1;
317*03ce13f7SAndroid Build Coastguard Worker }
318*03ce13f7SAndroid Build Coastguard Worker
319*03ce13f7SAndroid Build Coastguard Worker p = &a;
320*03ce13f7SAndroid Build Coastguard Worker }
321*03ce13f7SAndroid Build Coastguard Worker
322*03ce13f7SAndroid Build Coastguard Worker Return(a);
323*03ce13f7SAndroid Build Coastguard Worker }
324*03ce13f7SAndroid Build Coastguard Worker
325*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
326*03ce13f7SAndroid Build Coastguard Worker
327*03ce13f7SAndroid Build Coastguard Worker int result = routine();
328*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 1);
329*03ce13f7SAndroid Build Coastguard Worker }
330*03ce13f7SAndroid Build Coastguard Worker
331*03ce13f7SAndroid Build Coastguard Worker // This test checks that the value of a local variable which has been modified
332*03ce13f7SAndroid Build Coastguard Worker // though a pointer is correct at the point before its address is (statically)
333*03ce13f7SAndroid Build Coastguard Worker // obtained.
TEST(ReactorUnitTests,LoadAfterIndirectStore)334*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, LoadAfterIndirectStore)
335*03ce13f7SAndroid Build Coastguard Worker {
336*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void)> function;
337*03ce13f7SAndroid Build Coastguard Worker {
338*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p = nullptr;
339*03ce13f7SAndroid Build Coastguard Worker Int a = 0;
340*03ce13f7SAndroid Build Coastguard Worker Int b = 0;
341*03ce13f7SAndroid Build Coastguard Worker
342*03ce13f7SAndroid Build Coastguard Worker While(a == 0)
343*03ce13f7SAndroid Build Coastguard Worker {
344*03ce13f7SAndroid Build Coastguard Worker If(p != Pointer<Int>(nullptr))
345*03ce13f7SAndroid Build Coastguard Worker {
346*03ce13f7SAndroid Build Coastguard Worker *p = 1;
347*03ce13f7SAndroid Build Coastguard Worker }
348*03ce13f7SAndroid Build Coastguard Worker
349*03ce13f7SAndroid Build Coastguard Worker // `a` must be loaded from memory here, despite not statically knowing
350*03ce13f7SAndroid Build Coastguard Worker // yet that its address will be taken below.
351*03ce13f7SAndroid Build Coastguard Worker b = a + 5;
352*03ce13f7SAndroid Build Coastguard Worker
353*03ce13f7SAndroid Build Coastguard Worker p = &a;
354*03ce13f7SAndroid Build Coastguard Worker }
355*03ce13f7SAndroid Build Coastguard Worker
356*03ce13f7SAndroid Build Coastguard Worker Return(b);
357*03ce13f7SAndroid Build Coastguard Worker }
358*03ce13f7SAndroid Build Coastguard Worker
359*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
360*03ce13f7SAndroid Build Coastguard Worker
361*03ce13f7SAndroid Build Coastguard Worker int result = routine();
362*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 6);
363*03ce13f7SAndroid Build Coastguard Worker }
364*03ce13f7SAndroid Build Coastguard Worker
365*03ce13f7SAndroid Build Coastguard Worker // This test checks that variables statically accessed after a Return statement
366*03ce13f7SAndroid Build Coastguard Worker // are still loaded, modified, and stored correctly.
TEST(ReactorUnitTests,LoopAfterReturn)367*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, LoopAfterReturn)
368*03ce13f7SAndroid Build Coastguard Worker {
369*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void)> function;
370*03ce13f7SAndroid Build Coastguard Worker {
371*03ce13f7SAndroid Build Coastguard Worker Int min = 100;
372*03ce13f7SAndroid Build Coastguard Worker Int max = 200;
373*03ce13f7SAndroid Build Coastguard Worker
374*03ce13f7SAndroid Build Coastguard Worker If(min > max)
375*03ce13f7SAndroid Build Coastguard Worker {
376*03ce13f7SAndroid Build Coastguard Worker Return(5);
377*03ce13f7SAndroid Build Coastguard Worker }
378*03ce13f7SAndroid Build Coastguard Worker
379*03ce13f7SAndroid Build Coastguard Worker While(min < max)
380*03ce13f7SAndroid Build Coastguard Worker {
381*03ce13f7SAndroid Build Coastguard Worker min++;
382*03ce13f7SAndroid Build Coastguard Worker }
383*03ce13f7SAndroid Build Coastguard Worker
384*03ce13f7SAndroid Build Coastguard Worker Return(7);
385*03ce13f7SAndroid Build Coastguard Worker }
386*03ce13f7SAndroid Build Coastguard Worker
387*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
388*03ce13f7SAndroid Build Coastguard Worker
389*03ce13f7SAndroid Build Coastguard Worker int result = routine();
390*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 7);
391*03ce13f7SAndroid Build Coastguard Worker }
392*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ConstantPointer)393*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ConstantPointer)
394*03ce13f7SAndroid Build Coastguard Worker {
395*03ce13f7SAndroid Build Coastguard Worker int c = 44;
396*03ce13f7SAndroid Build Coastguard Worker
397*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
398*03ce13f7SAndroid Build Coastguard Worker {
399*03ce13f7SAndroid Build Coastguard Worker Int x = *Pointer<Int>(ConstantPointer(&c));
400*03ce13f7SAndroid Build Coastguard Worker
401*03ce13f7SAndroid Build Coastguard Worker Return(x);
402*03ce13f7SAndroid Build Coastguard Worker }
403*03ce13f7SAndroid Build Coastguard Worker
404*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
405*03ce13f7SAndroid Build Coastguard Worker
406*03ce13f7SAndroid Build Coastguard Worker int result = routine();
407*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 44);
408*03ce13f7SAndroid Build Coastguard Worker }
409*03ce13f7SAndroid Build Coastguard Worker
410*03ce13f7SAndroid Build Coastguard Worker // This test excercises the Optimizer::eliminateLoadsFollowingSingleStore() optimization pass.
411*03ce13f7SAndroid Build Coastguard Worker // The three load operations for `y` should get eliminated.
TEST(ReactorUnitTests,EliminateLoadsFollowingSingleStore)412*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, EliminateLoadsFollowingSingleStore)
413*03ce13f7SAndroid Build Coastguard Worker {
414*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
415*03ce13f7SAndroid Build Coastguard Worker {
416*03ce13f7SAndroid Build Coastguard Worker Int x = function.Arg<0>();
417*03ce13f7SAndroid Build Coastguard Worker
418*03ce13f7SAndroid Build Coastguard Worker Int y;
419*03ce13f7SAndroid Build Coastguard Worker Int z;
420*03ce13f7SAndroid Build Coastguard Worker
421*03ce13f7SAndroid Build Coastguard Worker // This branch materializes the variables.
422*03ce13f7SAndroid Build Coastguard Worker If(x != 0) // TODO(b/179922668): Support If(x)
423*03ce13f7SAndroid Build Coastguard Worker {
424*03ce13f7SAndroid Build Coastguard Worker y = x;
425*03ce13f7SAndroid Build Coastguard Worker z = y + y + y;
426*03ce13f7SAndroid Build Coastguard Worker }
427*03ce13f7SAndroid Build Coastguard Worker
428*03ce13f7SAndroid Build Coastguard Worker Return(z);
429*03ce13f7SAndroid Build Coastguard Worker }
430*03ce13f7SAndroid Build Coastguard Worker
431*03ce13f7SAndroid Build Coastguard Worker Nucleus::setOptimizerCallback([](const Nucleus::OptimizerReport *report) {
432*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->allocas, 2);
433*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->loads, 2);
434*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->stores, 2);
435*03ce13f7SAndroid Build Coastguard Worker });
436*03ce13f7SAndroid Build Coastguard Worker
437*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
438*03ce13f7SAndroid Build Coastguard Worker
439*03ce13f7SAndroid Build Coastguard Worker int result = routine(11);
440*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 33);
441*03ce13f7SAndroid Build Coastguard Worker }
442*03ce13f7SAndroid Build Coastguard Worker
443*03ce13f7SAndroid Build Coastguard Worker // This test excercises the Optimizer::propagateAlloca() optimization pass.
444*03ce13f7SAndroid Build Coastguard Worker // The pointer variable should not get stored to / loaded from memory.
TEST(ReactorUnitTests,PropagateAlloca)445*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, PropagateAlloca)
446*03ce13f7SAndroid Build Coastguard Worker {
447*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
448*03ce13f7SAndroid Build Coastguard Worker {
449*03ce13f7SAndroid Build Coastguard Worker Int b = function.Arg<0>();
450*03ce13f7SAndroid Build Coastguard Worker
451*03ce13f7SAndroid Build Coastguard Worker Int a = 22;
452*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p;
453*03ce13f7SAndroid Build Coastguard Worker
454*03ce13f7SAndroid Build Coastguard Worker // This branch materializes both `a` and `p`, and ensures single basic block
455*03ce13f7SAndroid Build Coastguard Worker // optimizations don't also eliminate the pointer store and load.
456*03ce13f7SAndroid Build Coastguard Worker If(b != 0) // TODO(b/179922668): Support If(b)
457*03ce13f7SAndroid Build Coastguard Worker {
458*03ce13f7SAndroid Build Coastguard Worker p = &a;
459*03ce13f7SAndroid Build Coastguard Worker }
460*03ce13f7SAndroid Build Coastguard Worker
461*03ce13f7SAndroid Build Coastguard Worker Return(Int(*p)); // TODO(b/179694472): Support Return(*p)
462*03ce13f7SAndroid Build Coastguard Worker }
463*03ce13f7SAndroid Build Coastguard Worker
464*03ce13f7SAndroid Build Coastguard Worker Nucleus::setOptimizerCallback([](const Nucleus::OptimizerReport *report) {
465*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->allocas, 1);
466*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->loads, 1);
467*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->stores, 1);
468*03ce13f7SAndroid Build Coastguard Worker });
469*03ce13f7SAndroid Build Coastguard Worker
470*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
471*03ce13f7SAndroid Build Coastguard Worker
472*03ce13f7SAndroid Build Coastguard Worker int result = routine(true);
473*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 22);
474*03ce13f7SAndroid Build Coastguard Worker }
475*03ce13f7SAndroid Build Coastguard Worker
476*03ce13f7SAndroid Build Coastguard Worker // Corner case for Optimizer::propagateAlloca(). It should not replace loading of `p`
477*03ce13f7SAndroid Build Coastguard Worker // with the addres of `a`, since it also got the address of `b` assigned.
TEST(ReactorUnitTests,PointerToPointer)478*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, PointerToPointer)
479*03ce13f7SAndroid Build Coastguard Worker {
480*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
481*03ce13f7SAndroid Build Coastguard Worker {
482*03ce13f7SAndroid Build Coastguard Worker Int a = 444;
483*03ce13f7SAndroid Build Coastguard Worker Int b = 555;
484*03ce13f7SAndroid Build Coastguard Worker
485*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p = &a;
486*03ce13f7SAndroid Build Coastguard Worker Pointer<Pointer<Int>> pp = &p;
487*03ce13f7SAndroid Build Coastguard Worker p = &b;
488*03ce13f7SAndroid Build Coastguard Worker
489*03ce13f7SAndroid Build Coastguard Worker Return(Int(*Pointer<Int>(*pp))); // TODO(b/179694472): Support **pp
490*03ce13f7SAndroid Build Coastguard Worker }
491*03ce13f7SAndroid Build Coastguard Worker
492*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
493*03ce13f7SAndroid Build Coastguard Worker
494*03ce13f7SAndroid Build Coastguard Worker int result = routine();
495*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 555);
496*03ce13f7SAndroid Build Coastguard Worker }
497*03ce13f7SAndroid Build Coastguard Worker
498*03ce13f7SAndroid Build Coastguard Worker // Corner case for Optimizer::propagateAlloca(). It should not replace loading of `p[i]`
499*03ce13f7SAndroid Build Coastguard Worker // with any of the addresses of the `a`, `b`, or `c`.
TEST(ReactorUnitTests,ArrayOfPointersToLocals)500*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ArrayOfPointersToLocals)
501*03ce13f7SAndroid Build Coastguard Worker {
502*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
503*03ce13f7SAndroid Build Coastguard Worker {
504*03ce13f7SAndroid Build Coastguard Worker Int i = function.Arg<0>();
505*03ce13f7SAndroid Build Coastguard Worker
506*03ce13f7SAndroid Build Coastguard Worker Int a = 111;
507*03ce13f7SAndroid Build Coastguard Worker Int b = 222;
508*03ce13f7SAndroid Build Coastguard Worker Int c = 333;
509*03ce13f7SAndroid Build Coastguard Worker
510*03ce13f7SAndroid Build Coastguard Worker Array<Pointer<Int>, 3> p;
511*03ce13f7SAndroid Build Coastguard Worker p[0] = &a;
512*03ce13f7SAndroid Build Coastguard Worker p[1] = &b;
513*03ce13f7SAndroid Build Coastguard Worker p[2] = &c;
514*03ce13f7SAndroid Build Coastguard Worker
515*03ce13f7SAndroid Build Coastguard Worker Return(Int(*Pointer<Int>(p[i]))); // TODO(b/179694472): Support *p[i]
516*03ce13f7SAndroid Build Coastguard Worker }
517*03ce13f7SAndroid Build Coastguard Worker
518*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
519*03ce13f7SAndroid Build Coastguard Worker
520*03ce13f7SAndroid Build Coastguard Worker int result = routine(1);
521*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 222);
522*03ce13f7SAndroid Build Coastguard Worker }
523*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ModifyLocalThroughPointer)524*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ModifyLocalThroughPointer)
525*03ce13f7SAndroid Build Coastguard Worker {
526*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void)> function;
527*03ce13f7SAndroid Build Coastguard Worker {
528*03ce13f7SAndroid Build Coastguard Worker Int a = 1;
529*03ce13f7SAndroid Build Coastguard Worker
530*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p = &a;
531*03ce13f7SAndroid Build Coastguard Worker Pointer<Pointer<Int>> pp = &p;
532*03ce13f7SAndroid Build Coastguard Worker
533*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> q = *pp;
534*03ce13f7SAndroid Build Coastguard Worker *q = 3;
535*03ce13f7SAndroid Build Coastguard Worker
536*03ce13f7SAndroid Build Coastguard Worker Return(a);
537*03ce13f7SAndroid Build Coastguard Worker }
538*03ce13f7SAndroid Build Coastguard Worker
539*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
540*03ce13f7SAndroid Build Coastguard Worker
541*03ce13f7SAndroid Build Coastguard Worker int result = routine();
542*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 3);
543*03ce13f7SAndroid Build Coastguard Worker }
544*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ScalarReplacementOfArray)545*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ScalarReplacementOfArray)
546*03ce13f7SAndroid Build Coastguard Worker {
547*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void)> function;
548*03ce13f7SAndroid Build Coastguard Worker {
549*03ce13f7SAndroid Build Coastguard Worker Array<Int, 2> a;
550*03ce13f7SAndroid Build Coastguard Worker a[0] = 1;
551*03ce13f7SAndroid Build Coastguard Worker a[1] = 2;
552*03ce13f7SAndroid Build Coastguard Worker
553*03ce13f7SAndroid Build Coastguard Worker Return(a[0] + a[1]);
554*03ce13f7SAndroid Build Coastguard Worker }
555*03ce13f7SAndroid Build Coastguard Worker
556*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
557*03ce13f7SAndroid Build Coastguard Worker
558*03ce13f7SAndroid Build Coastguard Worker int result = routine();
559*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 3);
560*03ce13f7SAndroid Build Coastguard Worker }
561*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,CArray)562*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, CArray)
563*03ce13f7SAndroid Build Coastguard Worker {
564*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void)> function;
565*03ce13f7SAndroid Build Coastguard Worker {
566*03ce13f7SAndroid Build Coastguard Worker Int a[2];
567*03ce13f7SAndroid Build Coastguard Worker a[0] = 1;
568*03ce13f7SAndroid Build Coastguard Worker a[1] = 2;
569*03ce13f7SAndroid Build Coastguard Worker
570*03ce13f7SAndroid Build Coastguard Worker auto x = a[0];
571*03ce13f7SAndroid Build Coastguard Worker a[0] = a[1];
572*03ce13f7SAndroid Build Coastguard Worker a[1] = x;
573*03ce13f7SAndroid Build Coastguard Worker
574*03ce13f7SAndroid Build Coastguard Worker Return(a[0] + a[1]);
575*03ce13f7SAndroid Build Coastguard Worker }
576*03ce13f7SAndroid Build Coastguard Worker
577*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
578*03ce13f7SAndroid Build Coastguard Worker
579*03ce13f7SAndroid Build Coastguard Worker int result = routine();
580*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 3);
581*03ce13f7SAndroid Build Coastguard Worker }
582*03ce13f7SAndroid Build Coastguard Worker
583*03ce13f7SAndroid Build Coastguard Worker // SRoA should replace the array elements with scalars, which in turn enables
584*03ce13f7SAndroid Build Coastguard Worker // eliminating all loads and stores.
TEST(ReactorUnitTests,ReactorArray)585*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ReactorArray)
586*03ce13f7SAndroid Build Coastguard Worker {
587*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void)> function;
588*03ce13f7SAndroid Build Coastguard Worker {
589*03ce13f7SAndroid Build Coastguard Worker Array<Int, 2> a;
590*03ce13f7SAndroid Build Coastguard Worker a[0] = 1;
591*03ce13f7SAndroid Build Coastguard Worker a[1] = 2;
592*03ce13f7SAndroid Build Coastguard Worker
593*03ce13f7SAndroid Build Coastguard Worker Int x = a[0];
594*03ce13f7SAndroid Build Coastguard Worker a[0] = a[1];
595*03ce13f7SAndroid Build Coastguard Worker a[1] = x;
596*03ce13f7SAndroid Build Coastguard Worker
597*03ce13f7SAndroid Build Coastguard Worker Return(a[0] + a[1]);
598*03ce13f7SAndroid Build Coastguard Worker }
599*03ce13f7SAndroid Build Coastguard Worker
600*03ce13f7SAndroid Build Coastguard Worker Nucleus::setOptimizerCallback([](const Nucleus::OptimizerReport *report) {
601*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->allocas, 0);
602*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->loads, 0);
603*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->stores, 0);
604*03ce13f7SAndroid Build Coastguard Worker });
605*03ce13f7SAndroid Build Coastguard Worker
606*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
607*03ce13f7SAndroid Build Coastguard Worker
608*03ce13f7SAndroid Build Coastguard Worker int result = routine();
609*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 3);
610*03ce13f7SAndroid Build Coastguard Worker }
611*03ce13f7SAndroid Build Coastguard Worker
612*03ce13f7SAndroid Build Coastguard Worker // Excercises the optimizeSingleBasicBlockLoadsStores optimization pass.
TEST(ReactorUnitTests,StoresInMultipleBlocks)613*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, StoresInMultipleBlocks)
614*03ce13f7SAndroid Build Coastguard Worker {
615*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
616*03ce13f7SAndroid Build Coastguard Worker {
617*03ce13f7SAndroid Build Coastguard Worker Int b = function.Arg<0>();
618*03ce13f7SAndroid Build Coastguard Worker
619*03ce13f7SAndroid Build Coastguard Worker Int a = 13;
620*03ce13f7SAndroid Build Coastguard Worker
621*03ce13f7SAndroid Build Coastguard Worker If(b != 0) // TODO(b/179922668): Support If(b)
622*03ce13f7SAndroid Build Coastguard Worker {
623*03ce13f7SAndroid Build Coastguard Worker a = 4;
624*03ce13f7SAndroid Build Coastguard Worker a = a + 3;
625*03ce13f7SAndroid Build Coastguard Worker }
626*03ce13f7SAndroid Build Coastguard Worker Else
627*03ce13f7SAndroid Build Coastguard Worker {
628*03ce13f7SAndroid Build Coastguard Worker a = 6;
629*03ce13f7SAndroid Build Coastguard Worker a = a + 5;
630*03ce13f7SAndroid Build Coastguard Worker }
631*03ce13f7SAndroid Build Coastguard Worker
632*03ce13f7SAndroid Build Coastguard Worker Return(a);
633*03ce13f7SAndroid Build Coastguard Worker }
634*03ce13f7SAndroid Build Coastguard Worker
635*03ce13f7SAndroid Build Coastguard Worker Nucleus::setOptimizerCallback([](const Nucleus::OptimizerReport *report) {
636*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->allocas, 1);
637*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->loads, 1);
638*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(report->stores, 3);
639*03ce13f7SAndroid Build Coastguard Worker });
640*03ce13f7SAndroid Build Coastguard Worker
641*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
642*03ce13f7SAndroid Build Coastguard Worker
643*03ce13f7SAndroid Build Coastguard Worker int result = routine(true);
644*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 7);
645*03ce13f7SAndroid Build Coastguard Worker }
646*03ce13f7SAndroid Build Coastguard Worker
647*03ce13f7SAndroid Build Coastguard Worker // This is similar to the LoadAfterIndirectStore test except that the indirect
648*03ce13f7SAndroid Build Coastguard Worker // store is preceded by a direct store. The subsequent load should not be replaced
649*03ce13f7SAndroid Build Coastguard Worker // by the value written by the direct store.
TEST(ReactorUnitTests,StoreBeforeIndirectStore)650*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, StoreBeforeIndirectStore)
651*03ce13f7SAndroid Build Coastguard Worker {
652*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
653*03ce13f7SAndroid Build Coastguard Worker {
654*03ce13f7SAndroid Build Coastguard Worker // Int b = function.Arg<0>();
655*03ce13f7SAndroid Build Coastguard Worker
656*03ce13f7SAndroid Build Coastguard Worker Int b;
657*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p = &b;
658*03ce13f7SAndroid Build Coastguard Worker Int a = 13;
659*03ce13f7SAndroid Build Coastguard Worker
660*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < 2, i++)
661*03ce13f7SAndroid Build Coastguard Worker {
662*03ce13f7SAndroid Build Coastguard Worker a = 10;
663*03ce13f7SAndroid Build Coastguard Worker
664*03ce13f7SAndroid Build Coastguard Worker *p = 4;
665*03ce13f7SAndroid Build Coastguard Worker
666*03ce13f7SAndroid Build Coastguard Worker // This load of `a` should not be replaced by the 10 written above, since
667*03ce13f7SAndroid Build Coastguard Worker // in the second iteration `p` points to `a` and writes 4.
668*03ce13f7SAndroid Build Coastguard Worker b = a;
669*03ce13f7SAndroid Build Coastguard Worker
670*03ce13f7SAndroid Build Coastguard Worker p = &a;
671*03ce13f7SAndroid Build Coastguard Worker }
672*03ce13f7SAndroid Build Coastguard Worker
673*03ce13f7SAndroid Build Coastguard Worker Return(b);
674*03ce13f7SAndroid Build Coastguard Worker }
675*03ce13f7SAndroid Build Coastguard Worker
676*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
677*03ce13f7SAndroid Build Coastguard Worker
678*03ce13f7SAndroid Build Coastguard Worker int result = routine(true);
679*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 4);
680*03ce13f7SAndroid Build Coastguard Worker }
681*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,AssertTrue)682*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, AssertTrue)
683*03ce13f7SAndroid Build Coastguard Worker {
684*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
685*03ce13f7SAndroid Build Coastguard Worker {
686*03ce13f7SAndroid Build Coastguard Worker Int a = 3;
687*03ce13f7SAndroid Build Coastguard Worker Int b = 5;
688*03ce13f7SAndroid Build Coastguard Worker
689*03ce13f7SAndroid Build Coastguard Worker Assert(a < b);
690*03ce13f7SAndroid Build Coastguard Worker
691*03ce13f7SAndroid Build Coastguard Worker Return(a + b);
692*03ce13f7SAndroid Build Coastguard Worker }
693*03ce13f7SAndroid Build Coastguard Worker
694*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
695*03ce13f7SAndroid Build Coastguard Worker
696*03ce13f7SAndroid Build Coastguard Worker int result = routine();
697*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 8);
698*03ce13f7SAndroid Build Coastguard Worker }
699*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,AssertFalse)700*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, AssertFalse)
701*03ce13f7SAndroid Build Coastguard Worker {
702*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
703*03ce13f7SAndroid Build Coastguard Worker {
704*03ce13f7SAndroid Build Coastguard Worker Int a = 3;
705*03ce13f7SAndroid Build Coastguard Worker Int b = 5;
706*03ce13f7SAndroid Build Coastguard Worker
707*03ce13f7SAndroid Build Coastguard Worker Assert(a == b);
708*03ce13f7SAndroid Build Coastguard Worker
709*03ce13f7SAndroid Build Coastguard Worker Return(a + b);
710*03ce13f7SAndroid Build Coastguard Worker }
711*03ce13f7SAndroid Build Coastguard Worker
712*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
713*03ce13f7SAndroid Build Coastguard Worker
714*03ce13f7SAndroid Build Coastguard Worker #ifndef NDEBUG
715*03ce13f7SAndroid Build Coastguard Worker # if !defined(__APPLE__)
716*03ce13f7SAndroid Build Coastguard Worker const char *stderrRegex = "AssertFalse"; // stderr should contain the assert's expression, file:line, and function
717*03ce13f7SAndroid Build Coastguard Worker # else
718*03ce13f7SAndroid Build Coastguard Worker const char *stderrRegex = ""; // TODO(b/156389924): On macOS an stderr redirect can cause googletest to fail the capture
719*03ce13f7SAndroid Build Coastguard Worker # endif
720*03ce13f7SAndroid Build Coastguard Worker
721*03ce13f7SAndroid Build Coastguard Worker EXPECT_DEATH(
722*03ce13f7SAndroid Build Coastguard Worker {
723*03ce13f7SAndroid Build Coastguard Worker int result = routine();
724*03ce13f7SAndroid Build Coastguard Worker EXPECT_NE(result, result); // We should never reach this
725*03ce13f7SAndroid Build Coastguard Worker },
726*03ce13f7SAndroid Build Coastguard Worker stderrRegex);
727*03ce13f7SAndroid Build Coastguard Worker #else
728*03ce13f7SAndroid Build Coastguard Worker int result = routine();
729*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 8);
730*03ce13f7SAndroid Build Coastguard Worker #endif
731*03ce13f7SAndroid Build Coastguard Worker }
732*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,SubVectorLoadStore)733*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, SubVectorLoadStore)
734*03ce13f7SAndroid Build Coastguard Worker {
735*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *, void *)> function;
736*03ce13f7SAndroid Build Coastguard Worker {
737*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> in = function.Arg<0>();
738*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<1>();
739*03ce13f7SAndroid Build Coastguard Worker
740*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 0) = *Pointer<Int4>(in + 16 * 0);
741*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * 1) = *Pointer<Short4>(in + 16 * 1);
742*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte8>(out + 16 * 2) = *Pointer<Byte8>(in + 16 * 2);
743*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte4>(out + 16 * 3) = *Pointer<Byte4>(in + 16 * 3);
744*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short2>(out + 16 * 4) = *Pointer<Short2>(in + 16 * 4);
745*03ce13f7SAndroid Build Coastguard Worker
746*03ce13f7SAndroid Build Coastguard Worker Return(0);
747*03ce13f7SAndroid Build Coastguard Worker }
748*03ce13f7SAndroid Build Coastguard Worker
749*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
750*03ce13f7SAndroid Build Coastguard Worker
751*03ce13f7SAndroid Build Coastguard Worker int8_t in[16 * 5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
752*03ce13f7SAndroid Build Coastguard Worker 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0,
753*03ce13f7SAndroid Build Coastguard Worker 25, 26, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0,
754*03ce13f7SAndroid Build Coastguard Worker 33, 34, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
755*03ce13f7SAndroid Build Coastguard Worker 37, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
756*03ce13f7SAndroid Build Coastguard Worker
757*03ce13f7SAndroid Build Coastguard Worker int8_t out[16 * 5] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
758*03ce13f7SAndroid Build Coastguard Worker -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
759*03ce13f7SAndroid Build Coastguard Worker -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
760*03ce13f7SAndroid Build Coastguard Worker -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
761*03ce13f7SAndroid Build Coastguard Worker -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
762*03ce13f7SAndroid Build Coastguard Worker
763*03ce13f7SAndroid Build Coastguard Worker routine(in, out);
764*03ce13f7SAndroid Build Coastguard Worker
765*03ce13f7SAndroid Build Coastguard Worker for(int row = 0; row < 5; row++)
766*03ce13f7SAndroid Build Coastguard Worker {
767*03ce13f7SAndroid Build Coastguard Worker for(int col = 0; col < 16; col++)
768*03ce13f7SAndroid Build Coastguard Worker {
769*03ce13f7SAndroid Build Coastguard Worker int i = row * 16 + col;
770*03ce13f7SAndroid Build Coastguard Worker
771*03ce13f7SAndroid Build Coastguard Worker if(in[i] == 0)
772*03ce13f7SAndroid Build Coastguard Worker {
773*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[i], -1) << "Row " << row << " column " << col << " not left untouched.";
774*03ce13f7SAndroid Build Coastguard Worker }
775*03ce13f7SAndroid Build Coastguard Worker else
776*03ce13f7SAndroid Build Coastguard Worker {
777*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[i], in[i]) << "Row " << row << " column " << col << " not equal to input.";
778*03ce13f7SAndroid Build Coastguard Worker }
779*03ce13f7SAndroid Build Coastguard Worker }
780*03ce13f7SAndroid Build Coastguard Worker }
781*03ce13f7SAndroid Build Coastguard Worker }
782*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,VectorConstant)783*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, VectorConstant)
784*03ce13f7SAndroid Build Coastguard Worker {
785*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
786*03ce13f7SAndroid Build Coastguard Worker {
787*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
788*03ce13f7SAndroid Build Coastguard Worker
789*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 0) = Int4(0x04030201, 0x08070605, 0x0C0B0A09, 0x100F0E0D);
790*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * 1) = Short4(0x1211, 0x1413, 0x1615, 0x1817);
791*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte8>(out + 16 * 2) = Byte8(0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20);
792*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int2>(out + 16 * 3) = Int2(0x24232221, 0x28272625);
793*03ce13f7SAndroid Build Coastguard Worker
794*03ce13f7SAndroid Build Coastguard Worker Return(0);
795*03ce13f7SAndroid Build Coastguard Worker }
796*03ce13f7SAndroid Build Coastguard Worker
797*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
798*03ce13f7SAndroid Build Coastguard Worker
799*03ce13f7SAndroid Build Coastguard Worker int8_t out[16 * 4] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
800*03ce13f7SAndroid Build Coastguard Worker -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
801*03ce13f7SAndroid Build Coastguard Worker -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
802*03ce13f7SAndroid Build Coastguard Worker -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
803*03ce13f7SAndroid Build Coastguard Worker
804*03ce13f7SAndroid Build Coastguard Worker int8_t exp[16 * 4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
805*03ce13f7SAndroid Build Coastguard Worker 17, 18, 19, 20, 21, 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, -1,
806*03ce13f7SAndroid Build Coastguard Worker 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, -1,
807*03ce13f7SAndroid Build Coastguard Worker 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, -1, -1 };
808*03ce13f7SAndroid Build Coastguard Worker
809*03ce13f7SAndroid Build Coastguard Worker routine(out);
810*03ce13f7SAndroid Build Coastguard Worker
811*03ce13f7SAndroid Build Coastguard Worker for(int row = 0; row < 4; row++)
812*03ce13f7SAndroid Build Coastguard Worker {
813*03ce13f7SAndroid Build Coastguard Worker for(int col = 0; col < 16; col++)
814*03ce13f7SAndroid Build Coastguard Worker {
815*03ce13f7SAndroid Build Coastguard Worker int i = row * 16 + col;
816*03ce13f7SAndroid Build Coastguard Worker
817*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[i], exp[i]);
818*03ce13f7SAndroid Build Coastguard Worker }
819*03ce13f7SAndroid Build Coastguard Worker }
820*03ce13f7SAndroid Build Coastguard Worker }
821*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Concatenate)822*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Concatenate)
823*03ce13f7SAndroid Build Coastguard Worker {
824*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
825*03ce13f7SAndroid Build Coastguard Worker {
826*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
827*03ce13f7SAndroid Build Coastguard Worker
828*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 0) = Int4(Int2(0x04030201, 0x08070605), Int2(0x0C0B0A09, 0x100F0E0D));
829*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short8>(out + 16 * 1) = Short8(Short4(0x0201, 0x0403, 0x0605, 0x0807), Short4(0x0A09, 0x0C0B, 0x0E0D, 0x100F));
830*03ce13f7SAndroid Build Coastguard Worker
831*03ce13f7SAndroid Build Coastguard Worker Return(0);
832*03ce13f7SAndroid Build Coastguard Worker }
833*03ce13f7SAndroid Build Coastguard Worker
834*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
835*03ce13f7SAndroid Build Coastguard Worker
836*03ce13f7SAndroid Build Coastguard Worker int8_t ref[16 * 5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
837*03ce13f7SAndroid Build Coastguard Worker 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
838*03ce13f7SAndroid Build Coastguard Worker
839*03ce13f7SAndroid Build Coastguard Worker int8_t out[16 * 5] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
840*03ce13f7SAndroid Build Coastguard Worker -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
841*03ce13f7SAndroid Build Coastguard Worker
842*03ce13f7SAndroid Build Coastguard Worker routine(out);
843*03ce13f7SAndroid Build Coastguard Worker
844*03ce13f7SAndroid Build Coastguard Worker for(int row = 0; row < 2; row++)
845*03ce13f7SAndroid Build Coastguard Worker {
846*03ce13f7SAndroid Build Coastguard Worker for(int col = 0; col < 16; col++)
847*03ce13f7SAndroid Build Coastguard Worker {
848*03ce13f7SAndroid Build Coastguard Worker int i = row * 16 + col;
849*03ce13f7SAndroid Build Coastguard Worker
850*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[i], ref[i]) << "Row " << row << " column " << col << " not equal to reference.";
851*03ce13f7SAndroid Build Coastguard Worker }
852*03ce13f7SAndroid Build Coastguard Worker }
853*03ce13f7SAndroid Build Coastguard Worker }
854*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Cast)855*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Cast)
856*03ce13f7SAndroid Build Coastguard Worker {
857*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(void *)> function;
858*03ce13f7SAndroid Build Coastguard Worker {
859*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
860*03ce13f7SAndroid Build Coastguard Worker
861*03ce13f7SAndroid Build Coastguard Worker Int4 c = Int4(0x01020304, 0x05060708, 0x09101112, 0x13141516);
862*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * 0) = Short4(c);
863*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte4>(out + 16 * 1 + 0) = Byte4(c);
864*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte4>(out + 16 * 1 + 4) = Byte4(As<Byte8>(c));
865*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte4>(out + 16 * 1 + 8) = Byte4(As<Short4>(c));
866*03ce13f7SAndroid Build Coastguard Worker }
867*03ce13f7SAndroid Build Coastguard Worker
868*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
869*03ce13f7SAndroid Build Coastguard Worker
870*03ce13f7SAndroid Build Coastguard Worker int out[2][4];
871*03ce13f7SAndroid Build Coastguard Worker
872*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
873*03ce13f7SAndroid Build Coastguard Worker
874*03ce13f7SAndroid Build Coastguard Worker routine(&out);
875*03ce13f7SAndroid Build Coastguard Worker
876*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0x07080304);
877*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0x15161112);
878*03ce13f7SAndroid Build Coastguard Worker
879*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0x16120804);
880*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0x01020304);
881*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][2], 0x06080204);
882*03ce13f7SAndroid Build Coastguard Worker }
883*03ce13f7SAndroid Build Coastguard Worker
swizzleCode4(int i)884*03ce13f7SAndroid Build Coastguard Worker static uint16_t swizzleCode4(int i)
885*03ce13f7SAndroid Build Coastguard Worker {
886*03ce13f7SAndroid Build Coastguard Worker auto x = (i >> 0) & 0x03;
887*03ce13f7SAndroid Build Coastguard Worker auto y = (i >> 2) & 0x03;
888*03ce13f7SAndroid Build Coastguard Worker auto z = (i >> 4) & 0x03;
889*03ce13f7SAndroid Build Coastguard Worker auto w = (i >> 6) & 0x03;
890*03ce13f7SAndroid Build Coastguard Worker return static_cast<uint16_t>((x << 12) | (y << 8) | (z << 4) | (w << 0));
891*03ce13f7SAndroid Build Coastguard Worker }
892*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Swizzle4)893*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Swizzle4)
894*03ce13f7SAndroid Build Coastguard Worker {
895*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(void *)> function;
896*03ce13f7SAndroid Build Coastguard Worker {
897*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
898*03ce13f7SAndroid Build Coastguard Worker
899*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 256; i++)
900*03ce13f7SAndroid Build Coastguard Worker {
901*03ce13f7SAndroid Build Coastguard Worker *Pointer<Float4>(out + 16 * i) = Swizzle(Float4(1.0f, 2.0f, 3.0f, 4.0f), swizzleCode4(i));
902*03ce13f7SAndroid Build Coastguard Worker }
903*03ce13f7SAndroid Build Coastguard Worker
904*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 256; i++)
905*03ce13f7SAndroid Build Coastguard Worker {
906*03ce13f7SAndroid Build Coastguard Worker *Pointer<Float4>(out + 16 * (256 + i)) = ShuffleLowHigh(Float4(1.0f, 2.0f, 3.0f, 4.0f), Float4(5.0f, 6.0f, 7.0f, 8.0f), swizzleCode4(i));
907*03ce13f7SAndroid Build Coastguard Worker }
908*03ce13f7SAndroid Build Coastguard Worker
909*03ce13f7SAndroid Build Coastguard Worker *Pointer<Float4>(out + 16 * (512 + 0)) = UnpackLow(Float4(1.0f, 2.0f, 3.0f, 4.0f), Float4(5.0f, 6.0f, 7.0f, 8.0f));
910*03ce13f7SAndroid Build Coastguard Worker *Pointer<Float4>(out + 16 * (512 + 1)) = UnpackHigh(Float4(1.0f, 2.0f, 3.0f, 4.0f), Float4(5.0f, 6.0f, 7.0f, 8.0f));
911*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int2>(out + 16 * (512 + 2)) = UnpackLow(Short4(1, 2, 3, 4), Short4(5, 6, 7, 8));
912*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int2>(out + 16 * (512 + 3)) = UnpackHigh(Short4(1, 2, 3, 4), Short4(5, 6, 7, 8));
913*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * (512 + 4)) = UnpackLow(Byte8(1, 2, 3, 4, 5, 6, 7, 8), Byte8(9, 10, 11, 12, 13, 14, 15, 16));
914*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * (512 + 5)) = UnpackHigh(Byte8(1, 2, 3, 4, 5, 6, 7, 8), Byte8(9, 10, 11, 12, 13, 14, 15, 16));
915*03ce13f7SAndroid Build Coastguard Worker
916*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 256; i++)
917*03ce13f7SAndroid Build Coastguard Worker {
918*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * (512 + 6) + (8 * i)) =
919*03ce13f7SAndroid Build Coastguard Worker Swizzle(Short4(1, 2, 3, 4), swizzleCode4(i));
920*03ce13f7SAndroid Build Coastguard Worker }
921*03ce13f7SAndroid Build Coastguard Worker
922*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 256; i++)
923*03ce13f7SAndroid Build Coastguard Worker {
924*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * (512 + 6 + i) + (8 * 256)) =
925*03ce13f7SAndroid Build Coastguard Worker Swizzle(Int4(1, 2, 3, 4), swizzleCode4(i));
926*03ce13f7SAndroid Build Coastguard Worker }
927*03ce13f7SAndroid Build Coastguard Worker }
928*03ce13f7SAndroid Build Coastguard Worker
929*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
930*03ce13f7SAndroid Build Coastguard Worker
931*03ce13f7SAndroid Build Coastguard Worker struct
932*03ce13f7SAndroid Build Coastguard Worker {
933*03ce13f7SAndroid Build Coastguard Worker float f[256 + 256 + 2][4];
934*03ce13f7SAndroid Build Coastguard Worker int i[388][4];
935*03ce13f7SAndroid Build Coastguard Worker } out;
936*03ce13f7SAndroid Build Coastguard Worker
937*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
938*03ce13f7SAndroid Build Coastguard Worker
939*03ce13f7SAndroid Build Coastguard Worker routine(&out);
940*03ce13f7SAndroid Build Coastguard Worker
941*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 256; i++)
942*03ce13f7SAndroid Build Coastguard Worker {
943*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[i][0], float((i >> 0) & 0x03) + 1.0f);
944*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[i][1], float((i >> 2) & 0x03) + 1.0f);
945*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[i][2], float((i >> 4) & 0x03) + 1.0f);
946*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[i][3], float((i >> 6) & 0x03) + 1.0f);
947*03ce13f7SAndroid Build Coastguard Worker }
948*03ce13f7SAndroid Build Coastguard Worker
949*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 256; i++)
950*03ce13f7SAndroid Build Coastguard Worker {
951*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[256 + i][0], float((i >> 0) & 0x03) + 1.0f);
952*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[256 + i][1], float((i >> 2) & 0x03) + 1.0f);
953*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[256 + i][2], float((i >> 4) & 0x03) + 5.0f);
954*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[256 + i][3], float((i >> 6) & 0x03) + 5.0f);
955*03ce13f7SAndroid Build Coastguard Worker }
956*03ce13f7SAndroid Build Coastguard Worker
957*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[512 + 0][0], 1.0f);
958*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[512 + 0][1], 5.0f);
959*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[512 + 0][2], 2.0f);
960*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[512 + 0][3], 6.0f);
961*03ce13f7SAndroid Build Coastguard Worker
962*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[512 + 1][0], 3.0f);
963*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[512 + 1][1], 7.0f);
964*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[512 + 1][2], 4.0f);
965*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[512 + 1][3], 8.0f);
966*03ce13f7SAndroid Build Coastguard Worker
967*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[0][0], 0x00050001);
968*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[0][1], 0x00060002);
969*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[0][2], 0x00000000);
970*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[0][3], 0x00000000);
971*03ce13f7SAndroid Build Coastguard Worker
972*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[1][0], 0x00070003);
973*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[1][1], 0x00080004);
974*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[1][2], 0x00000000);
975*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[1][3], 0x00000000);
976*03ce13f7SAndroid Build Coastguard Worker
977*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[2][0], 0x0A020901);
978*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[2][1], 0x0C040B03);
979*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[2][2], 0x00000000);
980*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[2][3], 0x00000000);
981*03ce13f7SAndroid Build Coastguard Worker
982*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[3][0], 0x0E060D05);
983*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[3][1], 0x10080F07);
984*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[3][2], 0x00000000);
985*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[3][3], 0x00000000);
986*03ce13f7SAndroid Build Coastguard Worker
987*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 256; i++)
988*03ce13f7SAndroid Build Coastguard Worker {
989*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[4 + i / 2][0 + (i % 2) * 2] & 0xFFFF,
990*03ce13f7SAndroid Build Coastguard Worker ((i >> 0) & 0x03) + 1);
991*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[4 + i / 2][0 + (i % 2) * 2] >> 16,
992*03ce13f7SAndroid Build Coastguard Worker ((i >> 2) & 0x03) + 1);
993*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[4 + i / 2][1 + (i % 2) * 2] & 0xFFFF,
994*03ce13f7SAndroid Build Coastguard Worker ((i >> 4) & 0x03) + 1);
995*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[4 + i / 2][1 + (i % 2) * 2] >> 16,
996*03ce13f7SAndroid Build Coastguard Worker ((i >> 6) & 0x03) + 1);
997*03ce13f7SAndroid Build Coastguard Worker }
998*03ce13f7SAndroid Build Coastguard Worker
999*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 256; i++)
1000*03ce13f7SAndroid Build Coastguard Worker {
1001*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[132 + i][0], ((i >> 0) & 0x03) + 1);
1002*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[132 + i][1], ((i >> 2) & 0x03) + 1);
1003*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[132 + i][2], ((i >> 4) & 0x03) + 1);
1004*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[132 + i][3], ((i >> 6) & 0x03) + 1);
1005*03ce13f7SAndroid Build Coastguard Worker }
1006*03ce13f7SAndroid Build Coastguard Worker }
1007*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Swizzle)1008*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Swizzle)
1009*03ce13f7SAndroid Build Coastguard Worker {
1010*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(void *)> function;
1011*03ce13f7SAndroid Build Coastguard Worker {
1012*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1013*03ce13f7SAndroid Build Coastguard Worker
1014*03ce13f7SAndroid Build Coastguard Worker Int4 c = Int4(0x01020304, 0x05060708, 0x09101112, 0x13141516);
1015*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte16>(out + 16 * 0) = Swizzle(As<Byte16>(c), 0xFEDCBA9876543210ull);
1016*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte8>(out + 16 * 1) = Swizzle(As<Byte8>(c), 0x76543210u);
1017*03ce13f7SAndroid Build Coastguard Worker *Pointer<UShort8>(out + 16 * 2) = Swizzle(As<UShort8>(c), 0x76543210u);
1018*03ce13f7SAndroid Build Coastguard Worker }
1019*03ce13f7SAndroid Build Coastguard Worker
1020*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1021*03ce13f7SAndroid Build Coastguard Worker
1022*03ce13f7SAndroid Build Coastguard Worker int out[3][4];
1023*03ce13f7SAndroid Build Coastguard Worker
1024*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1025*03ce13f7SAndroid Build Coastguard Worker
1026*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1027*03ce13f7SAndroid Build Coastguard Worker
1028*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0x16151413);
1029*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0x12111009);
1030*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][2], 0x08070605);
1031*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][3], 0x04030201);
1032*03ce13f7SAndroid Build Coastguard Worker
1033*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0x08070605);
1034*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0x04030201);
1035*03ce13f7SAndroid Build Coastguard Worker
1036*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][0], 0x15161314);
1037*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][1], 0x11120910);
1038*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][2], 0x07080506);
1039*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][3], 0x03040102);
1040*03ce13f7SAndroid Build Coastguard Worker }
1041*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Shuffle)1042*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Shuffle)
1043*03ce13f7SAndroid Build Coastguard Worker {
1044*03ce13f7SAndroid Build Coastguard Worker // |select| is [0aaa:0bbb:0ccc:0ddd] where |aaa|, |bbb|, |ccc|
1045*03ce13f7SAndroid Build Coastguard Worker // and |ddd| are 7-bit selection indices. For a total (1 << 12)
1046*03ce13f7SAndroid Build Coastguard Worker // possibilities.
1047*03ce13f7SAndroid Build Coastguard Worker const int kSelectRange = 1 << 12;
1048*03ce13f7SAndroid Build Coastguard Worker
1049*03ce13f7SAndroid Build Coastguard Worker // Unfortunately, testing the whole kSelectRange results in a test
1050*03ce13f7SAndroid Build Coastguard Worker // that is far too slow to run, because LLVM spends exponentially more
1051*03ce13f7SAndroid Build Coastguard Worker // time optimizing the function below as the number of test cases
1052*03ce13f7SAndroid Build Coastguard Worker // increases.
1053*03ce13f7SAndroid Build Coastguard Worker //
1054*03ce13f7SAndroid Build Coastguard Worker // To work-around the problem, only test a subset of the range by
1055*03ce13f7SAndroid Build Coastguard Worker // skipping every kRangeIncrement value.
1056*03ce13f7SAndroid Build Coastguard Worker //
1057*03ce13f7SAndroid Build Coastguard Worker // Set this value to 1 if you want to test the whole implementation,
1058*03ce13f7SAndroid Build Coastguard Worker // which will take a little less than 2 minutes on a fast workstation.
1059*03ce13f7SAndroid Build Coastguard Worker //
1060*03ce13f7SAndroid Build Coastguard Worker // The default value here takes about 1390ms, which is a little more than
1061*03ce13f7SAndroid Build Coastguard Worker // what the Swizzle test takes (993 ms) on my machine. A non-power-of-2
1062*03ce13f7SAndroid Build Coastguard Worker // value ensures a better spread over possible values.
1063*03ce13f7SAndroid Build Coastguard Worker const int kRangeIncrement = 11;
1064*03ce13f7SAndroid Build Coastguard Worker
1065*03ce13f7SAndroid Build Coastguard Worker auto rangeIndexToSelect = [](int i) {
1066*03ce13f7SAndroid Build Coastguard Worker return static_cast<unsigned short>(
1067*03ce13f7SAndroid Build Coastguard Worker (((i >> 9) & 7) << 0) |
1068*03ce13f7SAndroid Build Coastguard Worker (((i >> 6) & 7) << 4) |
1069*03ce13f7SAndroid Build Coastguard Worker (((i >> 3) & 7) << 8) |
1070*03ce13f7SAndroid Build Coastguard Worker (((i >> 0) & 7) << 12));
1071*03ce13f7SAndroid Build Coastguard Worker };
1072*03ce13f7SAndroid Build Coastguard Worker
1073*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1074*03ce13f7SAndroid Build Coastguard Worker {
1075*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1076*03ce13f7SAndroid Build Coastguard Worker
1077*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < kSelectRange; i += kRangeIncrement)
1078*03ce13f7SAndroid Build Coastguard Worker {
1079*03ce13f7SAndroid Build Coastguard Worker unsigned short select = rangeIndexToSelect(i);
1080*03ce13f7SAndroid Build Coastguard Worker
1081*03ce13f7SAndroid Build Coastguard Worker *Pointer<Float4>(out + 16 * i) = Shuffle(Float4(1.0f, 2.0f, 3.0f, 4.0f),
1082*03ce13f7SAndroid Build Coastguard Worker Float4(5.0f, 6.0f, 7.0f, 8.0f),
1083*03ce13f7SAndroid Build Coastguard Worker select);
1084*03ce13f7SAndroid Build Coastguard Worker
1085*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + (kSelectRange + i) * 16) = Shuffle(Int4(10, 11, 12, 13),
1086*03ce13f7SAndroid Build Coastguard Worker Int4(14, 15, 16, 17),
1087*03ce13f7SAndroid Build Coastguard Worker select);
1088*03ce13f7SAndroid Build Coastguard Worker
1089*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt4>(out + (2 * kSelectRange + i) * 16) = Shuffle(UInt4(100, 101, 102, 103),
1090*03ce13f7SAndroid Build Coastguard Worker UInt4(104, 105, 106, 107),
1091*03ce13f7SAndroid Build Coastguard Worker select);
1092*03ce13f7SAndroid Build Coastguard Worker }
1093*03ce13f7SAndroid Build Coastguard Worker
1094*03ce13f7SAndroid Build Coastguard Worker Return(0);
1095*03ce13f7SAndroid Build Coastguard Worker }
1096*03ce13f7SAndroid Build Coastguard Worker
1097*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1098*03ce13f7SAndroid Build Coastguard Worker
1099*03ce13f7SAndroid Build Coastguard Worker struct
1100*03ce13f7SAndroid Build Coastguard Worker {
1101*03ce13f7SAndroid Build Coastguard Worker float f[kSelectRange][4];
1102*03ce13f7SAndroid Build Coastguard Worker int i[kSelectRange][4];
1103*03ce13f7SAndroid Build Coastguard Worker unsigned u[kSelectRange][4];
1104*03ce13f7SAndroid Build Coastguard Worker } out;
1105*03ce13f7SAndroid Build Coastguard Worker
1106*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1107*03ce13f7SAndroid Build Coastguard Worker
1108*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1109*03ce13f7SAndroid Build Coastguard Worker
1110*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < kSelectRange; i += kRangeIncrement)
1111*03ce13f7SAndroid Build Coastguard Worker {
1112*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[i][0], float(1.0f + (i & 7)));
1113*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[i][1], float(1.0f + ((i >> 3) & 7)));
1114*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[i][2], float(1.0f + ((i >> 6) & 7)));
1115*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.f[i][3], float(1.0f + ((i >> 9) & 7)));
1116*03ce13f7SAndroid Build Coastguard Worker }
1117*03ce13f7SAndroid Build Coastguard Worker
1118*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < kSelectRange; i += kRangeIncrement)
1119*03ce13f7SAndroid Build Coastguard Worker {
1120*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[i][0], int(10 + (i & 7)));
1121*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[i][1], int(10 + ((i >> 3) & 7)));
1122*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[i][2], int(10 + ((i >> 6) & 7)));
1123*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.i[i][3], int(10 + ((i >> 9) & 7)));
1124*03ce13f7SAndroid Build Coastguard Worker }
1125*03ce13f7SAndroid Build Coastguard Worker
1126*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < kSelectRange; i += kRangeIncrement)
1127*03ce13f7SAndroid Build Coastguard Worker {
1128*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.u[i][0], unsigned(100 + (i & 7)));
1129*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.u[i][1], unsigned(100 + ((i >> 3) & 7)));
1130*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.u[i][2], unsigned(100 + ((i >> 6) & 7)));
1131*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out.u[i][3], unsigned(100 + ((i >> 9) & 7)));
1132*03ce13f7SAndroid Build Coastguard Worker }
1133*03ce13f7SAndroid Build Coastguard Worker }
1134*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Broadcast)1135*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Broadcast)
1136*03ce13f7SAndroid Build Coastguard Worker {
1137*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
1138*03ce13f7SAndroid Build Coastguard Worker {
1139*03ce13f7SAndroid Build Coastguard Worker Int4 i = 2;
1140*03ce13f7SAndroid Build Coastguard Worker Int j = 3 + i.x;
1141*03ce13f7SAndroid Build Coastguard Worker Int4 k = i * 7;
1142*03ce13f7SAndroid Build Coastguard Worker
1143*03ce13f7SAndroid Build Coastguard Worker Return(k.z - j);
1144*03ce13f7SAndroid Build Coastguard Worker }
1145*03ce13f7SAndroid Build Coastguard Worker
1146*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1147*03ce13f7SAndroid Build Coastguard Worker
1148*03ce13f7SAndroid Build Coastguard Worker int result = routine();
1149*03ce13f7SAndroid Build Coastguard Worker
1150*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 9);
1151*03ce13f7SAndroid Build Coastguard Worker }
1152*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Branching)1153*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Branching)
1154*03ce13f7SAndroid Build Coastguard Worker {
1155*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
1156*03ce13f7SAndroid Build Coastguard Worker {
1157*03ce13f7SAndroid Build Coastguard Worker Int x = 0;
1158*03ce13f7SAndroid Build Coastguard Worker
1159*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < 8, i++)
1160*03ce13f7SAndroid Build Coastguard Worker {
1161*03ce13f7SAndroid Build Coastguard Worker If(i < 2)
1162*03ce13f7SAndroid Build Coastguard Worker {
1163*03ce13f7SAndroid Build Coastguard Worker x += 1;
1164*03ce13f7SAndroid Build Coastguard Worker }
1165*03ce13f7SAndroid Build Coastguard Worker Else If(i < 4)
1166*03ce13f7SAndroid Build Coastguard Worker {
1167*03ce13f7SAndroid Build Coastguard Worker x += 10;
1168*03ce13f7SAndroid Build Coastguard Worker }
1169*03ce13f7SAndroid Build Coastguard Worker Else If(i < 6)
1170*03ce13f7SAndroid Build Coastguard Worker {
1171*03ce13f7SAndroid Build Coastguard Worker x += 100;
1172*03ce13f7SAndroid Build Coastguard Worker }
1173*03ce13f7SAndroid Build Coastguard Worker Else
1174*03ce13f7SAndroid Build Coastguard Worker {
1175*03ce13f7SAndroid Build Coastguard Worker x += 1000;
1176*03ce13f7SAndroid Build Coastguard Worker }
1177*03ce13f7SAndroid Build Coastguard Worker
1178*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < 5, i++)
1179*03ce13f7SAndroid Build Coastguard Worker x += 10000;
1180*03ce13f7SAndroid Build Coastguard Worker }
1181*03ce13f7SAndroid Build Coastguard Worker
1182*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < 10, i++) for(int i = 0; i < 10; i++)
1183*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < 10, i++)
1184*03ce13f7SAndroid Build Coastguard Worker {
1185*03ce13f7SAndroid Build Coastguard Worker x += 1000000;
1186*03ce13f7SAndroid Build Coastguard Worker }
1187*03ce13f7SAndroid Build Coastguard Worker
1188*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < 2, i++)
1189*03ce13f7SAndroid Build Coastguard Worker If(x == 1000402222)
1190*03ce13f7SAndroid Build Coastguard Worker {
1191*03ce13f7SAndroid Build Coastguard Worker If(x != 1000402222)
1192*03ce13f7SAndroid Build Coastguard Worker x += 1000000000;
1193*03ce13f7SAndroid Build Coastguard Worker }
1194*03ce13f7SAndroid Build Coastguard Worker Else
1195*03ce13f7SAndroid Build Coastguard Worker x = -5;
1196*03ce13f7SAndroid Build Coastguard Worker
1197*03ce13f7SAndroid Build Coastguard Worker Return(x);
1198*03ce13f7SAndroid Build Coastguard Worker }
1199*03ce13f7SAndroid Build Coastguard Worker
1200*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1201*03ce13f7SAndroid Build Coastguard Worker
1202*03ce13f7SAndroid Build Coastguard Worker int result = routine();
1203*03ce13f7SAndroid Build Coastguard Worker
1204*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 1000402222);
1205*03ce13f7SAndroid Build Coastguard Worker }
1206*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,FMulAdd)1207*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, FMulAdd)
1208*03ce13f7SAndroid Build Coastguard Worker {
1209*03ce13f7SAndroid Build Coastguard Worker Function<Void(Pointer<Float4>, Pointer<Float4>, Pointer<Float4>, Pointer<Float4>)> function;
1210*03ce13f7SAndroid Build Coastguard Worker {
1211*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> r = function.Arg<0>();
1212*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> x = function.Arg<1>();
1213*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> y = function.Arg<2>();
1214*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> z = function.Arg<3>();
1215*03ce13f7SAndroid Build Coastguard Worker
1216*03ce13f7SAndroid Build Coastguard Worker *r = MulAdd(*x, *y, *z);
1217*03ce13f7SAndroid Build Coastguard Worker }
1218*03ce13f7SAndroid Build Coastguard Worker
1219*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1220*03ce13f7SAndroid Build Coastguard Worker auto callable = (void (*)(float4 *, float4 *, float4 *, float4 *))routine->getEntry();
1221*03ce13f7SAndroid Build Coastguard Worker
1222*03ce13f7SAndroid Build Coastguard Worker float x[] = { 0.0f, 2.0f, 4.0f, 1.00000011920929f };
1223*03ce13f7SAndroid Build Coastguard Worker float y[] = { 0.0f, 3.0f, 0.0f, 53400708.0f };
1224*03ce13f7SAndroid Build Coastguard Worker float z[] = { 0.0f, 0.0f, 7.0f, -53400708.0f };
1225*03ce13f7SAndroid Build Coastguard Worker
1226*03ce13f7SAndroid Build Coastguard Worker for(size_t i = 0; i < std::size(x); i++)
1227*03ce13f7SAndroid Build Coastguard Worker {
1228*03ce13f7SAndroid Build Coastguard Worker float4 x_in = { x[i], x[i], x[i], x[i] };
1229*03ce13f7SAndroid Build Coastguard Worker float4 y_in = { y[i], y[i], y[i], y[i] };
1230*03ce13f7SAndroid Build Coastguard Worker float4 z_in = { z[i], z[i], z[i], z[i] };
1231*03ce13f7SAndroid Build Coastguard Worker float4 r_out;
1232*03ce13f7SAndroid Build Coastguard Worker
1233*03ce13f7SAndroid Build Coastguard Worker callable(&r_out, &x_in, &y_in, &z_in);
1234*03ce13f7SAndroid Build Coastguard Worker
1235*03ce13f7SAndroid Build Coastguard Worker // Possible results
1236*03ce13f7SAndroid Build Coastguard Worker float fma = fmaf(x[i], y[i], z[i]);
1237*03ce13f7SAndroid Build Coastguard Worker float mul_add = x[i] * y[i] + z[i];
1238*03ce13f7SAndroid Build Coastguard Worker
1239*03ce13f7SAndroid Build Coastguard Worker // If the backend and the CPU support FMA instructions, we assume MulAdd to use
1240*03ce13f7SAndroid Build Coastguard Worker // them. Otherwise it may behave as a multiplication followed by an addition.
1241*03ce13f7SAndroid Build Coastguard Worker if(rr::Caps::fmaIsFast())
1242*03ce13f7SAndroid Build Coastguard Worker {
1243*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(r_out[0], fma);
1244*03ce13f7SAndroid Build Coastguard Worker }
1245*03ce13f7SAndroid Build Coastguard Worker else if(r_out[0] != fma)
1246*03ce13f7SAndroid Build Coastguard Worker {
1247*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(r_out[0], mul_add);
1248*03ce13f7SAndroid Build Coastguard Worker }
1249*03ce13f7SAndroid Build Coastguard Worker }
1250*03ce13f7SAndroid Build Coastguard Worker }
1251*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,FMA)1252*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, FMA)
1253*03ce13f7SAndroid Build Coastguard Worker {
1254*03ce13f7SAndroid Build Coastguard Worker Function<Void(Pointer<Float4>, Pointer<Float4>, Pointer<Float4>, Pointer<Float4>)> function;
1255*03ce13f7SAndroid Build Coastguard Worker {
1256*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> r = function.Arg<0>();
1257*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> x = function.Arg<1>();
1258*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> y = function.Arg<2>();
1259*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> z = function.Arg<3>();
1260*03ce13f7SAndroid Build Coastguard Worker
1261*03ce13f7SAndroid Build Coastguard Worker *r = FMA(*x, *y, *z);
1262*03ce13f7SAndroid Build Coastguard Worker }
1263*03ce13f7SAndroid Build Coastguard Worker
1264*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1265*03ce13f7SAndroid Build Coastguard Worker auto callable = (void (*)(float4 *, float4 *, float4 *, float4 *))routine->getEntry();
1266*03ce13f7SAndroid Build Coastguard Worker
1267*03ce13f7SAndroid Build Coastguard Worker float x[] = { 0.0f, 2.0f, 4.0f, 1.00000011920929f };
1268*03ce13f7SAndroid Build Coastguard Worker float y[] = { 0.0f, 3.0f, 0.0f, 53400708.0f };
1269*03ce13f7SAndroid Build Coastguard Worker float z[] = { 0.0f, 0.0f, 7.0f, -53400708.0f };
1270*03ce13f7SAndroid Build Coastguard Worker
1271*03ce13f7SAndroid Build Coastguard Worker for(size_t i = 0; i < std::size(x); i++)
1272*03ce13f7SAndroid Build Coastguard Worker {
1273*03ce13f7SAndroid Build Coastguard Worker float4 x_in = { x[i], x[i], x[i], x[i] };
1274*03ce13f7SAndroid Build Coastguard Worker float4 y_in = { y[i], y[i], y[i], y[i] };
1275*03ce13f7SAndroid Build Coastguard Worker float4 z_in = { z[i], z[i], z[i], z[i] };
1276*03ce13f7SAndroid Build Coastguard Worker float4 r_out;
1277*03ce13f7SAndroid Build Coastguard Worker
1278*03ce13f7SAndroid Build Coastguard Worker callable(&r_out, &x_in, &y_in, &z_in);
1279*03ce13f7SAndroid Build Coastguard Worker
1280*03ce13f7SAndroid Build Coastguard Worker float expected = fmaf(x[i], y[i], z[i]);
1281*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(r_out[0], expected);
1282*03ce13f7SAndroid Build Coastguard Worker }
1283*03ce13f7SAndroid Build Coastguard Worker }
1284*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,FAbs)1285*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, FAbs)
1286*03ce13f7SAndroid Build Coastguard Worker {
1287*03ce13f7SAndroid Build Coastguard Worker Function<Void(Pointer<Float4>, Pointer<Float4>)> function;
1288*03ce13f7SAndroid Build Coastguard Worker {
1289*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> x = function.Arg<0>();
1290*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> y = function.Arg<1>();
1291*03ce13f7SAndroid Build Coastguard Worker
1292*03ce13f7SAndroid Build Coastguard Worker *y = Abs(*x);
1293*03ce13f7SAndroid Build Coastguard Worker }
1294*03ce13f7SAndroid Build Coastguard Worker
1295*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1296*03ce13f7SAndroid Build Coastguard Worker auto callable = (void (*)(float4 *, float4 *))routine->getEntry();
1297*03ce13f7SAndroid Build Coastguard Worker
1298*03ce13f7SAndroid Build Coastguard Worker float input[] = { 1.0f, -1.0f, -0.0f, 0.0f };
1299*03ce13f7SAndroid Build Coastguard Worker
1300*03ce13f7SAndroid Build Coastguard Worker for(float x : input)
1301*03ce13f7SAndroid Build Coastguard Worker {
1302*03ce13f7SAndroid Build Coastguard Worker float4 v_in = { x, x, x, x };
1303*03ce13f7SAndroid Build Coastguard Worker float4 v_out;
1304*03ce13f7SAndroid Build Coastguard Worker
1305*03ce13f7SAndroid Build Coastguard Worker callable(&v_in, &v_out);
1306*03ce13f7SAndroid Build Coastguard Worker
1307*03ce13f7SAndroid Build Coastguard Worker float expected = fabs(x);
1308*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(v_out[0], expected);
1309*03ce13f7SAndroid Build Coastguard Worker }
1310*03ce13f7SAndroid Build Coastguard Worker }
1311*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Abs)1312*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Abs)
1313*03ce13f7SAndroid Build Coastguard Worker {
1314*03ce13f7SAndroid Build Coastguard Worker Function<Void(Pointer<Int4>, Pointer<Int4>)> function;
1315*03ce13f7SAndroid Build Coastguard Worker {
1316*03ce13f7SAndroid Build Coastguard Worker Pointer<Int4> x = function.Arg<0>();
1317*03ce13f7SAndroid Build Coastguard Worker Pointer<Int4> y = function.Arg<1>();
1318*03ce13f7SAndroid Build Coastguard Worker
1319*03ce13f7SAndroid Build Coastguard Worker *y = Abs(*x);
1320*03ce13f7SAndroid Build Coastguard Worker }
1321*03ce13f7SAndroid Build Coastguard Worker
1322*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1323*03ce13f7SAndroid Build Coastguard Worker auto callable = (void (*)(int4 *, int4 *))routine->getEntry();
1324*03ce13f7SAndroid Build Coastguard Worker
1325*03ce13f7SAndroid Build Coastguard Worker int input[] = { 1, -1, 0, (int)0x80000000 };
1326*03ce13f7SAndroid Build Coastguard Worker
1327*03ce13f7SAndroid Build Coastguard Worker for(int x : input)
1328*03ce13f7SAndroid Build Coastguard Worker {
1329*03ce13f7SAndroid Build Coastguard Worker int4 v_in = { x, x, x, x };
1330*03ce13f7SAndroid Build Coastguard Worker int4 v_out;
1331*03ce13f7SAndroid Build Coastguard Worker
1332*03ce13f7SAndroid Build Coastguard Worker callable(&v_in, &v_out);
1333*03ce13f7SAndroid Build Coastguard Worker
1334*03ce13f7SAndroid Build Coastguard Worker float expected = abs(x);
1335*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(v_out[0], expected);
1336*03ce13f7SAndroid Build Coastguard Worker }
1337*03ce13f7SAndroid Build Coastguard Worker }
1338*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,MinMax)1339*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, MinMax)
1340*03ce13f7SAndroid Build Coastguard Worker {
1341*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1342*03ce13f7SAndroid Build Coastguard Worker {
1343*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1344*03ce13f7SAndroid Build Coastguard Worker
1345*03ce13f7SAndroid Build Coastguard Worker *Pointer<Float4>(out + 16 * 0) = Min(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
1346*03ce13f7SAndroid Build Coastguard Worker *Pointer<Float4>(out + 16 * 1) = Max(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
1347*03ce13f7SAndroid Build Coastguard Worker
1348*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 2) = Min(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
1349*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 3) = Max(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
1350*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt4>(out + 16 * 4) = Min(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
1351*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt4>(out + 16 * 5) = Max(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
1352*03ce13f7SAndroid Build Coastguard Worker
1353*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * 6) = Min(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
1354*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * 7) = Max(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
1355*03ce13f7SAndroid Build Coastguard Worker *Pointer<UShort4>(out + 16 * 8) = Min(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
1356*03ce13f7SAndroid Build Coastguard Worker *Pointer<UShort4>(out + 16 * 9) = Max(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
1357*03ce13f7SAndroid Build Coastguard Worker
1358*03ce13f7SAndroid Build Coastguard Worker Return(0);
1359*03ce13f7SAndroid Build Coastguard Worker }
1360*03ce13f7SAndroid Build Coastguard Worker
1361*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1362*03ce13f7SAndroid Build Coastguard Worker
1363*03ce13f7SAndroid Build Coastguard Worker unsigned int out[10][4];
1364*03ce13f7SAndroid Build Coastguard Worker
1365*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1366*03ce13f7SAndroid Build Coastguard Worker
1367*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1368*03ce13f7SAndroid Build Coastguard Worker
1369*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0x00000000u);
1370*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0x00000000u);
1371*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][2], 0x00000000u);
1372*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][3], 0x80000000u);
1373*03ce13f7SAndroid Build Coastguard Worker
1374*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0x3F800000u);
1375*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0x3F800000u);
1376*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][2], 0x00000000u);
1377*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][3], 0x80000000u);
1378*03ce13f7SAndroid Build Coastguard Worker
1379*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][0], 0x00000000u);
1380*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][1], 0x00000000u);
1381*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][2], 0xFFFFFFFFu);
1382*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][3], 0x00000000u);
1383*03ce13f7SAndroid Build Coastguard Worker
1384*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][0], 0x00000001u);
1385*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][1], 0x00000001u);
1386*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][2], 0x00000000u);
1387*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][3], 0x00000000u);
1388*03ce13f7SAndroid Build Coastguard Worker
1389*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][0], 0x00000000u);
1390*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][1], 0x00000000u);
1391*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][2], 0x00000000u);
1392*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][3], 0x00000000u);
1393*03ce13f7SAndroid Build Coastguard Worker
1394*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][0], 0x00000001u);
1395*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][1], 0x00000001u);
1396*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][2], 0xFFFFFFFFu);
1397*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][3], 0x00000000u);
1398*03ce13f7SAndroid Build Coastguard Worker
1399*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][0], 0x00000000u);
1400*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][1], 0x0000FFFFu);
1401*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][2], 0x00000000u);
1402*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][3], 0x00000000u);
1403*03ce13f7SAndroid Build Coastguard Worker
1404*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][0], 0x00010001u);
1405*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][1], 0x00000000u);
1406*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][2], 0x00000000u);
1407*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][3], 0x00000000u);
1408*03ce13f7SAndroid Build Coastguard Worker
1409*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][0], 0x00000000u);
1410*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][1], 0x00000000u);
1411*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][2], 0x00000000u);
1412*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][3], 0x00000000u);
1413*03ce13f7SAndroid Build Coastguard Worker
1414*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[9][0], 0x00010001u);
1415*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[9][1], 0x0000FFFFu);
1416*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[9][2], 0x00000000u);
1417*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[9][3], 0x00000000u);
1418*03ce13f7SAndroid Build Coastguard Worker }
1419*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,NotNeg)1420*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, NotNeg)
1421*03ce13f7SAndroid Build Coastguard Worker {
1422*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1423*03ce13f7SAndroid Build Coastguard Worker {
1424*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1425*03ce13f7SAndroid Build Coastguard Worker
1426*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int>(out + 16 * 0) = ~Int(0x55555555);
1427*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short>(out + 16 * 1) = ~Short(0x5555);
1428*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 2) = ~Int4(0x55555555, 0xAAAAAAAA, 0x00000000, 0xFFFFFFFF);
1429*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * 3) = ~Short4(0x5555, 0xAAAA, 0x0000, 0xFFFF);
1430*03ce13f7SAndroid Build Coastguard Worker
1431*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int>(out + 16 * 4) = -Int(0x55555555);
1432*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short>(out + 16 * 5) = -Short(0x5555);
1433*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 6) = -Int4(0x55555555, 0xAAAAAAAA, 0x00000000, 0xFFFFFFFF);
1434*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * 7) = -Short4(0x5555, 0xAAAA, 0x0000, 0xFFFF);
1435*03ce13f7SAndroid Build Coastguard Worker
1436*03ce13f7SAndroid Build Coastguard Worker *Pointer<Float4>(out + 16 * 8) = -Float4(1.0f, -1.0f, 0.0f, -0.0f);
1437*03ce13f7SAndroid Build Coastguard Worker
1438*03ce13f7SAndroid Build Coastguard Worker Return(0);
1439*03ce13f7SAndroid Build Coastguard Worker }
1440*03ce13f7SAndroid Build Coastguard Worker
1441*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1442*03ce13f7SAndroid Build Coastguard Worker
1443*03ce13f7SAndroid Build Coastguard Worker unsigned int out[10][4];
1444*03ce13f7SAndroid Build Coastguard Worker
1445*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1446*03ce13f7SAndroid Build Coastguard Worker
1447*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1448*03ce13f7SAndroid Build Coastguard Worker
1449*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0xAAAAAAAAu);
1450*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0x00000000u);
1451*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][2], 0x00000000u);
1452*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][3], 0x00000000u);
1453*03ce13f7SAndroid Build Coastguard Worker
1454*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0x0000AAAAu);
1455*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0x00000000u);
1456*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][2], 0x00000000u);
1457*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][3], 0x00000000u);
1458*03ce13f7SAndroid Build Coastguard Worker
1459*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][0], 0xAAAAAAAAu);
1460*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][1], 0x55555555u);
1461*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][2], 0xFFFFFFFFu);
1462*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][3], 0x00000000u);
1463*03ce13f7SAndroid Build Coastguard Worker
1464*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][0], 0x5555AAAAu);
1465*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][1], 0x0000FFFFu);
1466*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][2], 0x00000000u);
1467*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][3], 0x00000000u);
1468*03ce13f7SAndroid Build Coastguard Worker
1469*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][0], 0xAAAAAAABu);
1470*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][1], 0x00000000u);
1471*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][2], 0x00000000u);
1472*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][3], 0x00000000u);
1473*03ce13f7SAndroid Build Coastguard Worker
1474*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][0], 0x0000AAABu);
1475*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][1], 0x00000000u);
1476*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][2], 0x00000000u);
1477*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][3], 0x00000000u);
1478*03ce13f7SAndroid Build Coastguard Worker
1479*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][0], 0xAAAAAAABu);
1480*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][1], 0x55555556u);
1481*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][2], 0x00000000u);
1482*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][3], 0x00000001u);
1483*03ce13f7SAndroid Build Coastguard Worker
1484*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][0], 0x5556AAABu);
1485*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][1], 0x00010000u);
1486*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][2], 0x00000000u);
1487*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][3], 0x00000000u);
1488*03ce13f7SAndroid Build Coastguard Worker
1489*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][0], 0xBF800000u);
1490*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][1], 0x3F800000u);
1491*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][2], 0x80000000u);
1492*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][3], 0x00000000u);
1493*03ce13f7SAndroid Build Coastguard Worker }
1494*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,RoundInt)1495*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, RoundInt)
1496*03ce13f7SAndroid Build Coastguard Worker {
1497*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1498*03ce13f7SAndroid Build Coastguard Worker {
1499*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1500*03ce13f7SAndroid Build Coastguard Worker
1501*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 0) = RoundInt(Float4(3.1f, 3.6f, -3.1f, -3.6f));
1502*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16) = RoundIntClamped(Float4(2147483648.0f, -2147483648.0f, 2147483520, -2147483520));
1503*03ce13f7SAndroid Build Coastguard Worker
1504*03ce13f7SAndroid Build Coastguard Worker Return(0);
1505*03ce13f7SAndroid Build Coastguard Worker }
1506*03ce13f7SAndroid Build Coastguard Worker
1507*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1508*03ce13f7SAndroid Build Coastguard Worker
1509*03ce13f7SAndroid Build Coastguard Worker int out[2][4];
1510*03ce13f7SAndroid Build Coastguard Worker
1511*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1512*03ce13f7SAndroid Build Coastguard Worker
1513*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1514*03ce13f7SAndroid Build Coastguard Worker
1515*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 3);
1516*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 4);
1517*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][2], -3);
1518*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][3], -4);
1519*03ce13f7SAndroid Build Coastguard Worker
1520*03ce13f7SAndroid Build Coastguard Worker // x86 returns 0x80000000 for values which cannot be represented in a 32-bit
1521*03ce13f7SAndroid Build Coastguard Worker // integer, but RoundIntClamped() clamps to ensure a positive value for
1522*03ce13f7SAndroid Build Coastguard Worker // positive input. ARM saturates to the largest representable integers.
1523*03ce13f7SAndroid Build Coastguard Worker EXPECT_GE(out[1][0], 2147483520);
1524*03ce13f7SAndroid Build Coastguard Worker EXPECT_LT(out[1][1], -2147483647);
1525*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][2], 2147483520);
1526*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][3], -2147483520);
1527*03ce13f7SAndroid Build Coastguard Worker }
1528*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,FPtoUI)1529*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, FPtoUI)
1530*03ce13f7SAndroid Build Coastguard Worker {
1531*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1532*03ce13f7SAndroid Build Coastguard Worker {
1533*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1534*03ce13f7SAndroid Build Coastguard Worker
1535*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt>(out + 0) = UInt(Float(0xF0000000u));
1536*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt>(out + 4) = UInt(Float(0xC0000000u));
1537*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt>(out + 8) = UInt(Float(0x00000001u));
1538*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt>(out + 12) = UInt(Float(0xF000F000u));
1539*03ce13f7SAndroid Build Coastguard Worker
1540*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt4>(out + 16) = UInt4(Float4(0xF0000000u, 0x80000000u, 0x00000000u, 0xCCCC0000u));
1541*03ce13f7SAndroid Build Coastguard Worker
1542*03ce13f7SAndroid Build Coastguard Worker Return(0);
1543*03ce13f7SAndroid Build Coastguard Worker }
1544*03ce13f7SAndroid Build Coastguard Worker
1545*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1546*03ce13f7SAndroid Build Coastguard Worker
1547*03ce13f7SAndroid Build Coastguard Worker unsigned int out[2][4];
1548*03ce13f7SAndroid Build Coastguard Worker
1549*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1550*03ce13f7SAndroid Build Coastguard Worker
1551*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1552*03ce13f7SAndroid Build Coastguard Worker
1553*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0xF0000000u);
1554*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0xC0000000u);
1555*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][2], 0x00000001u);
1556*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][3], 0xF000F000u);
1557*03ce13f7SAndroid Build Coastguard Worker
1558*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0xF0000000u);
1559*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0x80000000u);
1560*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][2], 0x00000000u);
1561*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][3], 0xCCCC0000u);
1562*03ce13f7SAndroid Build Coastguard Worker }
1563*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,VectorCompare)1564*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, VectorCompare)
1565*03ce13f7SAndroid Build Coastguard Worker {
1566*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1567*03ce13f7SAndroid Build Coastguard Worker {
1568*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1569*03ce13f7SAndroid Build Coastguard Worker
1570*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 0) = CmpEQ(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
1571*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 1) = CmpEQ(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
1572*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte8>(out + 16 * 2) = CmpEQ(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
1573*03ce13f7SAndroid Build Coastguard Worker
1574*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 3) = CmpNLT(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
1575*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 4) = CmpNLT(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
1576*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte8>(out + 16 * 5) = CmpGT(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
1577*03ce13f7SAndroid Build Coastguard Worker
1578*03ce13f7SAndroid Build Coastguard Worker Return(0);
1579*03ce13f7SAndroid Build Coastguard Worker }
1580*03ce13f7SAndroid Build Coastguard Worker
1581*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1582*03ce13f7SAndroid Build Coastguard Worker
1583*03ce13f7SAndroid Build Coastguard Worker unsigned int out[6][4];
1584*03ce13f7SAndroid Build Coastguard Worker
1585*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1586*03ce13f7SAndroid Build Coastguard Worker
1587*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1588*03ce13f7SAndroid Build Coastguard Worker
1589*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0x00000000u);
1590*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0xFFFFFFFFu);
1591*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][2], 0xFFFFFFFFu);
1592*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][3], 0xFFFFFFFFu);
1593*03ce13f7SAndroid Build Coastguard Worker
1594*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0x00000000u);
1595*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0x00000000u);
1596*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][2], 0x00000000u);
1597*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][3], 0xFFFFFFFFu);
1598*03ce13f7SAndroid Build Coastguard Worker
1599*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][0], 0xFF000000u);
1600*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][1], 0x00000000u);
1601*03ce13f7SAndroid Build Coastguard Worker
1602*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][0], 0xFFFFFFFFu);
1603*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][1], 0xFFFFFFFFu);
1604*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][2], 0xFFFFFFFFu);
1605*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][3], 0xFFFFFFFFu);
1606*03ce13f7SAndroid Build Coastguard Worker
1607*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][0], 0xFFFFFFFFu);
1608*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][1], 0x00000000u);
1609*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][2], 0x00000000u);
1610*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][3], 0xFFFFFFFFu);
1611*03ce13f7SAndroid Build Coastguard Worker
1612*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][0], 0x00000000u);
1613*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][1], 0xFFFFFFFFu);
1614*03ce13f7SAndroid Build Coastguard Worker }
1615*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,SaturatedAddAndSubtract)1616*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, SaturatedAddAndSubtract)
1617*03ce13f7SAndroid Build Coastguard Worker {
1618*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1619*03ce13f7SAndroid Build Coastguard Worker {
1620*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1621*03ce13f7SAndroid Build Coastguard Worker
1622*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte8>(out + 8 * 0) =
1623*03ce13f7SAndroid Build Coastguard Worker AddSat(Byte8(1, 2, 3, 4, 5, 6, 7, 8),
1624*03ce13f7SAndroid Build Coastguard Worker Byte8(7, 6, 5, 4, 3, 2, 1, 0));
1625*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte8>(out + 8 * 1) =
1626*03ce13f7SAndroid Build Coastguard Worker AddSat(Byte8(0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE),
1627*03ce13f7SAndroid Build Coastguard Worker Byte8(7, 6, 5, 4, 3, 2, 1, 0));
1628*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte8>(out + 8 * 2) =
1629*03ce13f7SAndroid Build Coastguard Worker SubSat(Byte8(1, 2, 3, 4, 5, 6, 7, 8),
1630*03ce13f7SAndroid Build Coastguard Worker Byte8(7, 6, 5, 4, 3, 2, 1, 0));
1631*03ce13f7SAndroid Build Coastguard Worker
1632*03ce13f7SAndroid Build Coastguard Worker *Pointer<SByte8>(out + 8 * 3) =
1633*03ce13f7SAndroid Build Coastguard Worker AddSat(SByte8(1, 2, 3, 4, 5, 6, 7, 8),
1634*03ce13f7SAndroid Build Coastguard Worker SByte8(7, 6, 5, 4, 3, 2, 1, 0));
1635*03ce13f7SAndroid Build Coastguard Worker *Pointer<SByte8>(out + 8 * 4) =
1636*03ce13f7SAndroid Build Coastguard Worker AddSat(SByte8(0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E),
1637*03ce13f7SAndroid Build Coastguard Worker SByte8(7, 6, 5, 4, 3, 2, 1, 0));
1638*03ce13f7SAndroid Build Coastguard Worker *Pointer<SByte8>(out + 8 * 5) =
1639*03ce13f7SAndroid Build Coastguard Worker AddSat(SByte8(0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88),
1640*03ce13f7SAndroid Build Coastguard Worker SByte8(-7, -6, -5, -4, -3, -2, -1, -0));
1641*03ce13f7SAndroid Build Coastguard Worker *Pointer<SByte8>(out + 8 * 6) =
1642*03ce13f7SAndroid Build Coastguard Worker SubSat(SByte8(0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88),
1643*03ce13f7SAndroid Build Coastguard Worker SByte8(7, 6, 5, 4, 3, 2, 1, 0));
1644*03ce13f7SAndroid Build Coastguard Worker
1645*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 8 * 7) =
1646*03ce13f7SAndroid Build Coastguard Worker AddSat(Short4(1, 2, 3, 4), Short4(3, 2, 1, 0));
1647*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 8 * 8) =
1648*03ce13f7SAndroid Build Coastguard Worker AddSat(Short4(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFE),
1649*03ce13f7SAndroid Build Coastguard Worker Short4(3, 2, 1, 0));
1650*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 8 * 9) =
1651*03ce13f7SAndroid Build Coastguard Worker AddSat(Short4(0x8001, 0x8002, 0x8003, 0x8004),
1652*03ce13f7SAndroid Build Coastguard Worker Short4(-3, -2, -1, -0));
1653*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 8 * 10) =
1654*03ce13f7SAndroid Build Coastguard Worker SubSat(Short4(0x8001, 0x8002, 0x8003, 0x8004),
1655*03ce13f7SAndroid Build Coastguard Worker Short4(3, 2, 1, 0));
1656*03ce13f7SAndroid Build Coastguard Worker
1657*03ce13f7SAndroid Build Coastguard Worker *Pointer<UShort4>(out + 8 * 11) =
1658*03ce13f7SAndroid Build Coastguard Worker AddSat(UShort4(1, 2, 3, 4), UShort4(3, 2, 1, 0));
1659*03ce13f7SAndroid Build Coastguard Worker *Pointer<UShort4>(out + 8 * 12) =
1660*03ce13f7SAndroid Build Coastguard Worker AddSat(UShort4(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE),
1661*03ce13f7SAndroid Build Coastguard Worker UShort4(3, 2, 1, 0));
1662*03ce13f7SAndroid Build Coastguard Worker *Pointer<UShort4>(out + 8 * 13) =
1663*03ce13f7SAndroid Build Coastguard Worker SubSat(UShort4(1, 2, 3, 4), UShort4(3, 2, 1, 0));
1664*03ce13f7SAndroid Build Coastguard Worker
1665*03ce13f7SAndroid Build Coastguard Worker Return(0);
1666*03ce13f7SAndroid Build Coastguard Worker }
1667*03ce13f7SAndroid Build Coastguard Worker
1668*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1669*03ce13f7SAndroid Build Coastguard Worker
1670*03ce13f7SAndroid Build Coastguard Worker unsigned int out[14][2];
1671*03ce13f7SAndroid Build Coastguard Worker
1672*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1673*03ce13f7SAndroid Build Coastguard Worker
1674*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1675*03ce13f7SAndroid Build Coastguard Worker
1676*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0x08080808u);
1677*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0x08080808u);
1678*03ce13f7SAndroid Build Coastguard Worker
1679*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0xFFFFFFFFu);
1680*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0xFEFFFFFFu);
1681*03ce13f7SAndroid Build Coastguard Worker
1682*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][0], 0x00000000u);
1683*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][1], 0x08060402u);
1684*03ce13f7SAndroid Build Coastguard Worker
1685*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][0], 0x08080808u);
1686*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][1], 0x08080808u);
1687*03ce13f7SAndroid Build Coastguard Worker
1688*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][0], 0x7F7F7F7Fu);
1689*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][1], 0x7E7F7F7Fu);
1690*03ce13f7SAndroid Build Coastguard Worker
1691*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][0], 0x80808080u);
1692*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][1], 0x88868482u);
1693*03ce13f7SAndroid Build Coastguard Worker
1694*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][0], 0x80808080u);
1695*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[6][1], 0x88868482u);
1696*03ce13f7SAndroid Build Coastguard Worker
1697*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][0], 0x00040004u);
1698*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[7][1], 0x00040004u);
1699*03ce13f7SAndroid Build Coastguard Worker
1700*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][0], 0x7FFF7FFFu);
1701*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[8][1], 0x7FFE7FFFu);
1702*03ce13f7SAndroid Build Coastguard Worker
1703*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[9][0], 0x80008000u);
1704*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[9][1], 0x80048002u);
1705*03ce13f7SAndroid Build Coastguard Worker
1706*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[10][0], 0x80008000u);
1707*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[10][1], 0x80048002u);
1708*03ce13f7SAndroid Build Coastguard Worker
1709*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[11][0], 0x00040004u);
1710*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[11][1], 0x00040004u);
1711*03ce13f7SAndroid Build Coastguard Worker
1712*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[12][0], 0xFFFFFFFFu);
1713*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[12][1], 0xFFFEFFFFu);
1714*03ce13f7SAndroid Build Coastguard Worker
1715*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[13][0], 0x00000000u);
1716*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[13][1], 0x00040002u);
1717*03ce13f7SAndroid Build Coastguard Worker }
1718*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Unpack)1719*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Unpack)
1720*03ce13f7SAndroid Build Coastguard Worker {
1721*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *, void *)> function;
1722*03ce13f7SAndroid Build Coastguard Worker {
1723*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> in = function.Arg<0>();
1724*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<1>();
1725*03ce13f7SAndroid Build Coastguard Worker
1726*03ce13f7SAndroid Build Coastguard Worker Byte4 test_byte_a = *Pointer<Byte4>(in + 4 * 0);
1727*03ce13f7SAndroid Build Coastguard Worker Byte4 test_byte_b = *Pointer<Byte4>(in + 4 * 1);
1728*03ce13f7SAndroid Build Coastguard Worker
1729*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 8 * 0) =
1730*03ce13f7SAndroid Build Coastguard Worker Unpack(test_byte_a, test_byte_b);
1731*03ce13f7SAndroid Build Coastguard Worker
1732*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 8 * 1) = Unpack(test_byte_a);
1733*03ce13f7SAndroid Build Coastguard Worker
1734*03ce13f7SAndroid Build Coastguard Worker Return(0);
1735*03ce13f7SAndroid Build Coastguard Worker }
1736*03ce13f7SAndroid Build Coastguard Worker
1737*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1738*03ce13f7SAndroid Build Coastguard Worker
1739*03ce13f7SAndroid Build Coastguard Worker unsigned int in[1][2];
1740*03ce13f7SAndroid Build Coastguard Worker unsigned int out[2][2];
1741*03ce13f7SAndroid Build Coastguard Worker
1742*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1743*03ce13f7SAndroid Build Coastguard Worker
1744*03ce13f7SAndroid Build Coastguard Worker in[0][0] = 0xABCDEF12u;
1745*03ce13f7SAndroid Build Coastguard Worker in[0][1] = 0x34567890u;
1746*03ce13f7SAndroid Build Coastguard Worker
1747*03ce13f7SAndroid Build Coastguard Worker routine(&in, &out);
1748*03ce13f7SAndroid Build Coastguard Worker
1749*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0x78EF9012u);
1750*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0x34AB56CDu);
1751*03ce13f7SAndroid Build Coastguard Worker
1752*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0xEFEF1212u);
1753*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0xABABCDCDu);
1754*03ce13f7SAndroid Build Coastguard Worker }
1755*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Pack)1756*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Pack)
1757*03ce13f7SAndroid Build Coastguard Worker {
1758*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1759*03ce13f7SAndroid Build Coastguard Worker {
1760*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1761*03ce13f7SAndroid Build Coastguard Worker
1762*03ce13f7SAndroid Build Coastguard Worker *Pointer<SByte8>(out + 8 * 0) =
1763*03ce13f7SAndroid Build Coastguard Worker PackSigned(Short4(-1, -2, 1, 2),
1764*03ce13f7SAndroid Build Coastguard Worker Short4(3, 4, -3, -4));
1765*03ce13f7SAndroid Build Coastguard Worker
1766*03ce13f7SAndroid Build Coastguard Worker *Pointer<Byte8>(out + 8 * 1) =
1767*03ce13f7SAndroid Build Coastguard Worker PackUnsigned(Short4(-1, -2, 1, 2),
1768*03ce13f7SAndroid Build Coastguard Worker Short4(3, 4, -3, -4));
1769*03ce13f7SAndroid Build Coastguard Worker
1770*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short8>(out + 8 * 2) =
1771*03ce13f7SAndroid Build Coastguard Worker PackSigned(Int4(-1, -2, 1, 2),
1772*03ce13f7SAndroid Build Coastguard Worker Int4(3, 4, -3, -4));
1773*03ce13f7SAndroid Build Coastguard Worker
1774*03ce13f7SAndroid Build Coastguard Worker *Pointer<UShort8>(out + 8 * 4) =
1775*03ce13f7SAndroid Build Coastguard Worker PackUnsigned(Int4(-1, -2, 1, 2),
1776*03ce13f7SAndroid Build Coastguard Worker Int4(3, 4, -3, -4));
1777*03ce13f7SAndroid Build Coastguard Worker
1778*03ce13f7SAndroid Build Coastguard Worker Return(0);
1779*03ce13f7SAndroid Build Coastguard Worker }
1780*03ce13f7SAndroid Build Coastguard Worker
1781*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1782*03ce13f7SAndroid Build Coastguard Worker
1783*03ce13f7SAndroid Build Coastguard Worker unsigned int out[6][2];
1784*03ce13f7SAndroid Build Coastguard Worker
1785*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1786*03ce13f7SAndroid Build Coastguard Worker
1787*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1788*03ce13f7SAndroid Build Coastguard Worker
1789*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0x0201FEFFu);
1790*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0xFCFD0403u);
1791*03ce13f7SAndroid Build Coastguard Worker
1792*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0x02010000u);
1793*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0x00000403u);
1794*03ce13f7SAndroid Build Coastguard Worker
1795*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][0], 0xFFFEFFFFu);
1796*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][1], 0x00020001u);
1797*03ce13f7SAndroid Build Coastguard Worker
1798*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][0], 0x00040003u);
1799*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][1], 0xFFFCFFFDu);
1800*03ce13f7SAndroid Build Coastguard Worker
1801*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][0], 0x00000000u);
1802*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][1], 0x00020001u);
1803*03ce13f7SAndroid Build Coastguard Worker
1804*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][0], 0x00040003u);
1805*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][1], 0x00000000u);
1806*03ce13f7SAndroid Build Coastguard Worker }
1807*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,MulHigh)1808*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, MulHigh)
1809*03ce13f7SAndroid Build Coastguard Worker {
1810*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1811*03ce13f7SAndroid Build Coastguard Worker {
1812*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1813*03ce13f7SAndroid Build Coastguard Worker
1814*03ce13f7SAndroid Build Coastguard Worker *Pointer<Short4>(out + 16 * 0) =
1815*03ce13f7SAndroid Build Coastguard Worker MulHigh(Short4(0x01AA, 0x02DD, 0x03EE, 0xF422),
1816*03ce13f7SAndroid Build Coastguard Worker Short4(0x01BB, 0x02CC, 0x03FF, 0xF411));
1817*03ce13f7SAndroid Build Coastguard Worker *Pointer<UShort4>(out + 16 * 1) =
1818*03ce13f7SAndroid Build Coastguard Worker MulHigh(UShort4(0x01AA, 0x02DD, 0x03EE, 0xF422),
1819*03ce13f7SAndroid Build Coastguard Worker UShort4(0x01BB, 0x02CC, 0x03FF, 0xF411));
1820*03ce13f7SAndroid Build Coastguard Worker
1821*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 2) =
1822*03ce13f7SAndroid Build Coastguard Worker MulHigh(Int4(0x000001AA, 0x000002DD, 0xC8000000, 0xF8000000),
1823*03ce13f7SAndroid Build Coastguard Worker Int4(0x000001BB, 0x84000000, 0x000003EE, 0xD7000000));
1824*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt4>(out + 16 * 3) =
1825*03ce13f7SAndroid Build Coastguard Worker MulHigh(UInt4(0x000001AAu, 0x000002DDu, 0xC8000000u, 0xD8000000u),
1826*03ce13f7SAndroid Build Coastguard Worker UInt4(0x000001BBu, 0x84000000u, 0x000003EEu, 0xD7000000u));
1827*03ce13f7SAndroid Build Coastguard Worker
1828*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int4>(out + 16 * 4) =
1829*03ce13f7SAndroid Build Coastguard Worker MulHigh(Int4(0x7FFFFFFF, 0x7FFFFFFF, 0x80008000, 0xFFFFFFFF),
1830*03ce13f7SAndroid Build Coastguard Worker Int4(0x7FFFFFFF, 0x80000000, 0x80008000, 0xFFFFFFFF));
1831*03ce13f7SAndroid Build Coastguard Worker *Pointer<UInt4>(out + 16 * 5) =
1832*03ce13f7SAndroid Build Coastguard Worker MulHigh(UInt4(0x7FFFFFFFu, 0x7FFFFFFFu, 0x80008000u, 0xFFFFFFFFu),
1833*03ce13f7SAndroid Build Coastguard Worker UInt4(0x7FFFFFFFu, 0x80000000u, 0x80008000u, 0xFFFFFFFFu));
1834*03ce13f7SAndroid Build Coastguard Worker
1835*03ce13f7SAndroid Build Coastguard Worker // (U)Short8 variants currently unimplemented.
1836*03ce13f7SAndroid Build Coastguard Worker
1837*03ce13f7SAndroid Build Coastguard Worker Return(0);
1838*03ce13f7SAndroid Build Coastguard Worker }
1839*03ce13f7SAndroid Build Coastguard Worker
1840*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1841*03ce13f7SAndroid Build Coastguard Worker
1842*03ce13f7SAndroid Build Coastguard Worker unsigned int out[6][4];
1843*03ce13f7SAndroid Build Coastguard Worker
1844*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1845*03ce13f7SAndroid Build Coastguard Worker
1846*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1847*03ce13f7SAndroid Build Coastguard Worker
1848*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0x00080002u);
1849*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0x008D000Fu);
1850*03ce13f7SAndroid Build Coastguard Worker
1851*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][0], 0x00080002u);
1852*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[1][1], 0xE8C0000Fu);
1853*03ce13f7SAndroid Build Coastguard Worker
1854*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][0], 0x00000000u);
1855*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][1], 0xFFFFFE9Cu);
1856*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][2], 0xFFFFFF23u);
1857*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[2][3], 0x01480000u);
1858*03ce13f7SAndroid Build Coastguard Worker
1859*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][0], 0x00000000u);
1860*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][1], 0x00000179u);
1861*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][2], 0x00000311u);
1862*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[3][3], 0xB5680000u);
1863*03ce13f7SAndroid Build Coastguard Worker
1864*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][0], 0x3FFFFFFFu);
1865*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][1], 0xC0000000u);
1866*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][2], 0x3FFF8000u);
1867*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[4][3], 0x00000000u);
1868*03ce13f7SAndroid Build Coastguard Worker
1869*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][0], 0x3FFFFFFFu);
1870*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][1], 0x3FFFFFFFu);
1871*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][2], 0x40008000u);
1872*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[5][3], 0xFFFFFFFEu);
1873*03ce13f7SAndroid Build Coastguard Worker }
1874*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,MulAdd)1875*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, MulAdd)
1876*03ce13f7SAndroid Build Coastguard Worker {
1877*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
1878*03ce13f7SAndroid Build Coastguard Worker {
1879*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<0>();
1880*03ce13f7SAndroid Build Coastguard Worker
1881*03ce13f7SAndroid Build Coastguard Worker *Pointer<Int2>(out + 8 * 0) =
1882*03ce13f7SAndroid Build Coastguard Worker MulAdd(Short4(0x1aa, 0x2dd, 0x3ee, 0xF422),
1883*03ce13f7SAndroid Build Coastguard Worker Short4(0x1bb, 0x2cc, 0x3ff, 0xF411));
1884*03ce13f7SAndroid Build Coastguard Worker
1885*03ce13f7SAndroid Build Coastguard Worker // (U)Short8 variant is mentioned but unimplemented
1886*03ce13f7SAndroid Build Coastguard Worker Return(0);
1887*03ce13f7SAndroid Build Coastguard Worker }
1888*03ce13f7SAndroid Build Coastguard Worker
1889*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1890*03ce13f7SAndroid Build Coastguard Worker
1891*03ce13f7SAndroid Build Coastguard Worker unsigned int out[1][2];
1892*03ce13f7SAndroid Build Coastguard Worker
1893*03ce13f7SAndroid Build Coastguard Worker memset(&out, 0, sizeof(out));
1894*03ce13f7SAndroid Build Coastguard Worker
1895*03ce13f7SAndroid Build Coastguard Worker routine(&out);
1896*03ce13f7SAndroid Build Coastguard Worker
1897*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][0], 0x000AE34Au);
1898*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out[0][1], 0x009D5254u);
1899*03ce13f7SAndroid Build Coastguard Worker }
1900*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,PointersEqual)1901*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, PointersEqual)
1902*03ce13f7SAndroid Build Coastguard Worker {
1903*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *, void *)> function;
1904*03ce13f7SAndroid Build Coastguard Worker {
1905*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> ptrA = function.Arg<0>();
1906*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> ptrB = function.Arg<1>();
1907*03ce13f7SAndroid Build Coastguard Worker If(ptrA == ptrB)
1908*03ce13f7SAndroid Build Coastguard Worker {
1909*03ce13f7SAndroid Build Coastguard Worker Return(1);
1910*03ce13f7SAndroid Build Coastguard Worker }
1911*03ce13f7SAndroid Build Coastguard Worker Else
1912*03ce13f7SAndroid Build Coastguard Worker {
1913*03ce13f7SAndroid Build Coastguard Worker Return(0);
1914*03ce13f7SAndroid Build Coastguard Worker }
1915*03ce13f7SAndroid Build Coastguard Worker }
1916*03ce13f7SAndroid Build Coastguard Worker
1917*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
1918*03ce13f7SAndroid Build Coastguard Worker int *a = reinterpret_cast<int *>(uintptr_t(0x0000000000000000));
1919*03ce13f7SAndroid Build Coastguard Worker int *b = reinterpret_cast<int *>(uintptr_t(0x00000000F0000000));
1920*03ce13f7SAndroid Build Coastguard Worker int *c = reinterpret_cast<int *>(uintptr_t(0xF000000000000000));
1921*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(&a, &a), 1);
1922*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(&b, &b), 1);
1923*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(&c, &c), 1);
1924*03ce13f7SAndroid Build Coastguard Worker
1925*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(&a, &b), 0);
1926*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(&b, &a), 0);
1927*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(&b, &c), 0);
1928*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(&c, &b), 0);
1929*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(&c, &a), 0);
1930*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(&a, &c), 0);
1931*03ce13f7SAndroid Build Coastguard Worker }
1932*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Args_2Mixed)1933*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Args_2Mixed)
1934*03ce13f7SAndroid Build Coastguard Worker {
1935*03ce13f7SAndroid Build Coastguard Worker // 2 mixed type args
1936*03ce13f7SAndroid Build Coastguard Worker FunctionT<float(int, float)> function;
1937*03ce13f7SAndroid Build Coastguard Worker {
1938*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
1939*03ce13f7SAndroid Build Coastguard Worker Float b = function.Arg<1>();
1940*03ce13f7SAndroid Build Coastguard Worker Return(Float(a) + b);
1941*03ce13f7SAndroid Build Coastguard Worker }
1942*03ce13f7SAndroid Build Coastguard Worker
1943*03ce13f7SAndroid Build Coastguard Worker if(auto routine = function(testName().c_str()))
1944*03ce13f7SAndroid Build Coastguard Worker {
1945*03ce13f7SAndroid Build Coastguard Worker float result = routine(1, 2.f);
1946*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 3.f);
1947*03ce13f7SAndroid Build Coastguard Worker }
1948*03ce13f7SAndroid Build Coastguard Worker }
1949*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Args_4Mixed)1950*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Args_4Mixed)
1951*03ce13f7SAndroid Build Coastguard Worker {
1952*03ce13f7SAndroid Build Coastguard Worker // 4 mixed type args (max register allocation on Windows)
1953*03ce13f7SAndroid Build Coastguard Worker FunctionT<float(int, float, int, float)> function;
1954*03ce13f7SAndroid Build Coastguard Worker {
1955*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
1956*03ce13f7SAndroid Build Coastguard Worker Float b = function.Arg<1>();
1957*03ce13f7SAndroid Build Coastguard Worker Int c = function.Arg<2>();
1958*03ce13f7SAndroid Build Coastguard Worker Float d = function.Arg<3>();
1959*03ce13f7SAndroid Build Coastguard Worker Return(Float(a) + b + Float(c) + d);
1960*03ce13f7SAndroid Build Coastguard Worker }
1961*03ce13f7SAndroid Build Coastguard Worker
1962*03ce13f7SAndroid Build Coastguard Worker if(auto routine = function(testName().c_str()))
1963*03ce13f7SAndroid Build Coastguard Worker {
1964*03ce13f7SAndroid Build Coastguard Worker float result = routine(1, 2.f, 3, 4.f);
1965*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 10.f);
1966*03ce13f7SAndroid Build Coastguard Worker }
1967*03ce13f7SAndroid Build Coastguard Worker }
1968*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Args_5Mixed)1969*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Args_5Mixed)
1970*03ce13f7SAndroid Build Coastguard Worker {
1971*03ce13f7SAndroid Build Coastguard Worker // 5 mixed type args (5th spills over to stack on Windows)
1972*03ce13f7SAndroid Build Coastguard Worker FunctionT<float(int, float, int, float, int)> function;
1973*03ce13f7SAndroid Build Coastguard Worker {
1974*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
1975*03ce13f7SAndroid Build Coastguard Worker Float b = function.Arg<1>();
1976*03ce13f7SAndroid Build Coastguard Worker Int c = function.Arg<2>();
1977*03ce13f7SAndroid Build Coastguard Worker Float d = function.Arg<3>();
1978*03ce13f7SAndroid Build Coastguard Worker Int e = function.Arg<4>();
1979*03ce13f7SAndroid Build Coastguard Worker Return(Float(a) + b + Float(c) + d + Float(e));
1980*03ce13f7SAndroid Build Coastguard Worker }
1981*03ce13f7SAndroid Build Coastguard Worker
1982*03ce13f7SAndroid Build Coastguard Worker if(auto routine = function(testName().c_str()))
1983*03ce13f7SAndroid Build Coastguard Worker {
1984*03ce13f7SAndroid Build Coastguard Worker float result = routine(1, 2.f, 3, 4.f, 5);
1985*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 15.f);
1986*03ce13f7SAndroid Build Coastguard Worker }
1987*03ce13f7SAndroid Build Coastguard Worker }
1988*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Args_GreaterThan5Mixed)1989*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Args_GreaterThan5Mixed)
1990*03ce13f7SAndroid Build Coastguard Worker {
1991*03ce13f7SAndroid Build Coastguard Worker // >5 mixed type args
1992*03ce13f7SAndroid Build Coastguard Worker FunctionT<float(int, float, int, float, int, float, int, float, int, float)> function;
1993*03ce13f7SAndroid Build Coastguard Worker {
1994*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
1995*03ce13f7SAndroid Build Coastguard Worker Float b = function.Arg<1>();
1996*03ce13f7SAndroid Build Coastguard Worker Int c = function.Arg<2>();
1997*03ce13f7SAndroid Build Coastguard Worker Float d = function.Arg<3>();
1998*03ce13f7SAndroid Build Coastguard Worker Int e = function.Arg<4>();
1999*03ce13f7SAndroid Build Coastguard Worker Float f = function.Arg<5>();
2000*03ce13f7SAndroid Build Coastguard Worker Int g = function.Arg<6>();
2001*03ce13f7SAndroid Build Coastguard Worker Float h = function.Arg<7>();
2002*03ce13f7SAndroid Build Coastguard Worker Int i = function.Arg<8>();
2003*03ce13f7SAndroid Build Coastguard Worker Float j = function.Arg<9>();
2004*03ce13f7SAndroid Build Coastguard Worker Return(Float(a) + b + Float(c) + d + Float(e) + f + Float(g) + h + Float(i) + j);
2005*03ce13f7SAndroid Build Coastguard Worker }
2006*03ce13f7SAndroid Build Coastguard Worker
2007*03ce13f7SAndroid Build Coastguard Worker if(auto routine = function(testName().c_str()))
2008*03ce13f7SAndroid Build Coastguard Worker {
2009*03ce13f7SAndroid Build Coastguard Worker float result = routine(1, 2.f, 3, 4.f, 5, 6.f, 7, 8.f, 9, 10.f);
2010*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 55.f);
2011*03ce13f7SAndroid Build Coastguard Worker }
2012*03ce13f7SAndroid Build Coastguard Worker }
2013*03ce13f7SAndroid Build Coastguard Worker
2014*03ce13f7SAndroid Build Coastguard Worker // This test was written because on Windows with Subzero, we would get a crash when executing a function
2015*03ce13f7SAndroid Build Coastguard Worker // with a large number of local variables. The problem was that on Windows, 4K pages are allocated as
2016*03ce13f7SAndroid Build Coastguard Worker // needed for the stack whenever an access is made in a "guard page", at which point the page is committed,
2017*03ce13f7SAndroid Build Coastguard Worker // and the next 4K page becomes the guard page. If a stack access is made that's beyond the guard page,
2018*03ce13f7SAndroid Build Coastguard Worker // a regular page fault occurs. To fix this, Subzero (and any compiler) now emits a call to __chkstk with
2019*03ce13f7SAndroid Build Coastguard Worker // the stack size in EAX, so that it can probe the stack in 4K increments up to that size, committing the
2020*03ce13f7SAndroid Build Coastguard Worker // required pages. See https://docs.microsoft.com/en-us/windows/win32/devnotes/-win32-chkstk.
TEST(ReactorUnitTests,LargeStack)2021*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, LargeStack)
2022*03ce13f7SAndroid Build Coastguard Worker {
2023*03ce13f7SAndroid Build Coastguard Worker // An empirically large enough value to access outside the guard pages
2024*03ce13f7SAndroid Build Coastguard Worker constexpr int ArrayByteSize = 24 * 1024;
2025*03ce13f7SAndroid Build Coastguard Worker constexpr int ArraySize = ArrayByteSize / sizeof(int32_t);
2026*03ce13f7SAndroid Build Coastguard Worker
2027*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(int32_t * v)> function;
2028*03ce13f7SAndroid Build Coastguard Worker {
2029*03ce13f7SAndroid Build Coastguard Worker // Allocate a stack array large enough that writing to the first element will reach beyond
2030*03ce13f7SAndroid Build Coastguard Worker // the guard page.
2031*03ce13f7SAndroid Build Coastguard Worker Array<Int, ArraySize> largeStackArray;
2032*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < ArraySize; ++i)
2033*03ce13f7SAndroid Build Coastguard Worker {
2034*03ce13f7SAndroid Build Coastguard Worker largeStackArray[i] = i;
2035*03ce13f7SAndroid Build Coastguard Worker }
2036*03ce13f7SAndroid Build Coastguard Worker
2037*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> in = function.Arg<0>();
2038*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < ArraySize; ++i)
2039*03ce13f7SAndroid Build Coastguard Worker {
2040*03ce13f7SAndroid Build Coastguard Worker in[i] = largeStackArray[i];
2041*03ce13f7SAndroid Build Coastguard Worker }
2042*03ce13f7SAndroid Build Coastguard Worker }
2043*03ce13f7SAndroid Build Coastguard Worker
2044*03ce13f7SAndroid Build Coastguard Worker // LLVM takes very long to generate this routine when O2 optimizations are enabled. Disable for now.
2045*03ce13f7SAndroid Build Coastguard Worker // TODO(b/174031014): Remove this once we fix LLVM taking so long.
2046*03ce13f7SAndroid Build Coastguard Worker ScopedPragma O0(OptimizationLevel, 0);
2047*03ce13f7SAndroid Build Coastguard Worker
2048*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2049*03ce13f7SAndroid Build Coastguard Worker
2050*03ce13f7SAndroid Build Coastguard Worker std::array<int32_t, ArraySize> v;
2051*03ce13f7SAndroid Build Coastguard Worker
2052*03ce13f7SAndroid Build Coastguard Worker // Run this in a thread, so that we get the default reserved stack size (8K on Win64).
2053*03ce13f7SAndroid Build Coastguard Worker std::thread t([&] {
2054*03ce13f7SAndroid Build Coastguard Worker routine(v.data());
2055*03ce13f7SAndroid Build Coastguard Worker });
2056*03ce13f7SAndroid Build Coastguard Worker t.join();
2057*03ce13f7SAndroid Build Coastguard Worker
2058*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < ArraySize; ++i)
2059*03ce13f7SAndroid Build Coastguard Worker {
2060*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(v[i], i);
2061*03ce13f7SAndroid Build Coastguard Worker }
2062*03ce13f7SAndroid Build Coastguard Worker }
2063*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ShlSmallRHSScalar)2064*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ShlSmallRHSScalar)
2065*03ce13f7SAndroid Build Coastguard Worker {
2066*03ce13f7SAndroid Build Coastguard Worker // TODO(crbug.com/swiftshader/185): Testing a temporary LLVM workaround
2067*03ce13f7SAndroid Build Coastguard Worker if(Caps::backendName().find("LLVM") == std::string::npos) return;
2068*03ce13f7SAndroid Build Coastguard Worker
2069*03ce13f7SAndroid Build Coastguard Worker FunctionT<unsigned()> function;
2070*03ce13f7SAndroid Build Coastguard Worker {
2071*03ce13f7SAndroid Build Coastguard Worker auto lhs = UInt(4);
2072*03ce13f7SAndroid Build Coastguard Worker auto rhs = UInt(8);
2073*03ce13f7SAndroid Build Coastguard Worker auto res = lhs << rhs;
2074*03ce13f7SAndroid Build Coastguard Worker Return(res);
2075*03ce13f7SAndroid Build Coastguard Worker }
2076*03ce13f7SAndroid Build Coastguard Worker
2077*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2078*03ce13f7SAndroid Build Coastguard Worker
2079*03ce13f7SAndroid Build Coastguard Worker unsigned res = routine();
2080*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 1u << 10u);
2081*03ce13f7SAndroid Build Coastguard Worker }
2082*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ShlLargeRHSScalar)2083*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ShlLargeRHSScalar)
2084*03ce13f7SAndroid Build Coastguard Worker {
2085*03ce13f7SAndroid Build Coastguard Worker // TODO(crbug.com/swiftshader/185): Testing a temporary LLVM workaround
2086*03ce13f7SAndroid Build Coastguard Worker if(Caps::backendName().find("LLVM") == std::string::npos) return;
2087*03ce13f7SAndroid Build Coastguard Worker
2088*03ce13f7SAndroid Build Coastguard Worker FunctionT<unsigned()> function;
2089*03ce13f7SAndroid Build Coastguard Worker {
2090*03ce13f7SAndroid Build Coastguard Worker auto lhs = UInt(1);
2091*03ce13f7SAndroid Build Coastguard Worker auto rhs = UInt(99);
2092*03ce13f7SAndroid Build Coastguard Worker auto res = lhs << rhs;
2093*03ce13f7SAndroid Build Coastguard Worker Return(res);
2094*03ce13f7SAndroid Build Coastguard Worker }
2095*03ce13f7SAndroid Build Coastguard Worker
2096*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2097*03ce13f7SAndroid Build Coastguard Worker
2098*03ce13f7SAndroid Build Coastguard Worker unsigned res = routine();
2099*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 1u << 31u);
2100*03ce13f7SAndroid Build Coastguard Worker }
2101*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ShrSmallRHSScalar)2102*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ShrSmallRHSScalar)
2103*03ce13f7SAndroid Build Coastguard Worker {
2104*03ce13f7SAndroid Build Coastguard Worker // TODO(crbug.com/swiftshader/185): Testing a temporary LLVM workaround
2105*03ce13f7SAndroid Build Coastguard Worker if(Caps::backendName().find("LLVM") == std::string::npos) return;
2106*03ce13f7SAndroid Build Coastguard Worker
2107*03ce13f7SAndroid Build Coastguard Worker FunctionT<unsigned()> function;
2108*03ce13f7SAndroid Build Coastguard Worker {
2109*03ce13f7SAndroid Build Coastguard Worker auto lhs = UInt(64);
2110*03ce13f7SAndroid Build Coastguard Worker auto rhs = UInt(4);
2111*03ce13f7SAndroid Build Coastguard Worker auto res = lhs >> rhs;
2112*03ce13f7SAndroid Build Coastguard Worker Return(res);
2113*03ce13f7SAndroid Build Coastguard Worker }
2114*03ce13f7SAndroid Build Coastguard Worker
2115*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2116*03ce13f7SAndroid Build Coastguard Worker
2117*03ce13f7SAndroid Build Coastguard Worker unsigned res = routine();
2118*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 4u);
2119*03ce13f7SAndroid Build Coastguard Worker }
2120*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ShrLargeRHSScalar)2121*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ShrLargeRHSScalar)
2122*03ce13f7SAndroid Build Coastguard Worker {
2123*03ce13f7SAndroid Build Coastguard Worker // TODO(crbug.com/swiftshader/185): Testing a temporary LLVM workaround
2124*03ce13f7SAndroid Build Coastguard Worker if(Caps::backendName().find("LLVM") == std::string::npos) return;
2125*03ce13f7SAndroid Build Coastguard Worker
2126*03ce13f7SAndroid Build Coastguard Worker FunctionT<unsigned()> function;
2127*03ce13f7SAndroid Build Coastguard Worker {
2128*03ce13f7SAndroid Build Coastguard Worker auto lhs = UInt(4);
2129*03ce13f7SAndroid Build Coastguard Worker auto rhs = UInt(99);
2130*03ce13f7SAndroid Build Coastguard Worker auto res = lhs >> rhs;
2131*03ce13f7SAndroid Build Coastguard Worker Return(res);
2132*03ce13f7SAndroid Build Coastguard Worker }
2133*03ce13f7SAndroid Build Coastguard Worker
2134*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2135*03ce13f7SAndroid Build Coastguard Worker
2136*03ce13f7SAndroid Build Coastguard Worker unsigned res = routine();
2137*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 0u);
2138*03ce13f7SAndroid Build Coastguard Worker }
2139*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ShlRHSVector)2140*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ShlRHSVector)
2141*03ce13f7SAndroid Build Coastguard Worker {
2142*03ce13f7SAndroid Build Coastguard Worker // TODO(crbug.com/swiftshader/185): Testing a temporary LLVM workaround
2143*03ce13f7SAndroid Build Coastguard Worker if(Caps::backendName().find("LLVM") == std::string::npos) return;
2144*03ce13f7SAndroid Build Coastguard Worker
2145*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(unsigned *a, unsigned *b, unsigned *c, unsigned *d)> function;
2146*03ce13f7SAndroid Build Coastguard Worker {
2147*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> a = function.Arg<0>();
2148*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> b = function.Arg<1>();
2149*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> c = function.Arg<2>();
2150*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> d = function.Arg<3>();
2151*03ce13f7SAndroid Build Coastguard Worker
2152*03ce13f7SAndroid Build Coastguard Worker auto lhs = UInt4(4, 3, 6, 5);
2153*03ce13f7SAndroid Build Coastguard Worker auto rhs = UInt4(8, 99, 2, 50);
2154*03ce13f7SAndroid Build Coastguard Worker UInt4 res = lhs << rhs;
2155*03ce13f7SAndroid Build Coastguard Worker *a = res.x;
2156*03ce13f7SAndroid Build Coastguard Worker *b = res.y;
2157*03ce13f7SAndroid Build Coastguard Worker *c = res.z;
2158*03ce13f7SAndroid Build Coastguard Worker *d = res.w;
2159*03ce13f7SAndroid Build Coastguard Worker }
2160*03ce13f7SAndroid Build Coastguard Worker
2161*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2162*03ce13f7SAndroid Build Coastguard Worker
2163*03ce13f7SAndroid Build Coastguard Worker unsigned a = 0;
2164*03ce13f7SAndroid Build Coastguard Worker unsigned b = 0;
2165*03ce13f7SAndroid Build Coastguard Worker unsigned c = 0;
2166*03ce13f7SAndroid Build Coastguard Worker unsigned d = 0;
2167*03ce13f7SAndroid Build Coastguard Worker routine(&a, &b, &c, &d);
2168*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(a, 1024u);
2169*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(b, 0x80000000u);
2170*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(c, 24u);
2171*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(d, 0x80000000u);
2172*03ce13f7SAndroid Build Coastguard Worker }
2173*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ShrRHSVector)2174*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ShrRHSVector)
2175*03ce13f7SAndroid Build Coastguard Worker {
2176*03ce13f7SAndroid Build Coastguard Worker // TODO(crbug.com/swiftshader/185): Testing a temporary LLVM workaround
2177*03ce13f7SAndroid Build Coastguard Worker if(Caps::backendName().find("LLVM") == std::string::npos) return;
2178*03ce13f7SAndroid Build Coastguard Worker
2179*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(unsigned *a, unsigned *b, unsigned *c, unsigned *d)> function;
2180*03ce13f7SAndroid Build Coastguard Worker {
2181*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> a = function.Arg<0>();
2182*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> b = function.Arg<1>();
2183*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> c = function.Arg<2>();
2184*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> d = function.Arg<3>();
2185*03ce13f7SAndroid Build Coastguard Worker
2186*03ce13f7SAndroid Build Coastguard Worker auto lhs = UInt4(745, 23, 234, 54);
2187*03ce13f7SAndroid Build Coastguard Worker auto rhs = UInt4(8, 99, 2, 50);
2188*03ce13f7SAndroid Build Coastguard Worker UInt4 res = lhs >> rhs;
2189*03ce13f7SAndroid Build Coastguard Worker *a = res.x;
2190*03ce13f7SAndroid Build Coastguard Worker *b = res.y;
2191*03ce13f7SAndroid Build Coastguard Worker *c = res.z;
2192*03ce13f7SAndroid Build Coastguard Worker *d = res.w;
2193*03ce13f7SAndroid Build Coastguard Worker }
2194*03ce13f7SAndroid Build Coastguard Worker
2195*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2196*03ce13f7SAndroid Build Coastguard Worker
2197*03ce13f7SAndroid Build Coastguard Worker unsigned a = 0;
2198*03ce13f7SAndroid Build Coastguard Worker unsigned b = 0;
2199*03ce13f7SAndroid Build Coastguard Worker unsigned c = 0;
2200*03ce13f7SAndroid Build Coastguard Worker unsigned d = 0;
2201*03ce13f7SAndroid Build Coastguard Worker routine(&a, &b, &c, &d);
2202*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(a, 2u);
2203*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(b, 0u);
2204*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(c, 58u);
2205*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(d, 0u);
2206*03ce13f7SAndroid Build Coastguard Worker }
2207*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ShrLargeRHSVector)2208*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ShrLargeRHSVector)
2209*03ce13f7SAndroid Build Coastguard Worker {
2210*03ce13f7SAndroid Build Coastguard Worker // TODO(crbug.com/swiftshader/185): Testing a temporary LLVM workaround
2211*03ce13f7SAndroid Build Coastguard Worker if(Caps::backendName().find("LLVM") == std::string::npos) return;
2212*03ce13f7SAndroid Build Coastguard Worker
2213*03ce13f7SAndroid Build Coastguard Worker FunctionT<unsigned()> function;
2214*03ce13f7SAndroid Build Coastguard Worker {
2215*03ce13f7SAndroid Build Coastguard Worker auto lhs = UInt(4);
2216*03ce13f7SAndroid Build Coastguard Worker auto rhs = UInt(99);
2217*03ce13f7SAndroid Build Coastguard Worker auto res = lhs >> rhs;
2218*03ce13f7SAndroid Build Coastguard Worker Return(res);
2219*03ce13f7SAndroid Build Coastguard Worker }
2220*03ce13f7SAndroid Build Coastguard Worker
2221*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2222*03ce13f7SAndroid Build Coastguard Worker
2223*03ce13f7SAndroid Build Coastguard Worker unsigned res = routine();
2224*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 0u);
2225*03ce13f7SAndroid Build Coastguard Worker }
2226*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Call)2227*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Call)
2228*03ce13f7SAndroid Build Coastguard Worker {
2229*03ce13f7SAndroid Build Coastguard Worker struct Class
2230*03ce13f7SAndroid Build Coastguard Worker {
2231*03ce13f7SAndroid Build Coastguard Worker static int Callback(Class *p, int i, float f)
2232*03ce13f7SAndroid Build Coastguard Worker {
2233*03ce13f7SAndroid Build Coastguard Worker p->i = i;
2234*03ce13f7SAndroid Build Coastguard Worker p->f = f;
2235*03ce13f7SAndroid Build Coastguard Worker return i + int(f);
2236*03ce13f7SAndroid Build Coastguard Worker }
2237*03ce13f7SAndroid Build Coastguard Worker
2238*03ce13f7SAndroid Build Coastguard Worker int i = 0;
2239*03ce13f7SAndroid Build Coastguard Worker float f = 0.0f;
2240*03ce13f7SAndroid Build Coastguard Worker };
2241*03ce13f7SAndroid Build Coastguard Worker
2242*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
2243*03ce13f7SAndroid Build Coastguard Worker {
2244*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> c = function.Arg<0>();
2245*03ce13f7SAndroid Build Coastguard Worker auto res = Call(Class::Callback, c, 10, 20.0f);
2246*03ce13f7SAndroid Build Coastguard Worker Return(res);
2247*03ce13f7SAndroid Build Coastguard Worker }
2248*03ce13f7SAndroid Build Coastguard Worker
2249*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2250*03ce13f7SAndroid Build Coastguard Worker
2251*03ce13f7SAndroid Build Coastguard Worker Class c;
2252*03ce13f7SAndroid Build Coastguard Worker int res = routine(&c);
2253*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 30);
2254*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(c.i, 10);
2255*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(c.f, 20.0f);
2256*03ce13f7SAndroid Build Coastguard Worker }
2257*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,CallMemberFunction)2258*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, CallMemberFunction)
2259*03ce13f7SAndroid Build Coastguard Worker {
2260*03ce13f7SAndroid Build Coastguard Worker struct Class
2261*03ce13f7SAndroid Build Coastguard Worker {
2262*03ce13f7SAndroid Build Coastguard Worker int Callback(int argI, float argF)
2263*03ce13f7SAndroid Build Coastguard Worker {
2264*03ce13f7SAndroid Build Coastguard Worker i = argI;
2265*03ce13f7SAndroid Build Coastguard Worker f = argF;
2266*03ce13f7SAndroid Build Coastguard Worker return i + int(f);
2267*03ce13f7SAndroid Build Coastguard Worker }
2268*03ce13f7SAndroid Build Coastguard Worker
2269*03ce13f7SAndroid Build Coastguard Worker int i = 0;
2270*03ce13f7SAndroid Build Coastguard Worker float f = 0.0f;
2271*03ce13f7SAndroid Build Coastguard Worker };
2272*03ce13f7SAndroid Build Coastguard Worker
2273*03ce13f7SAndroid Build Coastguard Worker Class c;
2274*03ce13f7SAndroid Build Coastguard Worker
2275*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
2276*03ce13f7SAndroid Build Coastguard Worker {
2277*03ce13f7SAndroid Build Coastguard Worker auto res = Call(&Class::Callback, &c, 10, 20.0f);
2278*03ce13f7SAndroid Build Coastguard Worker Return(res);
2279*03ce13f7SAndroid Build Coastguard Worker }
2280*03ce13f7SAndroid Build Coastguard Worker
2281*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2282*03ce13f7SAndroid Build Coastguard Worker
2283*03ce13f7SAndroid Build Coastguard Worker int res = routine();
2284*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 30);
2285*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(c.i, 10);
2286*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(c.f, 20.0f);
2287*03ce13f7SAndroid Build Coastguard Worker }
2288*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,CallMemberFunctionIndirect)2289*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, CallMemberFunctionIndirect)
2290*03ce13f7SAndroid Build Coastguard Worker {
2291*03ce13f7SAndroid Build Coastguard Worker struct Class
2292*03ce13f7SAndroid Build Coastguard Worker {
2293*03ce13f7SAndroid Build Coastguard Worker int Callback(int argI, float argF)
2294*03ce13f7SAndroid Build Coastguard Worker {
2295*03ce13f7SAndroid Build Coastguard Worker i = argI;
2296*03ce13f7SAndroid Build Coastguard Worker f = argF;
2297*03ce13f7SAndroid Build Coastguard Worker return i + int(f);
2298*03ce13f7SAndroid Build Coastguard Worker }
2299*03ce13f7SAndroid Build Coastguard Worker
2300*03ce13f7SAndroid Build Coastguard Worker int i = 0;
2301*03ce13f7SAndroid Build Coastguard Worker float f = 0.0f;
2302*03ce13f7SAndroid Build Coastguard Worker };
2303*03ce13f7SAndroid Build Coastguard Worker
2304*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void *)> function;
2305*03ce13f7SAndroid Build Coastguard Worker {
2306*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> c = function.Arg<0>();
2307*03ce13f7SAndroid Build Coastguard Worker auto res = Call(&Class::Callback, c, 10, 20.0f);
2308*03ce13f7SAndroid Build Coastguard Worker Return(res);
2309*03ce13f7SAndroid Build Coastguard Worker }
2310*03ce13f7SAndroid Build Coastguard Worker
2311*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2312*03ce13f7SAndroid Build Coastguard Worker
2313*03ce13f7SAndroid Build Coastguard Worker Class c;
2314*03ce13f7SAndroid Build Coastguard Worker int res = routine(&c);
2315*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 30);
2316*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(c.i, 10);
2317*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(c.f, 20.0f);
2318*03ce13f7SAndroid Build Coastguard Worker }
2319*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,CallImplicitCast)2320*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, CallImplicitCast)
2321*03ce13f7SAndroid Build Coastguard Worker {
2322*03ce13f7SAndroid Build Coastguard Worker struct Class
2323*03ce13f7SAndroid Build Coastguard Worker {
2324*03ce13f7SAndroid Build Coastguard Worker static void Callback(Class *c, const char *s)
2325*03ce13f7SAndroid Build Coastguard Worker {
2326*03ce13f7SAndroid Build Coastguard Worker c->str = s;
2327*03ce13f7SAndroid Build Coastguard Worker }
2328*03ce13f7SAndroid Build Coastguard Worker std::string str;
2329*03ce13f7SAndroid Build Coastguard Worker };
2330*03ce13f7SAndroid Build Coastguard Worker
2331*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(Class * c, const char *s)> function;
2332*03ce13f7SAndroid Build Coastguard Worker {
2333*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> c = function.Arg<0>();
2334*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> s = function.Arg<1>();
2335*03ce13f7SAndroid Build Coastguard Worker Call(Class::Callback, c, s);
2336*03ce13f7SAndroid Build Coastguard Worker }
2337*03ce13f7SAndroid Build Coastguard Worker
2338*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2339*03ce13f7SAndroid Build Coastguard Worker
2340*03ce13f7SAndroid Build Coastguard Worker Class c;
2341*03ce13f7SAndroid Build Coastguard Worker routine(&c, "hello world");
2342*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(c.str, "hello world");
2343*03ce13f7SAndroid Build Coastguard Worker }
2344*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,CallBoolReturnFunction)2345*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, CallBoolReturnFunction)
2346*03ce13f7SAndroid Build Coastguard Worker {
2347*03ce13f7SAndroid Build Coastguard Worker struct Class
2348*03ce13f7SAndroid Build Coastguard Worker {
2349*03ce13f7SAndroid Build Coastguard Worker static bool IsEven(int a)
2350*03ce13f7SAndroid Build Coastguard Worker {
2351*03ce13f7SAndroid Build Coastguard Worker return a % 2 == 0;
2352*03ce13f7SAndroid Build Coastguard Worker }
2353*03ce13f7SAndroid Build Coastguard Worker };
2354*03ce13f7SAndroid Build Coastguard Worker
2355*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
2356*03ce13f7SAndroid Build Coastguard Worker {
2357*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
2358*03ce13f7SAndroid Build Coastguard Worker Bool res = Call(Class::IsEven, a);
2359*03ce13f7SAndroid Build Coastguard Worker If(res)
2360*03ce13f7SAndroid Build Coastguard Worker {
2361*03ce13f7SAndroid Build Coastguard Worker Return(1);
2362*03ce13f7SAndroid Build Coastguard Worker }
2363*03ce13f7SAndroid Build Coastguard Worker Return(0);
2364*03ce13f7SAndroid Build Coastguard Worker }
2365*03ce13f7SAndroid Build Coastguard Worker
2366*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2367*03ce13f7SAndroid Build Coastguard Worker
2368*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 10; ++i)
2369*03ce13f7SAndroid Build Coastguard Worker {
2370*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(i), i % 2 == 0);
2371*03ce13f7SAndroid Build Coastguard Worker }
2372*03ce13f7SAndroid Build Coastguard Worker }
2373*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Call_Args4)2374*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Call_Args4)
2375*03ce13f7SAndroid Build Coastguard Worker {
2376*03ce13f7SAndroid Build Coastguard Worker struct Class
2377*03ce13f7SAndroid Build Coastguard Worker {
2378*03ce13f7SAndroid Build Coastguard Worker static int Func(int a, int b, int c, int d)
2379*03ce13f7SAndroid Build Coastguard Worker {
2380*03ce13f7SAndroid Build Coastguard Worker return a + b + c + d;
2381*03ce13f7SAndroid Build Coastguard Worker }
2382*03ce13f7SAndroid Build Coastguard Worker };
2383*03ce13f7SAndroid Build Coastguard Worker
2384*03ce13f7SAndroid Build Coastguard Worker {
2385*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
2386*03ce13f7SAndroid Build Coastguard Worker {
2387*03ce13f7SAndroid Build Coastguard Worker auto res = Call(Class::Func, 1, 2, 3, 4);
2388*03ce13f7SAndroid Build Coastguard Worker Return(res);
2389*03ce13f7SAndroid Build Coastguard Worker }
2390*03ce13f7SAndroid Build Coastguard Worker
2391*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2392*03ce13f7SAndroid Build Coastguard Worker
2393*03ce13f7SAndroid Build Coastguard Worker int res = routine();
2394*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 1 + 2 + 3 + 4);
2395*03ce13f7SAndroid Build Coastguard Worker }
2396*03ce13f7SAndroid Build Coastguard Worker }
2397*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Call_Args5)2398*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Call_Args5)
2399*03ce13f7SAndroid Build Coastguard Worker {
2400*03ce13f7SAndroid Build Coastguard Worker struct Class
2401*03ce13f7SAndroid Build Coastguard Worker {
2402*03ce13f7SAndroid Build Coastguard Worker static int Func(int a, int b, int c, int d, int e)
2403*03ce13f7SAndroid Build Coastguard Worker {
2404*03ce13f7SAndroid Build Coastguard Worker return a + b + c + d + e;
2405*03ce13f7SAndroid Build Coastguard Worker }
2406*03ce13f7SAndroid Build Coastguard Worker };
2407*03ce13f7SAndroid Build Coastguard Worker
2408*03ce13f7SAndroid Build Coastguard Worker {
2409*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
2410*03ce13f7SAndroid Build Coastguard Worker {
2411*03ce13f7SAndroid Build Coastguard Worker auto res = Call(Class::Func, 1, 2, 3, 4, 5);
2412*03ce13f7SAndroid Build Coastguard Worker Return(res);
2413*03ce13f7SAndroid Build Coastguard Worker }
2414*03ce13f7SAndroid Build Coastguard Worker
2415*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2416*03ce13f7SAndroid Build Coastguard Worker
2417*03ce13f7SAndroid Build Coastguard Worker int res = routine();
2418*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 1 + 2 + 3 + 4 + 5);
2419*03ce13f7SAndroid Build Coastguard Worker }
2420*03ce13f7SAndroid Build Coastguard Worker }
2421*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Call_ArgsMany)2422*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Call_ArgsMany)
2423*03ce13f7SAndroid Build Coastguard Worker {
2424*03ce13f7SAndroid Build Coastguard Worker struct Class
2425*03ce13f7SAndroid Build Coastguard Worker {
2426*03ce13f7SAndroid Build Coastguard Worker static int Func(int a, int b, int c, int d, int e, int f, int g, int h)
2427*03ce13f7SAndroid Build Coastguard Worker {
2428*03ce13f7SAndroid Build Coastguard Worker return a + b + c + d + e + f + g + h;
2429*03ce13f7SAndroid Build Coastguard Worker }
2430*03ce13f7SAndroid Build Coastguard Worker };
2431*03ce13f7SAndroid Build Coastguard Worker
2432*03ce13f7SAndroid Build Coastguard Worker {
2433*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
2434*03ce13f7SAndroid Build Coastguard Worker {
2435*03ce13f7SAndroid Build Coastguard Worker auto res = Call(Class::Func, 1, 2, 3, 4, 5, 6, 7, 8);
2436*03ce13f7SAndroid Build Coastguard Worker Return(res);
2437*03ce13f7SAndroid Build Coastguard Worker }
2438*03ce13f7SAndroid Build Coastguard Worker
2439*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2440*03ce13f7SAndroid Build Coastguard Worker
2441*03ce13f7SAndroid Build Coastguard Worker int res = routine();
2442*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8);
2443*03ce13f7SAndroid Build Coastguard Worker }
2444*03ce13f7SAndroid Build Coastguard Worker }
2445*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Call_ArgsMixed)2446*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Call_ArgsMixed)
2447*03ce13f7SAndroid Build Coastguard Worker {
2448*03ce13f7SAndroid Build Coastguard Worker struct Class
2449*03ce13f7SAndroid Build Coastguard Worker {
2450*03ce13f7SAndroid Build Coastguard Worker static int Func(int a, float b, int *c, float *d, int e, float f, int *g, float *h)
2451*03ce13f7SAndroid Build Coastguard Worker {
2452*03ce13f7SAndroid Build Coastguard Worker return a + b + *c + *d + e + f + *g + *h;
2453*03ce13f7SAndroid Build Coastguard Worker }
2454*03ce13f7SAndroid Build Coastguard Worker };
2455*03ce13f7SAndroid Build Coastguard Worker
2456*03ce13f7SAndroid Build Coastguard Worker {
2457*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
2458*03ce13f7SAndroid Build Coastguard Worker {
2459*03ce13f7SAndroid Build Coastguard Worker Int c(3);
2460*03ce13f7SAndroid Build Coastguard Worker Float d(4);
2461*03ce13f7SAndroid Build Coastguard Worker Int g(7);
2462*03ce13f7SAndroid Build Coastguard Worker Float h(8);
2463*03ce13f7SAndroid Build Coastguard Worker auto res = Call(Class::Func, 1, 2.f, &c, &d, 5, 6.f, &g, &h);
2464*03ce13f7SAndroid Build Coastguard Worker Return(res);
2465*03ce13f7SAndroid Build Coastguard Worker }
2466*03ce13f7SAndroid Build Coastguard Worker
2467*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2468*03ce13f7SAndroid Build Coastguard Worker
2469*03ce13f7SAndroid Build Coastguard Worker int res = routine();
2470*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8);
2471*03ce13f7SAndroid Build Coastguard Worker }
2472*03ce13f7SAndroid Build Coastguard Worker }
2473*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Call_ArgsPointer)2474*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Call_ArgsPointer)
2475*03ce13f7SAndroid Build Coastguard Worker {
2476*03ce13f7SAndroid Build Coastguard Worker struct Class
2477*03ce13f7SAndroid Build Coastguard Worker {
2478*03ce13f7SAndroid Build Coastguard Worker static int Func(int *a)
2479*03ce13f7SAndroid Build Coastguard Worker {
2480*03ce13f7SAndroid Build Coastguard Worker return *a;
2481*03ce13f7SAndroid Build Coastguard Worker }
2482*03ce13f7SAndroid Build Coastguard Worker };
2483*03ce13f7SAndroid Build Coastguard Worker
2484*03ce13f7SAndroid Build Coastguard Worker {
2485*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
2486*03ce13f7SAndroid Build Coastguard Worker {
2487*03ce13f7SAndroid Build Coastguard Worker Int a(12345);
2488*03ce13f7SAndroid Build Coastguard Worker auto res = Call(Class::Func, &a);
2489*03ce13f7SAndroid Build Coastguard Worker Return(res);
2490*03ce13f7SAndroid Build Coastguard Worker }
2491*03ce13f7SAndroid Build Coastguard Worker
2492*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2493*03ce13f7SAndroid Build Coastguard Worker
2494*03ce13f7SAndroid Build Coastguard Worker int res = routine();
2495*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(res, 12345);
2496*03ce13f7SAndroid Build Coastguard Worker }
2497*03ce13f7SAndroid Build Coastguard Worker }
2498*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,CallExternalCallRoutine)2499*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, CallExternalCallRoutine)
2500*03ce13f7SAndroid Build Coastguard Worker {
2501*03ce13f7SAndroid Build Coastguard Worker // routine1 calls Class::Func, passing it a pointer to routine2, and Class::Func calls routine2
2502*03ce13f7SAndroid Build Coastguard Worker
2503*03ce13f7SAndroid Build Coastguard Worker auto routine2 = [] {
2504*03ce13f7SAndroid Build Coastguard Worker FunctionT<float(float, int)> function;
2505*03ce13f7SAndroid Build Coastguard Worker {
2506*03ce13f7SAndroid Build Coastguard Worker Float a = function.Arg<0>();
2507*03ce13f7SAndroid Build Coastguard Worker Int b = function.Arg<1>();
2508*03ce13f7SAndroid Build Coastguard Worker Return(a + Float(b));
2509*03ce13f7SAndroid Build Coastguard Worker }
2510*03ce13f7SAndroid Build Coastguard Worker return function("%s2", testName().c_str());
2511*03ce13f7SAndroid Build Coastguard Worker }();
2512*03ce13f7SAndroid Build Coastguard Worker
2513*03ce13f7SAndroid Build Coastguard Worker struct Class
2514*03ce13f7SAndroid Build Coastguard Worker {
2515*03ce13f7SAndroid Build Coastguard Worker static float Func(void *p, float a, int b)
2516*03ce13f7SAndroid Build Coastguard Worker {
2517*03ce13f7SAndroid Build Coastguard Worker auto funcToCall = reinterpret_cast<float (*)(float, int)>(p);
2518*03ce13f7SAndroid Build Coastguard Worker return funcToCall(a, b);
2519*03ce13f7SAndroid Build Coastguard Worker }
2520*03ce13f7SAndroid Build Coastguard Worker };
2521*03ce13f7SAndroid Build Coastguard Worker
2522*03ce13f7SAndroid Build Coastguard Worker auto routine1 = [] {
2523*03ce13f7SAndroid Build Coastguard Worker FunctionT<float(void *, float, int)> function;
2524*03ce13f7SAndroid Build Coastguard Worker {
2525*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> funcToCall = function.Arg<0>();
2526*03ce13f7SAndroid Build Coastguard Worker Float a = function.Arg<1>();
2527*03ce13f7SAndroid Build Coastguard Worker Int b = function.Arg<2>();
2528*03ce13f7SAndroid Build Coastguard Worker Float result = Call(Class::Func, funcToCall, a, b);
2529*03ce13f7SAndroid Build Coastguard Worker Return(result);
2530*03ce13f7SAndroid Build Coastguard Worker }
2531*03ce13f7SAndroid Build Coastguard Worker return function(testName().c_str());
2532*03ce13f7SAndroid Build Coastguard Worker }();
2533*03ce13f7SAndroid Build Coastguard Worker
2534*03ce13f7SAndroid Build Coastguard Worker float result = routine1((void *)routine2.getEntry(), 12.f, 13);
2535*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 25.f);
2536*03ce13f7SAndroid Build Coastguard Worker }
2537*03ce13f7SAndroid Build Coastguard Worker
2538*03ce13f7SAndroid Build Coastguard Worker // Check that a complex generated function which utilizes all 8 or 16 XMM
2539*03ce13f7SAndroid Build Coastguard Worker // registers computes the correct result.
2540*03ce13f7SAndroid Build Coastguard Worker // (Note that due to MSC's lack of support for inline assembly in x64,
2541*03ce13f7SAndroid Build Coastguard Worker // this test does not actually check that the register contents are
2542*03ce13f7SAndroid Build Coastguard Worker // preserved, just that the generated function computes the correct value.
2543*03ce13f7SAndroid Build Coastguard Worker // It's necessary to inspect the registers in a debugger to actually verify.)
TEST(ReactorUnitTests,PreserveXMMRegisters)2544*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, PreserveXMMRegisters)
2545*03ce13f7SAndroid Build Coastguard Worker {
2546*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(void *, void *)> function;
2547*03ce13f7SAndroid Build Coastguard Worker {
2548*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> in = function.Arg<0>();
2549*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> out = function.Arg<1>();
2550*03ce13f7SAndroid Build Coastguard Worker
2551*03ce13f7SAndroid Build Coastguard Worker Float4 a = *Pointer<Float4>(in + 16 * 0);
2552*03ce13f7SAndroid Build Coastguard Worker Float4 b = *Pointer<Float4>(in + 16 * 1);
2553*03ce13f7SAndroid Build Coastguard Worker Float4 c = *Pointer<Float4>(in + 16 * 2);
2554*03ce13f7SAndroid Build Coastguard Worker Float4 d = *Pointer<Float4>(in + 16 * 3);
2555*03ce13f7SAndroid Build Coastguard Worker Float4 e = *Pointer<Float4>(in + 16 * 4);
2556*03ce13f7SAndroid Build Coastguard Worker Float4 f = *Pointer<Float4>(in + 16 * 5);
2557*03ce13f7SAndroid Build Coastguard Worker Float4 g = *Pointer<Float4>(in + 16 * 6);
2558*03ce13f7SAndroid Build Coastguard Worker Float4 h = *Pointer<Float4>(in + 16 * 7);
2559*03ce13f7SAndroid Build Coastguard Worker Float4 i = *Pointer<Float4>(in + 16 * 8);
2560*03ce13f7SAndroid Build Coastguard Worker Float4 j = *Pointer<Float4>(in + 16 * 9);
2561*03ce13f7SAndroid Build Coastguard Worker Float4 k = *Pointer<Float4>(in + 16 * 10);
2562*03ce13f7SAndroid Build Coastguard Worker Float4 l = *Pointer<Float4>(in + 16 * 11);
2563*03ce13f7SAndroid Build Coastguard Worker Float4 m = *Pointer<Float4>(in + 16 * 12);
2564*03ce13f7SAndroid Build Coastguard Worker Float4 n = *Pointer<Float4>(in + 16 * 13);
2565*03ce13f7SAndroid Build Coastguard Worker Float4 o = *Pointer<Float4>(in + 16 * 14);
2566*03ce13f7SAndroid Build Coastguard Worker Float4 p = *Pointer<Float4>(in + 16 * 15);
2567*03ce13f7SAndroid Build Coastguard Worker
2568*03ce13f7SAndroid Build Coastguard Worker Float4 ab = a + b;
2569*03ce13f7SAndroid Build Coastguard Worker Float4 cd = c + d;
2570*03ce13f7SAndroid Build Coastguard Worker Float4 ef = e + f;
2571*03ce13f7SAndroid Build Coastguard Worker Float4 gh = g + h;
2572*03ce13f7SAndroid Build Coastguard Worker Float4 ij = i + j;
2573*03ce13f7SAndroid Build Coastguard Worker Float4 kl = k + l;
2574*03ce13f7SAndroid Build Coastguard Worker Float4 mn = m + n;
2575*03ce13f7SAndroid Build Coastguard Worker Float4 op = o + p;
2576*03ce13f7SAndroid Build Coastguard Worker
2577*03ce13f7SAndroid Build Coastguard Worker Float4 abcd = ab + cd;
2578*03ce13f7SAndroid Build Coastguard Worker Float4 efgh = ef + gh;
2579*03ce13f7SAndroid Build Coastguard Worker Float4 ijkl = ij + kl;
2580*03ce13f7SAndroid Build Coastguard Worker Float4 mnop = mn + op;
2581*03ce13f7SAndroid Build Coastguard Worker
2582*03ce13f7SAndroid Build Coastguard Worker Float4 abcdefgh = abcd + efgh;
2583*03ce13f7SAndroid Build Coastguard Worker Float4 ijklmnop = ijkl + mnop;
2584*03ce13f7SAndroid Build Coastguard Worker Float4 sum = abcdefgh + ijklmnop;
2585*03ce13f7SAndroid Build Coastguard Worker *Pointer<Float4>(out) = sum;
2586*03ce13f7SAndroid Build Coastguard Worker Return();
2587*03ce13f7SAndroid Build Coastguard Worker }
2588*03ce13f7SAndroid Build Coastguard Worker
2589*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2590*03ce13f7SAndroid Build Coastguard Worker assert(routine);
2591*03ce13f7SAndroid Build Coastguard Worker
2592*03ce13f7SAndroid Build Coastguard Worker float input[64] = { 1.0f, 0.0f, 0.0f, 0.0f,
2593*03ce13f7SAndroid Build Coastguard Worker -1.0f, 1.0f, -1.0f, 0.0f,
2594*03ce13f7SAndroid Build Coastguard Worker 1.0f, 2.0f, -2.0f, 0.0f,
2595*03ce13f7SAndroid Build Coastguard Worker -1.0f, 3.0f, -3.0f, 0.0f,
2596*03ce13f7SAndroid Build Coastguard Worker 1.0f, 4.0f, -4.0f, 0.0f,
2597*03ce13f7SAndroid Build Coastguard Worker -1.0f, 5.0f, -5.0f, 0.0f,
2598*03ce13f7SAndroid Build Coastguard Worker 1.0f, 6.0f, -6.0f, 0.0f,
2599*03ce13f7SAndroid Build Coastguard Worker -1.0f, 7.0f, -7.0f, 0.0f,
2600*03ce13f7SAndroid Build Coastguard Worker 1.0f, 8.0f, -8.0f, 0.0f,
2601*03ce13f7SAndroid Build Coastguard Worker -1.0f, 9.0f, -9.0f, 0.0f,
2602*03ce13f7SAndroid Build Coastguard Worker 1.0f, 10.0f, -10.0f, 0.0f,
2603*03ce13f7SAndroid Build Coastguard Worker -1.0f, 11.0f, -11.0f, 0.0f,
2604*03ce13f7SAndroid Build Coastguard Worker 1.0f, 12.0f, -12.0f, 0.0f,
2605*03ce13f7SAndroid Build Coastguard Worker -1.0f, 13.0f, -13.0f, 0.0f,
2606*03ce13f7SAndroid Build Coastguard Worker 1.0f, 14.0f, -14.0f, 0.0f,
2607*03ce13f7SAndroid Build Coastguard Worker -1.0f, 15.0f, -15.0f, 0.0f };
2608*03ce13f7SAndroid Build Coastguard Worker
2609*03ce13f7SAndroid Build Coastguard Worker float result[4];
2610*03ce13f7SAndroid Build Coastguard Worker
2611*03ce13f7SAndroid Build Coastguard Worker routine(input, result);
2612*03ce13f7SAndroid Build Coastguard Worker
2613*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result[0], 0.0f);
2614*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result[1], 120.0f);
2615*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result[2], -120.0f);
2616*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result[3], 0.0f);
2617*03ce13f7SAndroid Build Coastguard Worker }
2618*03ce13f7SAndroid Build Coastguard Worker
2619*03ce13f7SAndroid Build Coastguard Worker template<typename T>
2620*03ce13f7SAndroid Build Coastguard Worker class CToReactorTCastTest : public ::testing::Test
2621*03ce13f7SAndroid Build Coastguard Worker {
2622*03ce13f7SAndroid Build Coastguard Worker public:
2623*03ce13f7SAndroid Build Coastguard Worker using CType = typename std::tuple_element<0, T>::type;
2624*03ce13f7SAndroid Build Coastguard Worker using ReactorType = typename std::tuple_element<1, T>::type;
2625*03ce13f7SAndroid Build Coastguard Worker };
2626*03ce13f7SAndroid Build Coastguard Worker
2627*03ce13f7SAndroid Build Coastguard Worker using CToReactorTCastTestTypes = ::testing::Types< // Subset of types that can be used as arguments.
2628*03ce13f7SAndroid Build Coastguard Worker // std::pair<bool, Bool>, FIXME(capn): Not supported as argument type by Subzero.
2629*03ce13f7SAndroid Build Coastguard Worker // std::pair<uint8_t, Byte>, FIXME(capn): Not supported as argument type by Subzero.
2630*03ce13f7SAndroid Build Coastguard Worker // std::pair<int8_t, SByte>, FIXME(capn): Not supported as argument type by Subzero.
2631*03ce13f7SAndroid Build Coastguard Worker // std::pair<int16_t, Short>, FIXME(capn): Not supported as argument type by Subzero.
2632*03ce13f7SAndroid Build Coastguard Worker // std::pair<uint16_t, UShort>, FIXME(capn): Not supported as argument type by Subzero.
2633*03ce13f7SAndroid Build Coastguard Worker std::pair<int, Int>,
2634*03ce13f7SAndroid Build Coastguard Worker std::pair<unsigned int, UInt>,
2635*03ce13f7SAndroid Build Coastguard Worker std::pair<float, Float>>;
2636*03ce13f7SAndroid Build Coastguard Worker
2637*03ce13f7SAndroid Build Coastguard Worker TYPED_TEST_SUITE(CToReactorTCastTest, CToReactorTCastTestTypes);
2638*03ce13f7SAndroid Build Coastguard Worker
TYPED_TEST(CToReactorTCastTest,Casts)2639*03ce13f7SAndroid Build Coastguard Worker TYPED_TEST(CToReactorTCastTest, Casts)
2640*03ce13f7SAndroid Build Coastguard Worker {
2641*03ce13f7SAndroid Build Coastguard Worker using CType = typename TestFixture::CType;
2642*03ce13f7SAndroid Build Coastguard Worker using ReactorType = typename TestFixture::ReactorType;
2643*03ce13f7SAndroid Build Coastguard Worker
2644*03ce13f7SAndroid Build Coastguard Worker std::shared_ptr<Routine> routine;
2645*03ce13f7SAndroid Build Coastguard Worker
2646*03ce13f7SAndroid Build Coastguard Worker {
2647*03ce13f7SAndroid Build Coastguard Worker Function<Int(ReactorType)> function;
2648*03ce13f7SAndroid Build Coastguard Worker {
2649*03ce13f7SAndroid Build Coastguard Worker ReactorType a = function.template Arg<0>();
2650*03ce13f7SAndroid Build Coastguard Worker ReactorType b = CType{};
2651*03ce13f7SAndroid Build Coastguard Worker RValue<ReactorType> c = RValue<ReactorType>(CType{});
2652*03ce13f7SAndroid Build Coastguard Worker Bool same = (a == b) && (a == c);
2653*03ce13f7SAndroid Build Coastguard Worker Return(IfThenElse(same, Int(1), Int(0))); // TODO: Ability to use Bools as return values.
2654*03ce13f7SAndroid Build Coastguard Worker }
2655*03ce13f7SAndroid Build Coastguard Worker
2656*03ce13f7SAndroid Build Coastguard Worker routine = function(testName().c_str());
2657*03ce13f7SAndroid Build Coastguard Worker
2658*03ce13f7SAndroid Build Coastguard Worker auto callable = (int (*)(CType))routine->getEntry();
2659*03ce13f7SAndroid Build Coastguard Worker CType in = {};
2660*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(callable(in), 1);
2661*03ce13f7SAndroid Build Coastguard Worker }
2662*03ce13f7SAndroid Build Coastguard Worker }
2663*03ce13f7SAndroid Build Coastguard Worker
2664*03ce13f7SAndroid Build Coastguard Worker template<typename T>
2665*03ce13f7SAndroid Build Coastguard Worker class GEPTest : public ::testing::Test
2666*03ce13f7SAndroid Build Coastguard Worker {
2667*03ce13f7SAndroid Build Coastguard Worker public:
2668*03ce13f7SAndroid Build Coastguard Worker using CType = typename std::tuple_element<0, T>::type;
2669*03ce13f7SAndroid Build Coastguard Worker using ReactorType = typename std::tuple_element<1, T>::type;
2670*03ce13f7SAndroid Build Coastguard Worker };
2671*03ce13f7SAndroid Build Coastguard Worker
2672*03ce13f7SAndroid Build Coastguard Worker using GEPTestTypes = ::testing::Types<
2673*03ce13f7SAndroid Build Coastguard Worker std::pair<bool, Bool>,
2674*03ce13f7SAndroid Build Coastguard Worker std::pair<int8_t, Byte>,
2675*03ce13f7SAndroid Build Coastguard Worker std::pair<int8_t, SByte>,
2676*03ce13f7SAndroid Build Coastguard Worker std::pair<int8_t[4], Byte4>,
2677*03ce13f7SAndroid Build Coastguard Worker std::pair<int8_t[4], SByte4>,
2678*03ce13f7SAndroid Build Coastguard Worker std::pair<int8_t[8], Byte8>,
2679*03ce13f7SAndroid Build Coastguard Worker std::pair<int8_t[8], SByte8>,
2680*03ce13f7SAndroid Build Coastguard Worker std::pair<int8_t[16], Byte16>,
2681*03ce13f7SAndroid Build Coastguard Worker std::pair<int8_t[16], SByte16>,
2682*03ce13f7SAndroid Build Coastguard Worker std::pair<int16_t, Short>,
2683*03ce13f7SAndroid Build Coastguard Worker std::pair<int16_t, UShort>,
2684*03ce13f7SAndroid Build Coastguard Worker std::pair<int16_t[2], Short2>,
2685*03ce13f7SAndroid Build Coastguard Worker std::pair<int16_t[2], UShort2>,
2686*03ce13f7SAndroid Build Coastguard Worker std::pair<int16_t[4], Short4>,
2687*03ce13f7SAndroid Build Coastguard Worker std::pair<int16_t[4], UShort4>,
2688*03ce13f7SAndroid Build Coastguard Worker std::pair<int16_t[8], Short8>,
2689*03ce13f7SAndroid Build Coastguard Worker std::pair<int16_t[8], UShort8>,
2690*03ce13f7SAndroid Build Coastguard Worker std::pair<int, Int>,
2691*03ce13f7SAndroid Build Coastguard Worker std::pair<int, UInt>,
2692*03ce13f7SAndroid Build Coastguard Worker std::pair<int[2], Int2>,
2693*03ce13f7SAndroid Build Coastguard Worker std::pair<int[2], UInt2>,
2694*03ce13f7SAndroid Build Coastguard Worker std::pair<int[4], Int4>,
2695*03ce13f7SAndroid Build Coastguard Worker std::pair<int[4], UInt4>,
2696*03ce13f7SAndroid Build Coastguard Worker std::pair<int64_t, Long>,
2697*03ce13f7SAndroid Build Coastguard Worker std::pair<int16_t, Half>,
2698*03ce13f7SAndroid Build Coastguard Worker std::pair<float, Float>,
2699*03ce13f7SAndroid Build Coastguard Worker std::pair<float[2], Float2>,
2700*03ce13f7SAndroid Build Coastguard Worker std::pair<float[4], Float4>>;
2701*03ce13f7SAndroid Build Coastguard Worker
2702*03ce13f7SAndroid Build Coastguard Worker TYPED_TEST_SUITE(GEPTest, GEPTestTypes);
2703*03ce13f7SAndroid Build Coastguard Worker
TYPED_TEST(GEPTest,PtrOffsets)2704*03ce13f7SAndroid Build Coastguard Worker TYPED_TEST(GEPTest, PtrOffsets)
2705*03ce13f7SAndroid Build Coastguard Worker {
2706*03ce13f7SAndroid Build Coastguard Worker using CType = typename TestFixture::CType;
2707*03ce13f7SAndroid Build Coastguard Worker using ReactorType = typename TestFixture::ReactorType;
2708*03ce13f7SAndroid Build Coastguard Worker
2709*03ce13f7SAndroid Build Coastguard Worker std::shared_ptr<Routine> routine;
2710*03ce13f7SAndroid Build Coastguard Worker
2711*03ce13f7SAndroid Build Coastguard Worker {
2712*03ce13f7SAndroid Build Coastguard Worker Function<Pointer<ReactorType>(Pointer<ReactorType>, Int)> function;
2713*03ce13f7SAndroid Build Coastguard Worker {
2714*03ce13f7SAndroid Build Coastguard Worker Pointer<ReactorType> pointer = function.template Arg<0>();
2715*03ce13f7SAndroid Build Coastguard Worker Int index = function.template Arg<1>();
2716*03ce13f7SAndroid Build Coastguard Worker Return(&pointer[index]);
2717*03ce13f7SAndroid Build Coastguard Worker }
2718*03ce13f7SAndroid Build Coastguard Worker
2719*03ce13f7SAndroid Build Coastguard Worker routine = function(testName().c_str());
2720*03ce13f7SAndroid Build Coastguard Worker
2721*03ce13f7SAndroid Build Coastguard Worker auto callable = (CType * (*)(CType *, unsigned int)) routine->getEntry();
2722*03ce13f7SAndroid Build Coastguard Worker
2723*03ce13f7SAndroid Build Coastguard Worker union PtrInt
2724*03ce13f7SAndroid Build Coastguard Worker {
2725*03ce13f7SAndroid Build Coastguard Worker CType *p;
2726*03ce13f7SAndroid Build Coastguard Worker size_t i;
2727*03ce13f7SAndroid Build Coastguard Worker };
2728*03ce13f7SAndroid Build Coastguard Worker
2729*03ce13f7SAndroid Build Coastguard Worker PtrInt base;
2730*03ce13f7SAndroid Build Coastguard Worker base.i = 0x10000;
2731*03ce13f7SAndroid Build Coastguard Worker
2732*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 5; i++)
2733*03ce13f7SAndroid Build Coastguard Worker {
2734*03ce13f7SAndroid Build Coastguard Worker PtrInt reference;
2735*03ce13f7SAndroid Build Coastguard Worker reference.p = &base.p[i];
2736*03ce13f7SAndroid Build Coastguard Worker
2737*03ce13f7SAndroid Build Coastguard Worker PtrInt result;
2738*03ce13f7SAndroid Build Coastguard Worker result.p = callable(base.p, i);
2739*03ce13f7SAndroid Build Coastguard Worker
2740*03ce13f7SAndroid Build Coastguard Worker auto expect = reference.i - base.i;
2741*03ce13f7SAndroid Build Coastguard Worker auto got = result.i - base.i;
2742*03ce13f7SAndroid Build Coastguard Worker
2743*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(got, expect) << "i:" << i;
2744*03ce13f7SAndroid Build Coastguard Worker }
2745*03ce13f7SAndroid Build Coastguard Worker }
2746*03ce13f7SAndroid Build Coastguard Worker }
2747*03ce13f7SAndroid Build Coastguard Worker
2748*03ce13f7SAndroid Build Coastguard Worker static const std::vector<int> fibonacci = {
2749*03ce13f7SAndroid Build Coastguard Worker 0,
2750*03ce13f7SAndroid Build Coastguard Worker 1,
2751*03ce13f7SAndroid Build Coastguard Worker 1,
2752*03ce13f7SAndroid Build Coastguard Worker 2,
2753*03ce13f7SAndroid Build Coastguard Worker 3,
2754*03ce13f7SAndroid Build Coastguard Worker 5,
2755*03ce13f7SAndroid Build Coastguard Worker 8,
2756*03ce13f7SAndroid Build Coastguard Worker 13,
2757*03ce13f7SAndroid Build Coastguard Worker 21,
2758*03ce13f7SAndroid Build Coastguard Worker 34,
2759*03ce13f7SAndroid Build Coastguard Worker 55,
2760*03ce13f7SAndroid Build Coastguard Worker 89,
2761*03ce13f7SAndroid Build Coastguard Worker 144,
2762*03ce13f7SAndroid Build Coastguard Worker 233,
2763*03ce13f7SAndroid Build Coastguard Worker 377,
2764*03ce13f7SAndroid Build Coastguard Worker 610,
2765*03ce13f7SAndroid Build Coastguard Worker 987,
2766*03ce13f7SAndroid Build Coastguard Worker 1597,
2767*03ce13f7SAndroid Build Coastguard Worker 2584,
2768*03ce13f7SAndroid Build Coastguard Worker 4181,
2769*03ce13f7SAndroid Build Coastguard Worker 6765,
2770*03ce13f7SAndroid Build Coastguard Worker 10946,
2771*03ce13f7SAndroid Build Coastguard Worker 17711,
2772*03ce13f7SAndroid Build Coastguard Worker 28657,
2773*03ce13f7SAndroid Build Coastguard Worker 46368,
2774*03ce13f7SAndroid Build Coastguard Worker 75025,
2775*03ce13f7SAndroid Build Coastguard Worker 121393,
2776*03ce13f7SAndroid Build Coastguard Worker 196418,
2777*03ce13f7SAndroid Build Coastguard Worker 317811,
2778*03ce13f7SAndroid Build Coastguard Worker };
2779*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Fibonacci)2780*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Fibonacci)
2781*03ce13f7SAndroid Build Coastguard Worker {
2782*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int)> function;
2783*03ce13f7SAndroid Build Coastguard Worker {
2784*03ce13f7SAndroid Build Coastguard Worker Int n = function.Arg<0>();
2785*03ce13f7SAndroid Build Coastguard Worker Int current = 0;
2786*03ce13f7SAndroid Build Coastguard Worker Int next = 1;
2787*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < n, i++)
2788*03ce13f7SAndroid Build Coastguard Worker {
2789*03ce13f7SAndroid Build Coastguard Worker auto tmp = current + next;
2790*03ce13f7SAndroid Build Coastguard Worker current = next;
2791*03ce13f7SAndroid Build Coastguard Worker next = tmp;
2792*03ce13f7SAndroid Build Coastguard Worker }
2793*03ce13f7SAndroid Build Coastguard Worker Return(current);
2794*03ce13f7SAndroid Build Coastguard Worker }
2795*03ce13f7SAndroid Build Coastguard Worker
2796*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
2797*03ce13f7SAndroid Build Coastguard Worker
2798*03ce13f7SAndroid Build Coastguard Worker for(size_t i = 0; i < fibonacci.size(); i++)
2799*03ce13f7SAndroid Build Coastguard Worker {
2800*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(routine(i), fibonacci[i]);
2801*03ce13f7SAndroid Build Coastguard Worker }
2802*03ce13f7SAndroid Build Coastguard Worker }
2803*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Coroutines_Fibonacci)2804*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Coroutines_Fibonacci)
2805*03ce13f7SAndroid Build Coastguard Worker {
2806*03ce13f7SAndroid Build Coastguard Worker if(!rr::Caps::coroutinesSupported())
2807*03ce13f7SAndroid Build Coastguard Worker {
2808*03ce13f7SAndroid Build Coastguard Worker SUCCEED() << "Coroutines not supported";
2809*03ce13f7SAndroid Build Coastguard Worker return;
2810*03ce13f7SAndroid Build Coastguard Worker }
2811*03ce13f7SAndroid Build Coastguard Worker
2812*03ce13f7SAndroid Build Coastguard Worker Coroutine<int()> function;
2813*03ce13f7SAndroid Build Coastguard Worker {
2814*03ce13f7SAndroid Build Coastguard Worker Yield(Int(0));
2815*03ce13f7SAndroid Build Coastguard Worker Yield(Int(1));
2816*03ce13f7SAndroid Build Coastguard Worker Int current = 1;
2817*03ce13f7SAndroid Build Coastguard Worker Int next = 1;
2818*03ce13f7SAndroid Build Coastguard Worker While(true)
2819*03ce13f7SAndroid Build Coastguard Worker {
2820*03ce13f7SAndroid Build Coastguard Worker Yield(next);
2821*03ce13f7SAndroid Build Coastguard Worker auto tmp = current + next;
2822*03ce13f7SAndroid Build Coastguard Worker current = next;
2823*03ce13f7SAndroid Build Coastguard Worker next = tmp;
2824*03ce13f7SAndroid Build Coastguard Worker }
2825*03ce13f7SAndroid Build Coastguard Worker }
2826*03ce13f7SAndroid Build Coastguard Worker function.finalize(testName().c_str());
2827*03ce13f7SAndroid Build Coastguard Worker
2828*03ce13f7SAndroid Build Coastguard Worker auto coroutine = function();
2829*03ce13f7SAndroid Build Coastguard Worker
2830*03ce13f7SAndroid Build Coastguard Worker for(size_t i = 0; i < fibonacci.size(); i++)
2831*03ce13f7SAndroid Build Coastguard Worker {
2832*03ce13f7SAndroid Build Coastguard Worker int out = 0;
2833*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(coroutine->await(out), true);
2834*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, fibonacci[i]);
2835*03ce13f7SAndroid Build Coastguard Worker }
2836*03ce13f7SAndroid Build Coastguard Worker }
2837*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Coroutines_Parameters)2838*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Coroutines_Parameters)
2839*03ce13f7SAndroid Build Coastguard Worker {
2840*03ce13f7SAndroid Build Coastguard Worker if(!rr::Caps::coroutinesSupported())
2841*03ce13f7SAndroid Build Coastguard Worker {
2842*03ce13f7SAndroid Build Coastguard Worker SUCCEED() << "Coroutines not supported";
2843*03ce13f7SAndroid Build Coastguard Worker return;
2844*03ce13f7SAndroid Build Coastguard Worker }
2845*03ce13f7SAndroid Build Coastguard Worker
2846*03ce13f7SAndroid Build Coastguard Worker Coroutine<uint8_t(uint8_t * data, int count)> function;
2847*03ce13f7SAndroid Build Coastguard Worker {
2848*03ce13f7SAndroid Build Coastguard Worker Pointer<Byte> data = function.Arg<0>();
2849*03ce13f7SAndroid Build Coastguard Worker Int count = function.Arg<1>();
2850*03ce13f7SAndroid Build Coastguard Worker
2851*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < count, i++)
2852*03ce13f7SAndroid Build Coastguard Worker {
2853*03ce13f7SAndroid Build Coastguard Worker Yield(data[i]);
2854*03ce13f7SAndroid Build Coastguard Worker }
2855*03ce13f7SAndroid Build Coastguard Worker }
2856*03ce13f7SAndroid Build Coastguard Worker function.finalize(testName().c_str());
2857*03ce13f7SAndroid Build Coastguard Worker
2858*03ce13f7SAndroid Build Coastguard Worker uint8_t data[] = { 10, 20, 30 };
2859*03ce13f7SAndroid Build Coastguard Worker auto coroutine = function(&data[0], 3);
2860*03ce13f7SAndroid Build Coastguard Worker
2861*03ce13f7SAndroid Build Coastguard Worker uint8_t out = 0;
2862*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(coroutine->await(out), true);
2863*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, 10);
2864*03ce13f7SAndroid Build Coastguard Worker out = 0;
2865*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(coroutine->await(out), true);
2866*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, 20);
2867*03ce13f7SAndroid Build Coastguard Worker out = 0;
2868*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(coroutine->await(out), true);
2869*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, 30);
2870*03ce13f7SAndroid Build Coastguard Worker out = 99;
2871*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(coroutine->await(out), false);
2872*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, 99);
2873*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(coroutine->await(out), false);
2874*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, 99);
2875*03ce13f7SAndroid Build Coastguard Worker }
2876*03ce13f7SAndroid Build Coastguard Worker
2877*03ce13f7SAndroid Build Coastguard Worker // This test was written because Subzero's handling of vector types
2878*03ce13f7SAndroid Build Coastguard Worker // failed when more than one function is generated, as is the case
2879*03ce13f7SAndroid Build Coastguard Worker // with coroutines.
TEST(ReactorUnitTests,Coroutines_Vectors)2880*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Coroutines_Vectors)
2881*03ce13f7SAndroid Build Coastguard Worker {
2882*03ce13f7SAndroid Build Coastguard Worker if(!rr::Caps::coroutinesSupported())
2883*03ce13f7SAndroid Build Coastguard Worker {
2884*03ce13f7SAndroid Build Coastguard Worker SUCCEED() << "Coroutines not supported";
2885*03ce13f7SAndroid Build Coastguard Worker return;
2886*03ce13f7SAndroid Build Coastguard Worker }
2887*03ce13f7SAndroid Build Coastguard Worker
2888*03ce13f7SAndroid Build Coastguard Worker Coroutine<int()> function;
2889*03ce13f7SAndroid Build Coastguard Worker {
2890*03ce13f7SAndroid Build Coastguard Worker Int4 a{ 1, 2, 3, 4 };
2891*03ce13f7SAndroid Build Coastguard Worker Yield(rr::Extract(a, 2));
2892*03ce13f7SAndroid Build Coastguard Worker Int4 b{ 5, 6, 7, 8 };
2893*03ce13f7SAndroid Build Coastguard Worker Yield(rr::Extract(b, 1));
2894*03ce13f7SAndroid Build Coastguard Worker Int4 c{ 9, 10, 11, 12 };
2895*03ce13f7SAndroid Build Coastguard Worker Yield(rr::Extract(c, 1));
2896*03ce13f7SAndroid Build Coastguard Worker }
2897*03ce13f7SAndroid Build Coastguard Worker function.finalize(testName().c_str());
2898*03ce13f7SAndroid Build Coastguard Worker
2899*03ce13f7SAndroid Build Coastguard Worker auto coroutine = function();
2900*03ce13f7SAndroid Build Coastguard Worker
2901*03ce13f7SAndroid Build Coastguard Worker int out;
2902*03ce13f7SAndroid Build Coastguard Worker coroutine->await(out);
2903*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, 3);
2904*03ce13f7SAndroid Build Coastguard Worker coroutine->await(out);
2905*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, 6);
2906*03ce13f7SAndroid Build Coastguard Worker coroutine->await(out);
2907*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, 10);
2908*03ce13f7SAndroid Build Coastguard Worker }
2909*03ce13f7SAndroid Build Coastguard Worker
2910*03ce13f7SAndroid Build Coastguard Worker // This test was written to make sure a coroutine without a Yield()
2911*03ce13f7SAndroid Build Coastguard Worker // works correctly, by executing like a regular function with no
2912*03ce13f7SAndroid Build Coastguard Worker // return (the return type is ignored).
2913*03ce13f7SAndroid Build Coastguard Worker // We also run it twice to ensure per instance and/or global state
2914*03ce13f7SAndroid Build Coastguard Worker // is properly cleaned up in between.
TEST(ReactorUnitTests,Coroutines_NoYield)2915*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Coroutines_NoYield)
2916*03ce13f7SAndroid Build Coastguard Worker {
2917*03ce13f7SAndroid Build Coastguard Worker if(!rr::Caps::coroutinesSupported())
2918*03ce13f7SAndroid Build Coastguard Worker {
2919*03ce13f7SAndroid Build Coastguard Worker SUCCEED() << "Coroutines not supported";
2920*03ce13f7SAndroid Build Coastguard Worker return;
2921*03ce13f7SAndroid Build Coastguard Worker }
2922*03ce13f7SAndroid Build Coastguard Worker
2923*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < 2; ++i)
2924*03ce13f7SAndroid Build Coastguard Worker {
2925*03ce13f7SAndroid Build Coastguard Worker Coroutine<int()> function;
2926*03ce13f7SAndroid Build Coastguard Worker {
2927*03ce13f7SAndroid Build Coastguard Worker Int a;
2928*03ce13f7SAndroid Build Coastguard Worker a = 4;
2929*03ce13f7SAndroid Build Coastguard Worker }
2930*03ce13f7SAndroid Build Coastguard Worker function.finalize(testName().c_str());
2931*03ce13f7SAndroid Build Coastguard Worker
2932*03ce13f7SAndroid Build Coastguard Worker auto coroutine = function();
2933*03ce13f7SAndroid Build Coastguard Worker int out;
2934*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(coroutine->await(out), false);
2935*03ce13f7SAndroid Build Coastguard Worker }
2936*03ce13f7SAndroid Build Coastguard Worker }
2937*03ce13f7SAndroid Build Coastguard Worker
2938*03ce13f7SAndroid Build Coastguard Worker // Test generating one coroutine, and executing it on multiple threads. This makes
2939*03ce13f7SAndroid Build Coastguard Worker // sure the implementation manages per-call instance data correctly.
TEST(ReactorUnitTests,Coroutines_Parallel)2940*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Coroutines_Parallel)
2941*03ce13f7SAndroid Build Coastguard Worker {
2942*03ce13f7SAndroid Build Coastguard Worker if(!rr::Caps::coroutinesSupported())
2943*03ce13f7SAndroid Build Coastguard Worker {
2944*03ce13f7SAndroid Build Coastguard Worker SUCCEED() << "Coroutines not supported";
2945*03ce13f7SAndroid Build Coastguard Worker return;
2946*03ce13f7SAndroid Build Coastguard Worker }
2947*03ce13f7SAndroid Build Coastguard Worker
2948*03ce13f7SAndroid Build Coastguard Worker Coroutine<int()> function;
2949*03ce13f7SAndroid Build Coastguard Worker {
2950*03ce13f7SAndroid Build Coastguard Worker Yield(Int(0));
2951*03ce13f7SAndroid Build Coastguard Worker Yield(Int(1));
2952*03ce13f7SAndroid Build Coastguard Worker Int current = 1;
2953*03ce13f7SAndroid Build Coastguard Worker Int next = 1;
2954*03ce13f7SAndroid Build Coastguard Worker While(true)
2955*03ce13f7SAndroid Build Coastguard Worker {
2956*03ce13f7SAndroid Build Coastguard Worker Yield(next);
2957*03ce13f7SAndroid Build Coastguard Worker auto tmp = current + next;
2958*03ce13f7SAndroid Build Coastguard Worker current = next;
2959*03ce13f7SAndroid Build Coastguard Worker next = tmp;
2960*03ce13f7SAndroid Build Coastguard Worker }
2961*03ce13f7SAndroid Build Coastguard Worker }
2962*03ce13f7SAndroid Build Coastguard Worker
2963*03ce13f7SAndroid Build Coastguard Worker // Must call on same thread that creates the coroutine
2964*03ce13f7SAndroid Build Coastguard Worker function.finalize(testName().c_str());
2965*03ce13f7SAndroid Build Coastguard Worker
2966*03ce13f7SAndroid Build Coastguard Worker std::vector<std::thread> threads;
2967*03ce13f7SAndroid Build Coastguard Worker const size_t numThreads = 100;
2968*03ce13f7SAndroid Build Coastguard Worker
2969*03ce13f7SAndroid Build Coastguard Worker for(size_t t = 0; t < numThreads; ++t)
2970*03ce13f7SAndroid Build Coastguard Worker {
2971*03ce13f7SAndroid Build Coastguard Worker threads.emplace_back([&] {
2972*03ce13f7SAndroid Build Coastguard Worker auto coroutine = function();
2973*03ce13f7SAndroid Build Coastguard Worker
2974*03ce13f7SAndroid Build Coastguard Worker for(size_t i = 0; i < fibonacci.size(); i++)
2975*03ce13f7SAndroid Build Coastguard Worker {
2976*03ce13f7SAndroid Build Coastguard Worker int out = 0;
2977*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(coroutine->await(out), true);
2978*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(out, fibonacci[i]);
2979*03ce13f7SAndroid Build Coastguard Worker }
2980*03ce13f7SAndroid Build Coastguard Worker });
2981*03ce13f7SAndroid Build Coastguard Worker }
2982*03ce13f7SAndroid Build Coastguard Worker
2983*03ce13f7SAndroid Build Coastguard Worker for(auto &t : threads)
2984*03ce13f7SAndroid Build Coastguard Worker {
2985*03ce13f7SAndroid Build Coastguard Worker t.join();
2986*03ce13f7SAndroid Build Coastguard Worker }
2987*03ce13f7SAndroid Build Coastguard Worker }
2988*03ce13f7SAndroid Build Coastguard Worker
2989*03ce13f7SAndroid Build Coastguard Worker template<typename TestFuncType, typename RefFuncType, typename TestValueType>
2990*03ce13f7SAndroid Build Coastguard Worker struct IntrinsicTestParams
2991*03ce13f7SAndroid Build Coastguard Worker {
2992*03ce13f7SAndroid Build Coastguard Worker std::function<TestFuncType> testFunc; // Function we're testing (Reactor)
2993*03ce13f7SAndroid Build Coastguard Worker std::function<RefFuncType> refFunc; // Reference function to test against (C)
2994*03ce13f7SAndroid Build Coastguard Worker std::vector<TestValueType> testValues; // Values to input to functions
2995*03ce13f7SAndroid Build Coastguard Worker };
2996*03ce13f7SAndroid Build Coastguard Worker
2997*03ce13f7SAndroid Build Coastguard Worker using IntrinsicTestParams_Float = IntrinsicTestParams<RValue<Float>(RValue<Float>), float(float), float>;
2998*03ce13f7SAndroid Build Coastguard Worker using IntrinsicTestParams_Float4 = IntrinsicTestParams<RValue<Float4>(RValue<Float4>), float(float), float>;
2999*03ce13f7SAndroid Build Coastguard Worker using IntrinsicTestParams_Float4_Float4 = IntrinsicTestParams<RValue<Float4>(RValue<Float4>, RValue<Float4>), float(float, float), std::pair<float, float>>;
3000*03ce13f7SAndroid Build Coastguard Worker
3001*03ce13f7SAndroid Build Coastguard Worker // TODO(b/147818976): Each function has its own precision requirements for Vulkan, sometimes broken down
3002*03ce13f7SAndroid Build Coastguard Worker // by input range. These are currently validated by deqp, but we can improve our own tests as well.
3003*03ce13f7SAndroid Build Coastguard Worker // See https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#spirvenv-precision-operation
3004*03ce13f7SAndroid Build Coastguard Worker constexpr double INTRINSIC_PRECISION = 1e-4;
3005*03ce13f7SAndroid Build Coastguard Worker
3006*03ce13f7SAndroid Build Coastguard Worker struct IntrinsicTest_Float : public testing::TestWithParam<IntrinsicTestParams_Float>
3007*03ce13f7SAndroid Build Coastguard Worker {
testIntrinsicTest_Float3008*03ce13f7SAndroid Build Coastguard Worker void test()
3009*03ce13f7SAndroid Build Coastguard Worker {
3010*03ce13f7SAndroid Build Coastguard Worker FunctionT<float(float)> function;
3011*03ce13f7SAndroid Build Coastguard Worker {
3012*03ce13f7SAndroid Build Coastguard Worker Return(GetParam().testFunc((Float(function.Arg<0>()))));
3013*03ce13f7SAndroid Build Coastguard Worker }
3014*03ce13f7SAndroid Build Coastguard Worker
3015*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3016*03ce13f7SAndroid Build Coastguard Worker
3017*03ce13f7SAndroid Build Coastguard Worker for(auto &&v : GetParam().testValues)
3018*03ce13f7SAndroid Build Coastguard Worker {
3019*03ce13f7SAndroid Build Coastguard Worker SCOPED_TRACE(v);
3020*03ce13f7SAndroid Build Coastguard Worker EXPECT_NEAR(routine(v), GetParam().refFunc(v), INTRINSIC_PRECISION);
3021*03ce13f7SAndroid Build Coastguard Worker }
3022*03ce13f7SAndroid Build Coastguard Worker }
3023*03ce13f7SAndroid Build Coastguard Worker };
3024*03ce13f7SAndroid Build Coastguard Worker
3025*03ce13f7SAndroid Build Coastguard Worker // TODO: Move to Reactor.hpp
3026*03ce13f7SAndroid Build Coastguard Worker template<>
3027*03ce13f7SAndroid Build Coastguard Worker struct rr::CToReactor<int[4]>
3028*03ce13f7SAndroid Build Coastguard Worker {
3029*03ce13f7SAndroid Build Coastguard Worker using type = Int4;
3030*03ce13f7SAndroid Build Coastguard Worker static Int4 cast(float[4]);
3031*03ce13f7SAndroid Build Coastguard Worker };
3032*03ce13f7SAndroid Build Coastguard Worker
3033*03ce13f7SAndroid Build Coastguard Worker // Value type wrapper around a <type>[4] (i.e. float4, int4)
3034*03ce13f7SAndroid Build Coastguard Worker template<typename T>
3035*03ce13f7SAndroid Build Coastguard Worker struct type4_value
3036*03ce13f7SAndroid Build Coastguard Worker {
3037*03ce13f7SAndroid Build Coastguard Worker using E = typename std::remove_pointer_t<std::decay_t<T>>;
3038*03ce13f7SAndroid Build Coastguard Worker
3039*03ce13f7SAndroid Build Coastguard Worker type4_value() = default;
type4_valuetype4_value3040*03ce13f7SAndroid Build Coastguard Worker explicit type4_value(E rep)
3041*03ce13f7SAndroid Build Coastguard Worker : v{ rep, rep, rep, rep }
3042*03ce13f7SAndroid Build Coastguard Worker {}
type4_valuetype4_value3043*03ce13f7SAndroid Build Coastguard Worker type4_value(E x, E y, E z, E w)
3044*03ce13f7SAndroid Build Coastguard Worker : v{ x, y, z, w }
3045*03ce13f7SAndroid Build Coastguard Worker {}
3046*03ce13f7SAndroid Build Coastguard Worker
operator ==type4_value3047*03ce13f7SAndroid Build Coastguard Worker bool operator==(const type4_value &rhs) const
3048*03ce13f7SAndroid Build Coastguard Worker {
3049*03ce13f7SAndroid Build Coastguard Worker return std::equal(std::begin(v), std::end(v), rhs.v);
3050*03ce13f7SAndroid Build Coastguard Worker }
3051*03ce13f7SAndroid Build Coastguard Worker
3052*03ce13f7SAndroid Build Coastguard Worker // For gtest printing
operator <<(std::ostream & os,const type4_value & value)3053*03ce13f7SAndroid Build Coastguard Worker friend std::ostream &operator<<(std::ostream &os, const type4_value &value)
3054*03ce13f7SAndroid Build Coastguard Worker {
3055*03ce13f7SAndroid Build Coastguard Worker return os << "[" << value.v[0] << ", " << value.v[1] << ", " << value.v[2] << ", " << value.v[3] << "]";
3056*03ce13f7SAndroid Build Coastguard Worker }
3057*03ce13f7SAndroid Build Coastguard Worker
3058*03ce13f7SAndroid Build Coastguard Worker T v;
3059*03ce13f7SAndroid Build Coastguard Worker };
3060*03ce13f7SAndroid Build Coastguard Worker
3061*03ce13f7SAndroid Build Coastguard Worker using float4_value = type4_value<float4>;
3062*03ce13f7SAndroid Build Coastguard Worker using int4_value = type4_value<int4>;
3063*03ce13f7SAndroid Build Coastguard Worker
3064*03ce13f7SAndroid Build Coastguard Worker // Invoke a void(type4_value<T>*) routine on &v.v, returning wrapped result in v
3065*03ce13f7SAndroid Build Coastguard Worker template<typename RoutineType, typename T>
invokeRoutine(RoutineType & routine,type4_value<T> v)3066*03ce13f7SAndroid Build Coastguard Worker type4_value<T> invokeRoutine(RoutineType &routine, type4_value<T> v)
3067*03ce13f7SAndroid Build Coastguard Worker {
3068*03ce13f7SAndroid Build Coastguard Worker routine(&v.v);
3069*03ce13f7SAndroid Build Coastguard Worker return v;
3070*03ce13f7SAndroid Build Coastguard Worker }
3071*03ce13f7SAndroid Build Coastguard Worker
3072*03ce13f7SAndroid Build Coastguard Worker // Invoke a void(type4_value<T>*, type4_value<T>*) routine on &v1.v, &v2.v returning wrapped result in v1
3073*03ce13f7SAndroid Build Coastguard Worker template<typename RoutineType, typename T>
invokeRoutine(RoutineType & routine,type4_value<T> v1,type4_value<T> v2)3074*03ce13f7SAndroid Build Coastguard Worker type4_value<T> invokeRoutine(RoutineType &routine, type4_value<T> v1, type4_value<T> v2)
3075*03ce13f7SAndroid Build Coastguard Worker {
3076*03ce13f7SAndroid Build Coastguard Worker routine(&v1.v, &v2.v);
3077*03ce13f7SAndroid Build Coastguard Worker return v1;
3078*03ce13f7SAndroid Build Coastguard Worker }
3079*03ce13f7SAndroid Build Coastguard Worker
3080*03ce13f7SAndroid Build Coastguard Worker struct IntrinsicTest_Float4 : public testing::TestWithParam<IntrinsicTestParams_Float4>
3081*03ce13f7SAndroid Build Coastguard Worker {
testIntrinsicTest_Float43082*03ce13f7SAndroid Build Coastguard Worker void test()
3083*03ce13f7SAndroid Build Coastguard Worker {
3084*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(float4 *)> function;
3085*03ce13f7SAndroid Build Coastguard Worker {
3086*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> a = function.Arg<0>();
3087*03ce13f7SAndroid Build Coastguard Worker *a = GetParam().testFunc(*a);
3088*03ce13f7SAndroid Build Coastguard Worker Return();
3089*03ce13f7SAndroid Build Coastguard Worker }
3090*03ce13f7SAndroid Build Coastguard Worker
3091*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3092*03ce13f7SAndroid Build Coastguard Worker
3093*03ce13f7SAndroid Build Coastguard Worker for(auto &&v : GetParam().testValues)
3094*03ce13f7SAndroid Build Coastguard Worker {
3095*03ce13f7SAndroid Build Coastguard Worker SCOPED_TRACE(v);
3096*03ce13f7SAndroid Build Coastguard Worker float4_value result = invokeRoutine(routine, float4_value{ v });
3097*03ce13f7SAndroid Build Coastguard Worker float4_value expected = float4_value{ GetParam().refFunc(v) };
3098*03ce13f7SAndroid Build Coastguard Worker EXPECT_NEAR(result.v[0], expected.v[0], INTRINSIC_PRECISION);
3099*03ce13f7SAndroid Build Coastguard Worker EXPECT_NEAR(result.v[1], expected.v[1], INTRINSIC_PRECISION);
3100*03ce13f7SAndroid Build Coastguard Worker EXPECT_NEAR(result.v[2], expected.v[2], INTRINSIC_PRECISION);
3101*03ce13f7SAndroid Build Coastguard Worker EXPECT_NEAR(result.v[3], expected.v[3], INTRINSIC_PRECISION);
3102*03ce13f7SAndroid Build Coastguard Worker }
3103*03ce13f7SAndroid Build Coastguard Worker }
3104*03ce13f7SAndroid Build Coastguard Worker };
3105*03ce13f7SAndroid Build Coastguard Worker
3106*03ce13f7SAndroid Build Coastguard Worker struct IntrinsicTest_Float4_Float4 : public testing::TestWithParam<IntrinsicTestParams_Float4_Float4>
3107*03ce13f7SAndroid Build Coastguard Worker {
testIntrinsicTest_Float4_Float43108*03ce13f7SAndroid Build Coastguard Worker void test()
3109*03ce13f7SAndroid Build Coastguard Worker {
3110*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(float4 *, float4 *)> function;
3111*03ce13f7SAndroid Build Coastguard Worker {
3112*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> a = function.Arg<0>();
3113*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> b = function.Arg<1>();
3114*03ce13f7SAndroid Build Coastguard Worker *a = GetParam().testFunc(*a, *b);
3115*03ce13f7SAndroid Build Coastguard Worker Return();
3116*03ce13f7SAndroid Build Coastguard Worker }
3117*03ce13f7SAndroid Build Coastguard Worker
3118*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3119*03ce13f7SAndroid Build Coastguard Worker
3120*03ce13f7SAndroid Build Coastguard Worker for(auto &&v : GetParam().testValues)
3121*03ce13f7SAndroid Build Coastguard Worker {
3122*03ce13f7SAndroid Build Coastguard Worker SCOPED_TRACE(v);
3123*03ce13f7SAndroid Build Coastguard Worker float4_value result = invokeRoutine(routine, float4_value{ v.first }, float4_value{ v.second });
3124*03ce13f7SAndroid Build Coastguard Worker float4_value expected = float4_value{ GetParam().refFunc(v.first, v.second) };
3125*03ce13f7SAndroid Build Coastguard Worker EXPECT_NEAR(result.v[0], expected.v[0], INTRINSIC_PRECISION);
3126*03ce13f7SAndroid Build Coastguard Worker EXPECT_NEAR(result.v[1], expected.v[1], INTRINSIC_PRECISION);
3127*03ce13f7SAndroid Build Coastguard Worker EXPECT_NEAR(result.v[2], expected.v[2], INTRINSIC_PRECISION);
3128*03ce13f7SAndroid Build Coastguard Worker EXPECT_NEAR(result.v[3], expected.v[3], INTRINSIC_PRECISION);
3129*03ce13f7SAndroid Build Coastguard Worker }
3130*03ce13f7SAndroid Build Coastguard Worker }
3131*03ce13f7SAndroid Build Coastguard Worker };
3132*03ce13f7SAndroid Build Coastguard Worker
3133*03ce13f7SAndroid Build Coastguard Worker // clang-format off
3134*03ce13f7SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(IntrinsicTestParams_Float, IntrinsicTest_Float, testing::Values(
__anon5ddac1420e02(Float v) 3135*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float{ [](Float v) { return rr::Exp2(v); }, exp2f, {0.f, 1.f, 123.f} },
__anon5ddac1421002(Float v) 3136*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float{ [](Float v) { return rr::Log2(v); }, log2f, {1.f, 123.f} },
__anon5ddac1421102(Float v) 3137*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float{ [](Float v) { return rr::Sqrt(v); }, sqrtf, {0.f, 1.f, 123.f} }
3138*03ce13f7SAndroid Build Coastguard Worker ));
3139*03ce13f7SAndroid Build Coastguard Worker // clang-format on
3140*03ce13f7SAndroid Build Coastguard Worker
3141*03ce13f7SAndroid Build Coastguard Worker // TODO(b/149110874) Use coshf/sinhf when we've implemented SpirV versions at the SpirV level
vulkan_sinhf(float a)3142*03ce13f7SAndroid Build Coastguard Worker float vulkan_sinhf(float a)
3143*03ce13f7SAndroid Build Coastguard Worker {
3144*03ce13f7SAndroid Build Coastguard Worker return ((expf(a) - expf(-a)) / 2);
3145*03ce13f7SAndroid Build Coastguard Worker }
vulkan_coshf(float a)3146*03ce13f7SAndroid Build Coastguard Worker float vulkan_coshf(float a)
3147*03ce13f7SAndroid Build Coastguard Worker {
3148*03ce13f7SAndroid Build Coastguard Worker return ((expf(a) + expf(-a)) / 2);
3149*03ce13f7SAndroid Build Coastguard Worker }
3150*03ce13f7SAndroid Build Coastguard Worker
3151*03ce13f7SAndroid Build Coastguard Worker // clang-format off
3152*03ce13f7SAndroid Build Coastguard Worker constexpr float PI = 3.141592653589793f;
3153*03ce13f7SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(IntrinsicTestParams_Float4, IntrinsicTest_Float4, testing::Values(
__anon5ddac1421302(RValue<Float4> v) 3154*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Sin(v); }, sinf, {0.f, 1.f, PI, 123.f} },
__anon5ddac1421502(RValue<Float4> v) 3155*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Cos(v); }, cosf, {0.f, 1.f, PI, 123.f} },
__anon5ddac1421702(RValue<Float4> v) 3156*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Tan(v); }, tanf, {0.f, 1.f, PI, 123.f} },
__anon5ddac1421a02(RValue<Float4> v) 3157*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Asin(v); }, asinf, {0.f, 1.f, -1.f} },
__anon5ddac1421b02(RValue<Float4> v) 3158*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Acos(v); }, acosf, {0.f, 1.f, -1.f} },
__anon5ddac1421d02(RValue<Float4> v) 3159*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Atan(v); }, atanf, {0.f, 1.f, PI, 123.f} },
__anon5ddac1422002(RValue<Float4> v) 3160*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Sinh(v); }, vulkan_sinhf, {0.f, 1.f, PI} },
__anon5ddac1422102(RValue<Float4> v) 3161*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Cosh(v); }, vulkan_coshf, {0.f, 1.f, PI} },
__anon5ddac1422302(RValue<Float4> v) 3162*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Tanh(v); }, tanhf, {0.f, 1.f, PI} },
__anon5ddac1422502(RValue<Float4> v) 3163*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Asinh(v); }, asinhf, {0.f, 1.f, PI, 123.f} },
__anon5ddac1422802(RValue<Float4> v) 3164*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Acosh(v); }, acoshf, { 1.f, PI, 123.f} },
__anon5ddac1422a02(RValue<Float4> v) 3165*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Atanh(v); }, atanhf, {0.f, 0.9999f, -0.9999f} },
__anon5ddac1422b02(RValue<Float4> v) 3166*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Exp(v); }, expf, {0.f, 1.f, PI} },
__anon5ddac1422d02(RValue<Float4> v) 3167*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Log(v); }, logf, {1.f, PI, 123.f} },
__anon5ddac1423002(RValue<Float4> v) 3168*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Exp2(v); }, exp2f, {0.f, 1.f, PI, 123.f} },
__anon5ddac1423202(RValue<Float4> v) 3169*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Log2(v); }, log2f, {1.f, PI, 123.f} },
__anon5ddac1423402(RValue<Float4> v) 3170*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4{ [](RValue<Float4> v) { return rr::Sqrt(v); }, sqrtf, {0.f, 1.f, PI, 123.f} }
3171*03ce13f7SAndroid Build Coastguard Worker ));
3172*03ce13f7SAndroid Build Coastguard Worker // clang-format on
3173*03ce13f7SAndroid Build Coastguard Worker
3174*03ce13f7SAndroid Build Coastguard Worker // clang-format off
3175*03ce13f7SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(IntrinsicTestParams_Float4_Float4, IntrinsicTest_Float4_Float4, testing::Values(
__anon5ddac1423602(RValue<Float4> v1, RValue<Float4> v2) 3176*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4_Float4{ [](RValue<Float4> v1, RValue<Float4> v2) { return Atan2(v1, v2); }, atan2f, { {0.f, 0.f}, {0.f, -1.f}, {-1.f, 0.f}, {123.f, 123.f} } },
__anon5ddac1423802(RValue<Float4> v1, RValue<Float4> v2) 3177*03ce13f7SAndroid Build Coastguard Worker IntrinsicTestParams_Float4_Float4{ [](RValue<Float4> v1, RValue<Float4> v2) { return Pow(v1, v2); }, powf, { {1.f, 0.f}, {1.f, -1.f}, {-1.f, 0.f} } }
3178*03ce13f7SAndroid Build Coastguard Worker ));
3179*03ce13f7SAndroid Build Coastguard Worker // clang-format on
3180*03ce13f7SAndroid Build Coastguard Worker
TEST_P(IntrinsicTest_Float,Test)3181*03ce13f7SAndroid Build Coastguard Worker TEST_P(IntrinsicTest_Float, Test)
3182*03ce13f7SAndroid Build Coastguard Worker {
3183*03ce13f7SAndroid Build Coastguard Worker test();
3184*03ce13f7SAndroid Build Coastguard Worker }
TEST_P(IntrinsicTest_Float4,Test)3185*03ce13f7SAndroid Build Coastguard Worker TEST_P(IntrinsicTest_Float4, Test)
3186*03ce13f7SAndroid Build Coastguard Worker {
3187*03ce13f7SAndroid Build Coastguard Worker test();
3188*03ce13f7SAndroid Build Coastguard Worker }
TEST_P(IntrinsicTest_Float4_Float4,Test)3189*03ce13f7SAndroid Build Coastguard Worker TEST_P(IntrinsicTest_Float4_Float4, Test)
3190*03ce13f7SAndroid Build Coastguard Worker {
3191*03ce13f7SAndroid Build Coastguard Worker test();
3192*03ce13f7SAndroid Build Coastguard Worker }
3193*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Intrinsics_Ctlz)3194*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Intrinsics_Ctlz)
3195*03ce13f7SAndroid Build Coastguard Worker {
3196*03ce13f7SAndroid Build Coastguard Worker // ctlz: counts number of leading zeros
3197*03ce13f7SAndroid Build Coastguard Worker
3198*03ce13f7SAndroid Build Coastguard Worker {
3199*03ce13f7SAndroid Build Coastguard Worker Function<UInt(UInt x)> function;
3200*03ce13f7SAndroid Build Coastguard Worker {
3201*03ce13f7SAndroid Build Coastguard Worker UInt x = function.Arg<0>();
3202*03ce13f7SAndroid Build Coastguard Worker Return(rr::Ctlz(x, false));
3203*03ce13f7SAndroid Build Coastguard Worker }
3204*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3205*03ce13f7SAndroid Build Coastguard Worker auto callable = (uint32_t(*)(uint32_t))routine->getEntry();
3206*03ce13f7SAndroid Build Coastguard Worker
3207*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < 31; ++i)
3208*03ce13f7SAndroid Build Coastguard Worker {
3209*03ce13f7SAndroid Build Coastguard Worker uint32_t result = callable(1 << i);
3210*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 31 - i);
3211*03ce13f7SAndroid Build Coastguard Worker }
3212*03ce13f7SAndroid Build Coastguard Worker
3213*03ce13f7SAndroid Build Coastguard Worker // Input 0 should return 32 for isZeroUndef == false
3214*03ce13f7SAndroid Build Coastguard Worker {
3215*03ce13f7SAndroid Build Coastguard Worker uint32_t result = callable(0);
3216*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 32u);
3217*03ce13f7SAndroid Build Coastguard Worker }
3218*03ce13f7SAndroid Build Coastguard Worker }
3219*03ce13f7SAndroid Build Coastguard Worker
3220*03ce13f7SAndroid Build Coastguard Worker {
3221*03ce13f7SAndroid Build Coastguard Worker Function<Void(Pointer<UInt4>, UInt x)> function;
3222*03ce13f7SAndroid Build Coastguard Worker {
3223*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt4> out = function.Arg<0>();
3224*03ce13f7SAndroid Build Coastguard Worker UInt x = function.Arg<1>();
3225*03ce13f7SAndroid Build Coastguard Worker *out = rr::Ctlz(UInt4(x), false);
3226*03ce13f7SAndroid Build Coastguard Worker }
3227*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3228*03ce13f7SAndroid Build Coastguard Worker auto callable = (void (*)(uint32_t *, uint32_t))routine->getEntry();
3229*03ce13f7SAndroid Build Coastguard Worker
3230*03ce13f7SAndroid Build Coastguard Worker uint32_t x[4];
3231*03ce13f7SAndroid Build Coastguard Worker
3232*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < 31; ++i)
3233*03ce13f7SAndroid Build Coastguard Worker {
3234*03ce13f7SAndroid Build Coastguard Worker callable(x, 1 << i);
3235*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[0], 31 - i);
3236*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[1], 31 - i);
3237*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[2], 31 - i);
3238*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[3], 31 - i);
3239*03ce13f7SAndroid Build Coastguard Worker }
3240*03ce13f7SAndroid Build Coastguard Worker
3241*03ce13f7SAndroid Build Coastguard Worker // Input 0 should return 32 for isZeroUndef == false
3242*03ce13f7SAndroid Build Coastguard Worker {
3243*03ce13f7SAndroid Build Coastguard Worker callable(x, 0);
3244*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[0], 32u);
3245*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[1], 32u);
3246*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[2], 32u);
3247*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[3], 32u);
3248*03ce13f7SAndroid Build Coastguard Worker }
3249*03ce13f7SAndroid Build Coastguard Worker }
3250*03ce13f7SAndroid Build Coastguard Worker }
3251*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Intrinsics_Cttz)3252*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Intrinsics_Cttz)
3253*03ce13f7SAndroid Build Coastguard Worker {
3254*03ce13f7SAndroid Build Coastguard Worker // cttz: counts number of trailing zeros
3255*03ce13f7SAndroid Build Coastguard Worker
3256*03ce13f7SAndroid Build Coastguard Worker {
3257*03ce13f7SAndroid Build Coastguard Worker Function<UInt(UInt x)> function;
3258*03ce13f7SAndroid Build Coastguard Worker {
3259*03ce13f7SAndroid Build Coastguard Worker UInt x = function.Arg<0>();
3260*03ce13f7SAndroid Build Coastguard Worker Return(rr::Cttz(x, false));
3261*03ce13f7SAndroid Build Coastguard Worker }
3262*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3263*03ce13f7SAndroid Build Coastguard Worker auto callable = (uint32_t(*)(uint32_t))routine->getEntry();
3264*03ce13f7SAndroid Build Coastguard Worker
3265*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < 31; ++i)
3266*03ce13f7SAndroid Build Coastguard Worker {
3267*03ce13f7SAndroid Build Coastguard Worker uint32_t result = callable(1 << i);
3268*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, i);
3269*03ce13f7SAndroid Build Coastguard Worker }
3270*03ce13f7SAndroid Build Coastguard Worker
3271*03ce13f7SAndroid Build Coastguard Worker // Input 0 should return 32 for isZeroUndef == false
3272*03ce13f7SAndroid Build Coastguard Worker {
3273*03ce13f7SAndroid Build Coastguard Worker uint32_t result = callable(0);
3274*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, 32u);
3275*03ce13f7SAndroid Build Coastguard Worker }
3276*03ce13f7SAndroid Build Coastguard Worker }
3277*03ce13f7SAndroid Build Coastguard Worker
3278*03ce13f7SAndroid Build Coastguard Worker {
3279*03ce13f7SAndroid Build Coastguard Worker Function<Void(Pointer<UInt4>, UInt x)> function;
3280*03ce13f7SAndroid Build Coastguard Worker {
3281*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt4> out = function.Arg<0>();
3282*03ce13f7SAndroid Build Coastguard Worker UInt x = function.Arg<1>();
3283*03ce13f7SAndroid Build Coastguard Worker *out = rr::Cttz(UInt4(x), false);
3284*03ce13f7SAndroid Build Coastguard Worker }
3285*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3286*03ce13f7SAndroid Build Coastguard Worker auto callable = (void (*)(uint32_t *, uint32_t))routine->getEntry();
3287*03ce13f7SAndroid Build Coastguard Worker
3288*03ce13f7SAndroid Build Coastguard Worker uint32_t x[4];
3289*03ce13f7SAndroid Build Coastguard Worker
3290*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < 31; ++i)
3291*03ce13f7SAndroid Build Coastguard Worker {
3292*03ce13f7SAndroid Build Coastguard Worker callable(x, 1 << i);
3293*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[0], i);
3294*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[1], i);
3295*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[2], i);
3296*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[3], i);
3297*03ce13f7SAndroid Build Coastguard Worker }
3298*03ce13f7SAndroid Build Coastguard Worker
3299*03ce13f7SAndroid Build Coastguard Worker // Input 0 should return 32 for isZeroUndef == false
3300*03ce13f7SAndroid Build Coastguard Worker {
3301*03ce13f7SAndroid Build Coastguard Worker callable(x, 0);
3302*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[0], 32u);
3303*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[1], 32u);
3304*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[2], 32u);
3305*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x[3], 32u);
3306*03ce13f7SAndroid Build Coastguard Worker }
3307*03ce13f7SAndroid Build Coastguard Worker }
3308*03ce13f7SAndroid Build Coastguard Worker }
3309*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ExtractFromRValue)3310*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ExtractFromRValue)
3311*03ce13f7SAndroid Build Coastguard Worker {
3312*03ce13f7SAndroid Build Coastguard Worker Function<Void(Pointer<Int4> values, Pointer<Int4> result)> function;
3313*03ce13f7SAndroid Build Coastguard Worker {
3314*03ce13f7SAndroid Build Coastguard Worker Pointer<Int4> vIn = function.Arg<0>();
3315*03ce13f7SAndroid Build Coastguard Worker Pointer<Int4> resultIn = function.Arg<1>();
3316*03ce13f7SAndroid Build Coastguard Worker
3317*03ce13f7SAndroid Build Coastguard Worker RValue<Int4> v = *vIn;
3318*03ce13f7SAndroid Build Coastguard Worker
3319*03ce13f7SAndroid Build Coastguard Worker Int4 result(678);
3320*03ce13f7SAndroid Build Coastguard Worker
3321*03ce13f7SAndroid Build Coastguard Worker If(Extract(v, 0) == 42)
3322*03ce13f7SAndroid Build Coastguard Worker {
3323*03ce13f7SAndroid Build Coastguard Worker result = Insert(result, 1, 0);
3324*03ce13f7SAndroid Build Coastguard Worker }
3325*03ce13f7SAndroid Build Coastguard Worker
3326*03ce13f7SAndroid Build Coastguard Worker If(Extract(v, 1) == 42)
3327*03ce13f7SAndroid Build Coastguard Worker {
3328*03ce13f7SAndroid Build Coastguard Worker result = Insert(result, 1, 1);
3329*03ce13f7SAndroid Build Coastguard Worker }
3330*03ce13f7SAndroid Build Coastguard Worker
3331*03ce13f7SAndroid Build Coastguard Worker *resultIn = result;
3332*03ce13f7SAndroid Build Coastguard Worker
3333*03ce13f7SAndroid Build Coastguard Worker Return();
3334*03ce13f7SAndroid Build Coastguard Worker }
3335*03ce13f7SAndroid Build Coastguard Worker
3336*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3337*03ce13f7SAndroid Build Coastguard Worker auto entry = (void (*)(int *, int *))routine->getEntry();
3338*03ce13f7SAndroid Build Coastguard Worker
3339*03ce13f7SAndroid Build Coastguard Worker int v[4] = { 42, 42, 42, 42 };
3340*03ce13f7SAndroid Build Coastguard Worker int result[4] = { 99, 99, 99, 99 };
3341*03ce13f7SAndroid Build Coastguard Worker entry(v, result);
3342*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result[0], 1);
3343*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result[1], 1);
3344*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result[2], 678);
3345*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result[3], 678);
3346*03ce13f7SAndroid Build Coastguard Worker }
3347*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,AddAtomic)3348*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, AddAtomic)
3349*03ce13f7SAndroid Build Coastguard Worker {
3350*03ce13f7SAndroid Build Coastguard Worker FunctionT<uint32_t(uint32_t * p, uint32_t a)> function;
3351*03ce13f7SAndroid Build Coastguard Worker {
3352*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> p = function.Arg<0>();
3353*03ce13f7SAndroid Build Coastguard Worker UInt a = function.Arg<1>();
3354*03ce13f7SAndroid Build Coastguard Worker UInt r = rr::AddAtomic(p, a, std::memory_order_relaxed);
3355*03ce13f7SAndroid Build Coastguard Worker Return(r);
3356*03ce13f7SAndroid Build Coastguard Worker }
3357*03ce13f7SAndroid Build Coastguard Worker
3358*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3359*03ce13f7SAndroid Build Coastguard Worker uint32_t x = 123;
3360*03ce13f7SAndroid Build Coastguard Worker uint32_t y = 456;
3361*03ce13f7SAndroid Build Coastguard Worker uint32_t prevX = routine(&x, y);
3362*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 123u);
3363*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, 579u);
3364*03ce13f7SAndroid Build Coastguard Worker }
3365*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,SubAtomic)3366*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, SubAtomic)
3367*03ce13f7SAndroid Build Coastguard Worker {
3368*03ce13f7SAndroid Build Coastguard Worker FunctionT<uint32_t(uint32_t * p, uint32_t a)> function;
3369*03ce13f7SAndroid Build Coastguard Worker {
3370*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> p = function.Arg<0>();
3371*03ce13f7SAndroid Build Coastguard Worker UInt a = function.Arg<1>();
3372*03ce13f7SAndroid Build Coastguard Worker UInt r = rr::SubAtomic(p, a, std::memory_order_relaxed);
3373*03ce13f7SAndroid Build Coastguard Worker Return(r);
3374*03ce13f7SAndroid Build Coastguard Worker }
3375*03ce13f7SAndroid Build Coastguard Worker
3376*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3377*03ce13f7SAndroid Build Coastguard Worker uint32_t x = 456;
3378*03ce13f7SAndroid Build Coastguard Worker uint32_t y = 123;
3379*03ce13f7SAndroid Build Coastguard Worker uint32_t prevX = routine(&x, y);
3380*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 456u);
3381*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, 333u);
3382*03ce13f7SAndroid Build Coastguard Worker }
3383*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,AndAtomic)3384*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, AndAtomic)
3385*03ce13f7SAndroid Build Coastguard Worker {
3386*03ce13f7SAndroid Build Coastguard Worker FunctionT<uint32_t(uint32_t * p, uint32_t a)> function;
3387*03ce13f7SAndroid Build Coastguard Worker {
3388*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> p = function.Arg<0>();
3389*03ce13f7SAndroid Build Coastguard Worker UInt a = function.Arg<1>();
3390*03ce13f7SAndroid Build Coastguard Worker UInt r = rr::AndAtomic(p, a, std::memory_order_relaxed);
3391*03ce13f7SAndroid Build Coastguard Worker Return(r);
3392*03ce13f7SAndroid Build Coastguard Worker }
3393*03ce13f7SAndroid Build Coastguard Worker
3394*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3395*03ce13f7SAndroid Build Coastguard Worker uint32_t x = 0b1111'0000;
3396*03ce13f7SAndroid Build Coastguard Worker uint32_t y = 0b1010'1100;
3397*03ce13f7SAndroid Build Coastguard Worker uint32_t prevX = routine(&x, y);
3398*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 0b1111'0000u);
3399*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, 0b1010'0000u);
3400*03ce13f7SAndroid Build Coastguard Worker }
3401*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,OrAtomic)3402*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, OrAtomic)
3403*03ce13f7SAndroid Build Coastguard Worker {
3404*03ce13f7SAndroid Build Coastguard Worker FunctionT<uint32_t(uint32_t * p, uint32_t a)> function;
3405*03ce13f7SAndroid Build Coastguard Worker {
3406*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> p = function.Arg<0>();
3407*03ce13f7SAndroid Build Coastguard Worker UInt a = function.Arg<1>();
3408*03ce13f7SAndroid Build Coastguard Worker UInt r = rr::OrAtomic(p, a, std::memory_order_relaxed);
3409*03ce13f7SAndroid Build Coastguard Worker Return(r);
3410*03ce13f7SAndroid Build Coastguard Worker }
3411*03ce13f7SAndroid Build Coastguard Worker
3412*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3413*03ce13f7SAndroid Build Coastguard Worker uint32_t x = 0b1111'0000;
3414*03ce13f7SAndroid Build Coastguard Worker uint32_t y = 0b1010'1100;
3415*03ce13f7SAndroid Build Coastguard Worker uint32_t prevX = routine(&x, y);
3416*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 0b1111'0000u);
3417*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, 0b1111'1100u);
3418*03ce13f7SAndroid Build Coastguard Worker }
3419*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,XorAtomic)3420*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, XorAtomic)
3421*03ce13f7SAndroid Build Coastguard Worker {
3422*03ce13f7SAndroid Build Coastguard Worker FunctionT<uint32_t(uint32_t * p, uint32_t a)> function;
3423*03ce13f7SAndroid Build Coastguard Worker {
3424*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> p = function.Arg<0>();
3425*03ce13f7SAndroid Build Coastguard Worker UInt a = function.Arg<1>();
3426*03ce13f7SAndroid Build Coastguard Worker UInt r = rr::XorAtomic(p, a, std::memory_order_relaxed);
3427*03ce13f7SAndroid Build Coastguard Worker Return(r);
3428*03ce13f7SAndroid Build Coastguard Worker }
3429*03ce13f7SAndroid Build Coastguard Worker
3430*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3431*03ce13f7SAndroid Build Coastguard Worker uint32_t x = 0b1111'0000;
3432*03ce13f7SAndroid Build Coastguard Worker uint32_t y = 0b1010'1100;
3433*03ce13f7SAndroid Build Coastguard Worker uint32_t prevX = routine(&x, y);
3434*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 0b1111'0000u);
3435*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, 0b0101'1100u);
3436*03ce13f7SAndroid Build Coastguard Worker }
3437*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,MinAtomic)3438*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, MinAtomic)
3439*03ce13f7SAndroid Build Coastguard Worker {
3440*03ce13f7SAndroid Build Coastguard Worker {
3441*03ce13f7SAndroid Build Coastguard Worker FunctionT<uint32_t(uint32_t * p, uint32_t a)> function;
3442*03ce13f7SAndroid Build Coastguard Worker {
3443*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> p = function.Arg<0>();
3444*03ce13f7SAndroid Build Coastguard Worker UInt a = function.Arg<1>();
3445*03ce13f7SAndroid Build Coastguard Worker UInt r = rr::MinAtomic(p, a, std::memory_order_relaxed);
3446*03ce13f7SAndroid Build Coastguard Worker Return(r);
3447*03ce13f7SAndroid Build Coastguard Worker }
3448*03ce13f7SAndroid Build Coastguard Worker
3449*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3450*03ce13f7SAndroid Build Coastguard Worker uint32_t x = 123;
3451*03ce13f7SAndroid Build Coastguard Worker uint32_t y = 100;
3452*03ce13f7SAndroid Build Coastguard Worker uint32_t prevX = routine(&x, y);
3453*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 123u);
3454*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, 100u);
3455*03ce13f7SAndroid Build Coastguard Worker }
3456*03ce13f7SAndroid Build Coastguard Worker
3457*03ce13f7SAndroid Build Coastguard Worker {
3458*03ce13f7SAndroid Build Coastguard Worker FunctionT<int32_t(int32_t * p, int32_t a)> function;
3459*03ce13f7SAndroid Build Coastguard Worker {
3460*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p = function.Arg<0>();
3461*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<1>();
3462*03ce13f7SAndroid Build Coastguard Worker Int r = rr::MinAtomic(p, a, std::memory_order_relaxed);
3463*03ce13f7SAndroid Build Coastguard Worker Return(r);
3464*03ce13f7SAndroid Build Coastguard Worker }
3465*03ce13f7SAndroid Build Coastguard Worker
3466*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3467*03ce13f7SAndroid Build Coastguard Worker int32_t x = -123;
3468*03ce13f7SAndroid Build Coastguard Worker int32_t y = -200;
3469*03ce13f7SAndroid Build Coastguard Worker int32_t prevX = routine(&x, y);
3470*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, -123);
3471*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, -200);
3472*03ce13f7SAndroid Build Coastguard Worker }
3473*03ce13f7SAndroid Build Coastguard Worker }
3474*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,MaxAtomic)3475*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, MaxAtomic)
3476*03ce13f7SAndroid Build Coastguard Worker {
3477*03ce13f7SAndroid Build Coastguard Worker {
3478*03ce13f7SAndroid Build Coastguard Worker FunctionT<uint32_t(uint32_t * p, uint32_t a)> function;
3479*03ce13f7SAndroid Build Coastguard Worker {
3480*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> p = function.Arg<0>();
3481*03ce13f7SAndroid Build Coastguard Worker UInt a = function.Arg<1>();
3482*03ce13f7SAndroid Build Coastguard Worker UInt r = rr::MaxAtomic(p, a, std::memory_order_relaxed);
3483*03ce13f7SAndroid Build Coastguard Worker Return(r);
3484*03ce13f7SAndroid Build Coastguard Worker }
3485*03ce13f7SAndroid Build Coastguard Worker
3486*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3487*03ce13f7SAndroid Build Coastguard Worker uint32_t x = 123;
3488*03ce13f7SAndroid Build Coastguard Worker uint32_t y = 100;
3489*03ce13f7SAndroid Build Coastguard Worker uint32_t prevX = routine(&x, y);
3490*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 123u);
3491*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, 123u);
3492*03ce13f7SAndroid Build Coastguard Worker }
3493*03ce13f7SAndroid Build Coastguard Worker
3494*03ce13f7SAndroid Build Coastguard Worker {
3495*03ce13f7SAndroid Build Coastguard Worker FunctionT<int32_t(int32_t * p, int32_t a)> function;
3496*03ce13f7SAndroid Build Coastguard Worker {
3497*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> p = function.Arg<0>();
3498*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<1>();
3499*03ce13f7SAndroid Build Coastguard Worker Int r = rr::MaxAtomic(p, a, std::memory_order_relaxed);
3500*03ce13f7SAndroid Build Coastguard Worker Return(r);
3501*03ce13f7SAndroid Build Coastguard Worker }
3502*03ce13f7SAndroid Build Coastguard Worker
3503*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3504*03ce13f7SAndroid Build Coastguard Worker int32_t x = -123;
3505*03ce13f7SAndroid Build Coastguard Worker int32_t y = -200;
3506*03ce13f7SAndroid Build Coastguard Worker int32_t prevX = routine(&x, y);
3507*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, -123);
3508*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, -123);
3509*03ce13f7SAndroid Build Coastguard Worker }
3510*03ce13f7SAndroid Build Coastguard Worker }
3511*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,ExchangeAtomic)3512*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, ExchangeAtomic)
3513*03ce13f7SAndroid Build Coastguard Worker {
3514*03ce13f7SAndroid Build Coastguard Worker FunctionT<uint32_t(uint32_t * p, uint32_t a)> function;
3515*03ce13f7SAndroid Build Coastguard Worker {
3516*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> p = function.Arg<0>();
3517*03ce13f7SAndroid Build Coastguard Worker UInt a = function.Arg<1>();
3518*03ce13f7SAndroid Build Coastguard Worker UInt r = rr::ExchangeAtomic(p, a, std::memory_order_relaxed);
3519*03ce13f7SAndroid Build Coastguard Worker Return(r);
3520*03ce13f7SAndroid Build Coastguard Worker }
3521*03ce13f7SAndroid Build Coastguard Worker
3522*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3523*03ce13f7SAndroid Build Coastguard Worker uint32_t x = 123;
3524*03ce13f7SAndroid Build Coastguard Worker uint32_t y = 456;
3525*03ce13f7SAndroid Build Coastguard Worker uint32_t prevX = routine(&x, y);
3526*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 123u);
3527*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, y);
3528*03ce13f7SAndroid Build Coastguard Worker }
3529*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,CompareExchangeAtomic)3530*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, CompareExchangeAtomic)
3531*03ce13f7SAndroid Build Coastguard Worker {
3532*03ce13f7SAndroid Build Coastguard Worker FunctionT<uint32_t(uint32_t * x, uint32_t y, uint32_t compare)> function;
3533*03ce13f7SAndroid Build Coastguard Worker {
3534*03ce13f7SAndroid Build Coastguard Worker Pointer<UInt> x = function.Arg<0>();
3535*03ce13f7SAndroid Build Coastguard Worker UInt y = function.Arg<1>();
3536*03ce13f7SAndroid Build Coastguard Worker UInt compare = function.Arg<2>();
3537*03ce13f7SAndroid Build Coastguard Worker UInt r = rr::CompareExchangeAtomic(x, y, compare, std::memory_order_relaxed, std::memory_order_relaxed);
3538*03ce13f7SAndroid Build Coastguard Worker Return(r);
3539*03ce13f7SAndroid Build Coastguard Worker }
3540*03ce13f7SAndroid Build Coastguard Worker
3541*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3542*03ce13f7SAndroid Build Coastguard Worker uint32_t x = 123;
3543*03ce13f7SAndroid Build Coastguard Worker uint32_t y = 456;
3544*03ce13f7SAndroid Build Coastguard Worker uint32_t compare = 123;
3545*03ce13f7SAndroid Build Coastguard Worker uint32_t prevX = routine(&x, y, compare);
3546*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 123u);
3547*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, y);
3548*03ce13f7SAndroid Build Coastguard Worker
3549*03ce13f7SAndroid Build Coastguard Worker x = 123;
3550*03ce13f7SAndroid Build Coastguard Worker y = 456;
3551*03ce13f7SAndroid Build Coastguard Worker compare = 456;
3552*03ce13f7SAndroid Build Coastguard Worker prevX = routine(&x, y, compare);
3553*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(prevX, 123u);
3554*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(x, 123u);
3555*03ce13f7SAndroid Build Coastguard Worker }
3556*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,SRem)3557*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, SRem)
3558*03ce13f7SAndroid Build Coastguard Worker {
3559*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(int4 *, int4 *)> function;
3560*03ce13f7SAndroid Build Coastguard Worker {
3561*03ce13f7SAndroid Build Coastguard Worker Pointer<Int4> a = function.Arg<0>();
3562*03ce13f7SAndroid Build Coastguard Worker Pointer<Int4> b = function.Arg<1>();
3563*03ce13f7SAndroid Build Coastguard Worker *a = *a % *b;
3564*03ce13f7SAndroid Build Coastguard Worker }
3565*03ce13f7SAndroid Build Coastguard Worker
3566*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3567*03ce13f7SAndroid Build Coastguard Worker
3568*03ce13f7SAndroid Build Coastguard Worker int4_value result = invokeRoutine(routine, int4_value{ 10, 11, 12, 13 }, int4_value{ 3, 3, 3, 3 });
3569*03ce13f7SAndroid Build Coastguard Worker int4_value expected = int4_value{ 10 % 3, 11 % 3, 12 % 3, 13 % 3 };
3570*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(result.v[0], expected.v[0]);
3571*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(result.v[1], expected.v[1]);
3572*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(result.v[2], expected.v[2]);
3573*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(result.v[3], expected.v[3]);
3574*03ce13f7SAndroid Build Coastguard Worker }
3575*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,FRem)3576*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, FRem)
3577*03ce13f7SAndroid Build Coastguard Worker {
3578*03ce13f7SAndroid Build Coastguard Worker FunctionT<void(float4 *, float4 *)> function;
3579*03ce13f7SAndroid Build Coastguard Worker {
3580*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> a = function.Arg<0>();
3581*03ce13f7SAndroid Build Coastguard Worker Pointer<Float4> b = function.Arg<1>();
3582*03ce13f7SAndroid Build Coastguard Worker *a = *a % *b;
3583*03ce13f7SAndroid Build Coastguard Worker }
3584*03ce13f7SAndroid Build Coastguard Worker
3585*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3586*03ce13f7SAndroid Build Coastguard Worker
3587*03ce13f7SAndroid Build Coastguard Worker float4_value result = invokeRoutine(routine, float4_value{ 10.1f, 11.2f, 12.3f, 13.4f }, float4_value{ 3.f, 3.f, 3.f, 3.f });
3588*03ce13f7SAndroid Build Coastguard Worker float4_value expected = float4_value{ fmodf(10.1f, 3.f), fmodf(11.2f, 3.f), fmodf(12.3f, 3.f), fmodf(13.4f, 3.f) };
3589*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(result.v[0], expected.v[0]);
3590*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(result.v[1], expected.v[1]);
3591*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(result.v[2], expected.v[2]);
3592*03ce13f7SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(result.v[3], expected.v[3]);
3593*03ce13f7SAndroid Build Coastguard Worker }
3594*03ce13f7SAndroid Build Coastguard Worker
3595*03ce13f7SAndroid Build Coastguard Worker // Subzero's load instruction assumes that a Constant ptr value is an offset, rather than an absolute
3596*03ce13f7SAndroid Build Coastguard Worker // pointer, and would fail during codegen. This was fixed by casting the constant to a non-const
3597*03ce13f7SAndroid Build Coastguard Worker // variable, and loading from it instead. This test makes sure this works.
TEST(ReactorUnitTests,LoadFromConstantData)3598*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, LoadFromConstantData)
3599*03ce13f7SAndroid Build Coastguard Worker {
3600*03ce13f7SAndroid Build Coastguard Worker const int value = 123;
3601*03ce13f7SAndroid Build Coastguard Worker
3602*03ce13f7SAndroid Build Coastguard Worker FunctionT<int()> function;
3603*03ce13f7SAndroid Build Coastguard Worker {
3604*03ce13f7SAndroid Build Coastguard Worker auto p = Pointer<Int>{ ConstantData(&value, sizeof(value)) };
3605*03ce13f7SAndroid Build Coastguard Worker Int v = *p;
3606*03ce13f7SAndroid Build Coastguard Worker Return(v);
3607*03ce13f7SAndroid Build Coastguard Worker }
3608*03ce13f7SAndroid Build Coastguard Worker
3609*03ce13f7SAndroid Build Coastguard Worker const int result = function(testName().c_str())();
3610*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, value);
3611*03ce13f7SAndroid Build Coastguard Worker }
3612*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Multithreaded_Function)3613*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Multithreaded_Function)
3614*03ce13f7SAndroid Build Coastguard Worker {
3615*03ce13f7SAndroid Build Coastguard Worker constexpr int numThreads = 8;
3616*03ce13f7SAndroid Build Coastguard Worker constexpr int numLoops = 16;
3617*03ce13f7SAndroid Build Coastguard Worker
3618*03ce13f7SAndroid Build Coastguard Worker auto threads = std::unique_ptr<std::thread[]>(new std::thread[numThreads]);
3619*03ce13f7SAndroid Build Coastguard Worker auto results = std::unique_ptr<int[]>(new int[numThreads * numLoops]);
3620*03ce13f7SAndroid Build Coastguard Worker
3621*03ce13f7SAndroid Build Coastguard Worker for(int t = 0; t < numThreads; t++)
3622*03ce13f7SAndroid Build Coastguard Worker {
3623*03ce13f7SAndroid Build Coastguard Worker auto threadFunc = [&](int t) {
3624*03ce13f7SAndroid Build Coastguard Worker for(int l = 0; l < numLoops; l++)
3625*03ce13f7SAndroid Build Coastguard Worker {
3626*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int, int)> function;
3627*03ce13f7SAndroid Build Coastguard Worker {
3628*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
3629*03ce13f7SAndroid Build Coastguard Worker Int b = function.Arg<1>();
3630*03ce13f7SAndroid Build Coastguard Worker Return((a << 16) | b);
3631*03ce13f7SAndroid Build Coastguard Worker }
3632*03ce13f7SAndroid Build Coastguard Worker
3633*03ce13f7SAndroid Build Coastguard Worker auto f = function("%s_thread%d_loop%d", testName().c_str(), t, l);
3634*03ce13f7SAndroid Build Coastguard Worker results[t * numLoops + l] = f(t, l);
3635*03ce13f7SAndroid Build Coastguard Worker }
3636*03ce13f7SAndroid Build Coastguard Worker };
3637*03ce13f7SAndroid Build Coastguard Worker threads[t] = std::thread(threadFunc, t);
3638*03ce13f7SAndroid Build Coastguard Worker }
3639*03ce13f7SAndroid Build Coastguard Worker
3640*03ce13f7SAndroid Build Coastguard Worker for(int t = 0; t < numThreads; t++)
3641*03ce13f7SAndroid Build Coastguard Worker {
3642*03ce13f7SAndroid Build Coastguard Worker threads[t].join();
3643*03ce13f7SAndroid Build Coastguard Worker }
3644*03ce13f7SAndroid Build Coastguard Worker
3645*03ce13f7SAndroid Build Coastguard Worker for(int t = 0; t < numThreads; t++)
3646*03ce13f7SAndroid Build Coastguard Worker {
3647*03ce13f7SAndroid Build Coastguard Worker for(int l = 0; l < numLoops; l++)
3648*03ce13f7SAndroid Build Coastguard Worker {
3649*03ce13f7SAndroid Build Coastguard Worker auto expect = (t << 16) | l;
3650*03ce13f7SAndroid Build Coastguard Worker auto result = results[t * numLoops + l];
3651*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, expect);
3652*03ce13f7SAndroid Build Coastguard Worker }
3653*03ce13f7SAndroid Build Coastguard Worker }
3654*03ce13f7SAndroid Build Coastguard Worker }
3655*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,Multithreaded_Coroutine)3656*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Multithreaded_Coroutine)
3657*03ce13f7SAndroid Build Coastguard Worker {
3658*03ce13f7SAndroid Build Coastguard Worker if(!rr::Caps::coroutinesSupported())
3659*03ce13f7SAndroid Build Coastguard Worker {
3660*03ce13f7SAndroid Build Coastguard Worker SUCCEED() << "Coroutines not supported";
3661*03ce13f7SAndroid Build Coastguard Worker return;
3662*03ce13f7SAndroid Build Coastguard Worker }
3663*03ce13f7SAndroid Build Coastguard Worker
3664*03ce13f7SAndroid Build Coastguard Worker constexpr int numThreads = 8;
3665*03ce13f7SAndroid Build Coastguard Worker constexpr int numLoops = 16;
3666*03ce13f7SAndroid Build Coastguard Worker
3667*03ce13f7SAndroid Build Coastguard Worker struct Result
3668*03ce13f7SAndroid Build Coastguard Worker {
3669*03ce13f7SAndroid Build Coastguard Worker bool yieldReturns[3];
3670*03ce13f7SAndroid Build Coastguard Worker int yieldValues[3];
3671*03ce13f7SAndroid Build Coastguard Worker };
3672*03ce13f7SAndroid Build Coastguard Worker
3673*03ce13f7SAndroid Build Coastguard Worker auto threads = std::unique_ptr<std::thread[]>(new std::thread[numThreads]);
3674*03ce13f7SAndroid Build Coastguard Worker auto results = std::unique_ptr<Result[]>(new Result[numThreads * numLoops]);
3675*03ce13f7SAndroid Build Coastguard Worker
3676*03ce13f7SAndroid Build Coastguard Worker for(int t = 0; t < numThreads; t++)
3677*03ce13f7SAndroid Build Coastguard Worker {
3678*03ce13f7SAndroid Build Coastguard Worker auto threadFunc = [&](int t) {
3679*03ce13f7SAndroid Build Coastguard Worker for(int l = 0; l < numLoops; l++)
3680*03ce13f7SAndroid Build Coastguard Worker {
3681*03ce13f7SAndroid Build Coastguard Worker Coroutine<int(int, int)> function;
3682*03ce13f7SAndroid Build Coastguard Worker {
3683*03ce13f7SAndroid Build Coastguard Worker Int a = function.Arg<0>();
3684*03ce13f7SAndroid Build Coastguard Worker Int b = function.Arg<1>();
3685*03ce13f7SAndroid Build Coastguard Worker Yield(a);
3686*03ce13f7SAndroid Build Coastguard Worker Yield(b);
3687*03ce13f7SAndroid Build Coastguard Worker }
3688*03ce13f7SAndroid Build Coastguard Worker function.finalize((testName() + "_thread" + std::to_string(t) + "_loop" + std::to_string(l)).c_str());
3689*03ce13f7SAndroid Build Coastguard Worker
3690*03ce13f7SAndroid Build Coastguard Worker auto coroutine = function(t, l);
3691*03ce13f7SAndroid Build Coastguard Worker
3692*03ce13f7SAndroid Build Coastguard Worker auto &result = results[t * numLoops + l];
3693*03ce13f7SAndroid Build Coastguard Worker result = {};
3694*03ce13f7SAndroid Build Coastguard Worker result.yieldReturns[0] = coroutine->await(result.yieldValues[0]);
3695*03ce13f7SAndroid Build Coastguard Worker result.yieldReturns[1] = coroutine->await(result.yieldValues[1]);
3696*03ce13f7SAndroid Build Coastguard Worker result.yieldReturns[2] = coroutine->await(result.yieldValues[2]);
3697*03ce13f7SAndroid Build Coastguard Worker }
3698*03ce13f7SAndroid Build Coastguard Worker };
3699*03ce13f7SAndroid Build Coastguard Worker threads[t] = std::thread(threadFunc, t);
3700*03ce13f7SAndroid Build Coastguard Worker }
3701*03ce13f7SAndroid Build Coastguard Worker
3702*03ce13f7SAndroid Build Coastguard Worker for(int t = 0; t < numThreads; t++)
3703*03ce13f7SAndroid Build Coastguard Worker {
3704*03ce13f7SAndroid Build Coastguard Worker threads[t].join();
3705*03ce13f7SAndroid Build Coastguard Worker }
3706*03ce13f7SAndroid Build Coastguard Worker
3707*03ce13f7SAndroid Build Coastguard Worker for(int t = 0; t < numThreads; t++)
3708*03ce13f7SAndroid Build Coastguard Worker {
3709*03ce13f7SAndroid Build Coastguard Worker for(int l = 0; l < numLoops; l++)
3710*03ce13f7SAndroid Build Coastguard Worker {
3711*03ce13f7SAndroid Build Coastguard Worker const auto &result = results[t * numLoops + l];
3712*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result.yieldReturns[0], true);
3713*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result.yieldValues[0], t);
3714*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result.yieldReturns[1], true);
3715*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result.yieldValues[1], l);
3716*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result.yieldReturns[2], false);
3717*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result.yieldValues[2], 0);
3718*03ce13f7SAndroid Build Coastguard Worker }
3719*03ce13f7SAndroid Build Coastguard Worker }
3720*03ce13f7SAndroid Build Coastguard Worker }
3721*03ce13f7SAndroid Build Coastguard Worker
3722*03ce13f7SAndroid Build Coastguard Worker // For gtest printing of pairs
3723*03ce13f7SAndroid Build Coastguard Worker namespace std {
3724*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename U>
operator <<(std::ostream & os,const std::pair<T,U> & value)3725*03ce13f7SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &value)
3726*03ce13f7SAndroid Build Coastguard Worker {
3727*03ce13f7SAndroid Build Coastguard Worker return os << "{ " << value.first << ", " << value.second << " }";
3728*03ce13f7SAndroid Build Coastguard Worker }
3729*03ce13f7SAndroid Build Coastguard Worker } // namespace std
3730*03ce13f7SAndroid Build Coastguard Worker
3731*03ce13f7SAndroid Build Coastguard Worker class StdOutCapture
3732*03ce13f7SAndroid Build Coastguard Worker {
3733*03ce13f7SAndroid Build Coastguard Worker public:
~StdOutCapture()3734*03ce13f7SAndroid Build Coastguard Worker ~StdOutCapture()
3735*03ce13f7SAndroid Build Coastguard Worker {
3736*03ce13f7SAndroid Build Coastguard Worker stopIfCapturing();
3737*03ce13f7SAndroid Build Coastguard Worker }
3738*03ce13f7SAndroid Build Coastguard Worker
start()3739*03ce13f7SAndroid Build Coastguard Worker void start()
3740*03ce13f7SAndroid Build Coastguard Worker {
3741*03ce13f7SAndroid Build Coastguard Worker stopIfCapturing();
3742*03ce13f7SAndroid Build Coastguard Worker capturing = true;
3743*03ce13f7SAndroid Build Coastguard Worker testing::internal::CaptureStdout();
3744*03ce13f7SAndroid Build Coastguard Worker }
3745*03ce13f7SAndroid Build Coastguard Worker
stop()3746*03ce13f7SAndroid Build Coastguard Worker std::string stop()
3747*03ce13f7SAndroid Build Coastguard Worker {
3748*03ce13f7SAndroid Build Coastguard Worker assert(capturing);
3749*03ce13f7SAndroid Build Coastguard Worker capturing = false;
3750*03ce13f7SAndroid Build Coastguard Worker return testing::internal::GetCapturedStdout();
3751*03ce13f7SAndroid Build Coastguard Worker }
3752*03ce13f7SAndroid Build Coastguard Worker
3753*03ce13f7SAndroid Build Coastguard Worker private:
stopIfCapturing()3754*03ce13f7SAndroid Build Coastguard Worker void stopIfCapturing()
3755*03ce13f7SAndroid Build Coastguard Worker {
3756*03ce13f7SAndroid Build Coastguard Worker if(capturing)
3757*03ce13f7SAndroid Build Coastguard Worker {
3758*03ce13f7SAndroid Build Coastguard Worker // This stops the capture
3759*03ce13f7SAndroid Build Coastguard Worker testing::internal::GetCapturedStdout();
3760*03ce13f7SAndroid Build Coastguard Worker }
3761*03ce13f7SAndroid Build Coastguard Worker }
3762*03ce13f7SAndroid Build Coastguard Worker
3763*03ce13f7SAndroid Build Coastguard Worker bool capturing = false;
3764*03ce13f7SAndroid Build Coastguard Worker };
3765*03ce13f7SAndroid Build Coastguard Worker
split(const std::string & s)3766*03ce13f7SAndroid Build Coastguard Worker std::vector<std::string> split(const std::string &s)
3767*03ce13f7SAndroid Build Coastguard Worker {
3768*03ce13f7SAndroid Build Coastguard Worker std::vector<std::string> result;
3769*03ce13f7SAndroid Build Coastguard Worker std::istringstream iss(s);
3770*03ce13f7SAndroid Build Coastguard Worker for(std::string line; std::getline(iss, line);)
3771*03ce13f7SAndroid Build Coastguard Worker {
3772*03ce13f7SAndroid Build Coastguard Worker result.push_back(line);
3773*03ce13f7SAndroid Build Coastguard Worker }
3774*03ce13f7SAndroid Build Coastguard Worker return result;
3775*03ce13f7SAndroid Build Coastguard Worker }
3776*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,PrintPrimitiveTypes)3777*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, PrintPrimitiveTypes)
3778*03ce13f7SAndroid Build Coastguard Worker {
3779*03ce13f7SAndroid Build Coastguard Worker #if defined(ENABLE_RR_PRINT) && !defined(ENABLE_RR_EMIT_PRINT_LOCATION)
3780*03ce13f7SAndroid Build Coastguard Worker FunctionT<void()> function;
3781*03ce13f7SAndroid Build Coastguard Worker {
3782*03ce13f7SAndroid Build Coastguard Worker bool b(true);
3783*03ce13f7SAndroid Build Coastguard Worker int8_t i8(-1);
3784*03ce13f7SAndroid Build Coastguard Worker uint8_t ui8(1);
3785*03ce13f7SAndroid Build Coastguard Worker int16_t i16(-1);
3786*03ce13f7SAndroid Build Coastguard Worker uint16_t ui16(1);
3787*03ce13f7SAndroid Build Coastguard Worker int32_t i32(-1);
3788*03ce13f7SAndroid Build Coastguard Worker uint32_t ui32(1);
3789*03ce13f7SAndroid Build Coastguard Worker int64_t i64(-1);
3790*03ce13f7SAndroid Build Coastguard Worker uint64_t ui64(1);
3791*03ce13f7SAndroid Build Coastguard Worker float f(1);
3792*03ce13f7SAndroid Build Coastguard Worker double d(2);
3793*03ce13f7SAndroid Build Coastguard Worker const char *cstr = "const char*";
3794*03ce13f7SAndroid Build Coastguard Worker std::string str = "std::string";
3795*03ce13f7SAndroid Build Coastguard Worker int *p = nullptr;
3796*03ce13f7SAndroid Build Coastguard Worker
3797*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(b);
3798*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(i8);
3799*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(ui8);
3800*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(i16);
3801*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(ui16);
3802*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(i32);
3803*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(ui32);
3804*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(i64);
3805*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(ui64);
3806*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(f);
3807*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(d);
3808*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(cstr);
3809*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(str);
3810*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(p);
3811*03ce13f7SAndroid Build Coastguard Worker }
3812*03ce13f7SAndroid Build Coastguard Worker
3813*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3814*03ce13f7SAndroid Build Coastguard Worker
3815*03ce13f7SAndroid Build Coastguard Worker char pNullptr[64];
3816*03ce13f7SAndroid Build Coastguard Worker snprintf(pNullptr, sizeof(pNullptr), " p: %p", nullptr);
3817*03ce13f7SAndroid Build Coastguard Worker
3818*03ce13f7SAndroid Build Coastguard Worker const char *expected[] = {
3819*03ce13f7SAndroid Build Coastguard Worker " b: true",
3820*03ce13f7SAndroid Build Coastguard Worker " i8: -1",
3821*03ce13f7SAndroid Build Coastguard Worker " ui8: 1",
3822*03ce13f7SAndroid Build Coastguard Worker " i16: -1",
3823*03ce13f7SAndroid Build Coastguard Worker " ui16: 1",
3824*03ce13f7SAndroid Build Coastguard Worker " i32: -1",
3825*03ce13f7SAndroid Build Coastguard Worker " ui32: 1",
3826*03ce13f7SAndroid Build Coastguard Worker " i64: -1",
3827*03ce13f7SAndroid Build Coastguard Worker " ui64: 1",
3828*03ce13f7SAndroid Build Coastguard Worker " f: 1.000000",
3829*03ce13f7SAndroid Build Coastguard Worker " d: 2.000000",
3830*03ce13f7SAndroid Build Coastguard Worker " cstr: const char*",
3831*03ce13f7SAndroid Build Coastguard Worker " str: std::string",
3832*03ce13f7SAndroid Build Coastguard Worker pNullptr,
3833*03ce13f7SAndroid Build Coastguard Worker };
3834*03ce13f7SAndroid Build Coastguard Worker constexpr size_t expectedSize = sizeof(expected) / sizeof(expected[0]);
3835*03ce13f7SAndroid Build Coastguard Worker
3836*03ce13f7SAndroid Build Coastguard Worker StdOutCapture capture;
3837*03ce13f7SAndroid Build Coastguard Worker capture.start();
3838*03ce13f7SAndroid Build Coastguard Worker routine();
3839*03ce13f7SAndroid Build Coastguard Worker auto output = split(capture.stop());
3840*03ce13f7SAndroid Build Coastguard Worker for(size_t i = 0, j = 1; i < expectedSize; ++i, j += 2)
3841*03ce13f7SAndroid Build Coastguard Worker {
3842*03ce13f7SAndroid Build Coastguard Worker ASSERT_EQ(expected[i], output[j]);
3843*03ce13f7SAndroid Build Coastguard Worker }
3844*03ce13f7SAndroid Build Coastguard Worker
3845*03ce13f7SAndroid Build Coastguard Worker #endif
3846*03ce13f7SAndroid Build Coastguard Worker }
3847*03ce13f7SAndroid Build Coastguard Worker
TEST(ReactorUnitTests,PrintReactorTypes)3848*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, PrintReactorTypes)
3849*03ce13f7SAndroid Build Coastguard Worker {
3850*03ce13f7SAndroid Build Coastguard Worker #if defined(ENABLE_RR_PRINT) && !defined(ENABLE_RR_EMIT_PRINT_LOCATION)
3851*03ce13f7SAndroid Build Coastguard Worker FunctionT<void()> function;
3852*03ce13f7SAndroid Build Coastguard Worker {
3853*03ce13f7SAndroid Build Coastguard Worker Bool b(true);
3854*03ce13f7SAndroid Build Coastguard Worker Int i(-1);
3855*03ce13f7SAndroid Build Coastguard Worker Int2 i2(-1, -2);
3856*03ce13f7SAndroid Build Coastguard Worker Int4 i4(-1, -2, -3, -4);
3857*03ce13f7SAndroid Build Coastguard Worker UInt ui(1);
3858*03ce13f7SAndroid Build Coastguard Worker UInt2 ui2(1, 2);
3859*03ce13f7SAndroid Build Coastguard Worker UInt4 ui4(1, 2, 3, 4);
3860*03ce13f7SAndroid Build Coastguard Worker Short s(-1);
3861*03ce13f7SAndroid Build Coastguard Worker Short4 s4(-1, -2, -3, -4);
3862*03ce13f7SAndroid Build Coastguard Worker UShort us(1);
3863*03ce13f7SAndroid Build Coastguard Worker UShort4 us4(1, 2, 3, 4);
3864*03ce13f7SAndroid Build Coastguard Worker Float f(1);
3865*03ce13f7SAndroid Build Coastguard Worker Float4 f4(1, 2, 3, 4);
3866*03ce13f7SAndroid Build Coastguard Worker Long l(i);
3867*03ce13f7SAndroid Build Coastguard Worker Pointer<Int> pi = nullptr;
3868*03ce13f7SAndroid Build Coastguard Worker RValue<Int> rvi = i;
3869*03ce13f7SAndroid Build Coastguard Worker Byte by('a');
3870*03ce13f7SAndroid Build Coastguard Worker Byte4 by4(i4);
3871*03ce13f7SAndroid Build Coastguard Worker
3872*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(b);
3873*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(i);
3874*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(i2);
3875*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(i4);
3876*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(ui);
3877*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(ui2);
3878*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(ui4);
3879*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(s);
3880*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(s4);
3881*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(us);
3882*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(us4);
3883*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(f);
3884*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(f4);
3885*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(l);
3886*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(pi);
3887*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(rvi);
3888*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(by);
3889*03ce13f7SAndroid Build Coastguard Worker RR_WATCH(by4);
3890*03ce13f7SAndroid Build Coastguard Worker }
3891*03ce13f7SAndroid Build Coastguard Worker
3892*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3893*03ce13f7SAndroid Build Coastguard Worker
3894*03ce13f7SAndroid Build Coastguard Worker char piNullptr[64];
3895*03ce13f7SAndroid Build Coastguard Worker snprintf(piNullptr, sizeof(piNullptr), " pi: %p", nullptr);
3896*03ce13f7SAndroid Build Coastguard Worker
3897*03ce13f7SAndroid Build Coastguard Worker const char *expected[] = {
3898*03ce13f7SAndroid Build Coastguard Worker " b: true",
3899*03ce13f7SAndroid Build Coastguard Worker " i: -1",
3900*03ce13f7SAndroid Build Coastguard Worker " i2: [-1, -2]",
3901*03ce13f7SAndroid Build Coastguard Worker " i4: [-1, -2, -3, -4]",
3902*03ce13f7SAndroid Build Coastguard Worker " ui: 1",
3903*03ce13f7SAndroid Build Coastguard Worker " ui2: [1, 2]",
3904*03ce13f7SAndroid Build Coastguard Worker " ui4: [1, 2, 3, 4]",
3905*03ce13f7SAndroid Build Coastguard Worker " s: -1",
3906*03ce13f7SAndroid Build Coastguard Worker " s4: [-1, -2, -3, -4]",
3907*03ce13f7SAndroid Build Coastguard Worker " us: 1",
3908*03ce13f7SAndroid Build Coastguard Worker " us4: [1, 2, 3, 4]",
3909*03ce13f7SAndroid Build Coastguard Worker " f: 1.000000",
3910*03ce13f7SAndroid Build Coastguard Worker " f4: [1.000000, 2.000000, 3.000000, 4.000000]",
3911*03ce13f7SAndroid Build Coastguard Worker " l: -1",
3912*03ce13f7SAndroid Build Coastguard Worker piNullptr,
3913*03ce13f7SAndroid Build Coastguard Worker " rvi: -1",
3914*03ce13f7SAndroid Build Coastguard Worker " by: 97",
3915*03ce13f7SAndroid Build Coastguard Worker " by4: [255, 254, 253, 252]",
3916*03ce13f7SAndroid Build Coastguard Worker };
3917*03ce13f7SAndroid Build Coastguard Worker constexpr size_t expectedSize = sizeof(expected) / sizeof(expected[0]);
3918*03ce13f7SAndroid Build Coastguard Worker
3919*03ce13f7SAndroid Build Coastguard Worker StdOutCapture capture;
3920*03ce13f7SAndroid Build Coastguard Worker capture.start();
3921*03ce13f7SAndroid Build Coastguard Worker routine();
3922*03ce13f7SAndroid Build Coastguard Worker auto output = split(capture.stop());
3923*03ce13f7SAndroid Build Coastguard Worker for(size_t i = 0, j = 1; i < expectedSize; ++i, j += 2)
3924*03ce13f7SAndroid Build Coastguard Worker {
3925*03ce13f7SAndroid Build Coastguard Worker ASSERT_EQ(expected[i], output[j]);
3926*03ce13f7SAndroid Build Coastguard Worker }
3927*03ce13f7SAndroid Build Coastguard Worker
3928*03ce13f7SAndroid Build Coastguard Worker #endif
3929*03ce13f7SAndroid Build Coastguard Worker }
3930*03ce13f7SAndroid Build Coastguard Worker
3931*03ce13f7SAndroid Build Coastguard Worker // Test constant <op> variable
3932*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename Func>
Arithmetic_LhsConstArg(T arg1,T arg2,Func f)3933*03ce13f7SAndroid Build Coastguard Worker T Arithmetic_LhsConstArg(T arg1, T arg2, Func f)
3934*03ce13f7SAndroid Build Coastguard Worker {
3935*03ce13f7SAndroid Build Coastguard Worker using ReactorT = CToReactorT<T>;
3936*03ce13f7SAndroid Build Coastguard Worker
3937*03ce13f7SAndroid Build Coastguard Worker FunctionT<T(T)> function;
3938*03ce13f7SAndroid Build Coastguard Worker {
3939*03ce13f7SAndroid Build Coastguard Worker ReactorT lhs = arg1;
3940*03ce13f7SAndroid Build Coastguard Worker ReactorT rhs = function.template Arg<0>();
3941*03ce13f7SAndroid Build Coastguard Worker ReactorT result = f(lhs, rhs);
3942*03ce13f7SAndroid Build Coastguard Worker Return(result);
3943*03ce13f7SAndroid Build Coastguard Worker }
3944*03ce13f7SAndroid Build Coastguard Worker
3945*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3946*03ce13f7SAndroid Build Coastguard Worker return routine(arg2);
3947*03ce13f7SAndroid Build Coastguard Worker }
3948*03ce13f7SAndroid Build Coastguard Worker
3949*03ce13f7SAndroid Build Coastguard Worker // Test variable <op> constant
3950*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename Func>
Arithmetic_RhsConstArg(T arg1,T arg2,Func f)3951*03ce13f7SAndroid Build Coastguard Worker T Arithmetic_RhsConstArg(T arg1, T arg2, Func f)
3952*03ce13f7SAndroid Build Coastguard Worker {
3953*03ce13f7SAndroid Build Coastguard Worker using ReactorT = CToReactorT<T>;
3954*03ce13f7SAndroid Build Coastguard Worker
3955*03ce13f7SAndroid Build Coastguard Worker FunctionT<T(T)> function;
3956*03ce13f7SAndroid Build Coastguard Worker {
3957*03ce13f7SAndroid Build Coastguard Worker ReactorT lhs = function.template Arg<0>();
3958*03ce13f7SAndroid Build Coastguard Worker ReactorT rhs = arg2;
3959*03ce13f7SAndroid Build Coastguard Worker ReactorT result = f(lhs, rhs);
3960*03ce13f7SAndroid Build Coastguard Worker Return(result);
3961*03ce13f7SAndroid Build Coastguard Worker }
3962*03ce13f7SAndroid Build Coastguard Worker
3963*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3964*03ce13f7SAndroid Build Coastguard Worker return routine(arg1);
3965*03ce13f7SAndroid Build Coastguard Worker }
3966*03ce13f7SAndroid Build Coastguard Worker
3967*03ce13f7SAndroid Build Coastguard Worker // Test constant <op> constant
3968*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename Func>
Arithmetic_TwoConstArgs(T arg1,T arg2,Func f)3969*03ce13f7SAndroid Build Coastguard Worker T Arithmetic_TwoConstArgs(T arg1, T arg2, Func f)
3970*03ce13f7SAndroid Build Coastguard Worker {
3971*03ce13f7SAndroid Build Coastguard Worker using ReactorT = CToReactorT<T>;
3972*03ce13f7SAndroid Build Coastguard Worker
3973*03ce13f7SAndroid Build Coastguard Worker FunctionT<T()> function;
3974*03ce13f7SAndroid Build Coastguard Worker {
3975*03ce13f7SAndroid Build Coastguard Worker ReactorT lhs = arg1;
3976*03ce13f7SAndroid Build Coastguard Worker ReactorT rhs = arg2;
3977*03ce13f7SAndroid Build Coastguard Worker ReactorT result = f(lhs, rhs);
3978*03ce13f7SAndroid Build Coastguard Worker Return(result);
3979*03ce13f7SAndroid Build Coastguard Worker }
3980*03ce13f7SAndroid Build Coastguard Worker
3981*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
3982*03ce13f7SAndroid Build Coastguard Worker return routine();
3983*03ce13f7SAndroid Build Coastguard Worker }
3984*03ce13f7SAndroid Build Coastguard Worker
3985*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename Func>
Arithmetic_ConstArgs(T arg1,T arg2,T expected,Func f)3986*03ce13f7SAndroid Build Coastguard Worker void Arithmetic_ConstArgs(T arg1, T arg2, T expected, Func f)
3987*03ce13f7SAndroid Build Coastguard Worker {
3988*03ce13f7SAndroid Build Coastguard Worker SCOPED_TRACE(std::to_string(arg1) + " <op> " + std::to_string(arg2) + " = " + std::to_string(expected));
3989*03ce13f7SAndroid Build Coastguard Worker T result{};
3990*03ce13f7SAndroid Build Coastguard Worker result = Arithmetic_LhsConstArg(arg1, arg2, std::forward<Func>(f));
3991*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, expected);
3992*03ce13f7SAndroid Build Coastguard Worker result = Arithmetic_RhsConstArg(arg1, arg2, std::forward<Func>(f));
3993*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, expected);
3994*03ce13f7SAndroid Build Coastguard Worker result = Arithmetic_TwoConstArgs(arg1, arg2, std::forward<Func>(f));
3995*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, expected);
3996*03ce13f7SAndroid Build Coastguard Worker }
3997*03ce13f7SAndroid Build Coastguard Worker
3998*03ce13f7SAndroid Build Coastguard Worker // Test that we generate valid code for when one or both args to arithmetic operations
3999*03ce13f7SAndroid Build Coastguard Worker // are constant. In particular, we want to validate the case for two const args, as
4000*03ce13f7SAndroid Build Coastguard Worker // often lowered instructions do not support this case.
TEST(ReactorUnitTests,Arithmetic_ConstantArgs)4001*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, Arithmetic_ConstantArgs)
4002*03ce13f7SAndroid Build Coastguard Worker {
4003*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(2, 3, 5, [](auto c1, auto c2) { return c1 + c2; });
4004*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(5, 3, 2, [](auto c1, auto c2) { return c1 - c2; });
4005*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(2, 3, 6, [](auto c1, auto c2) { return c1 * c2; });
4006*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(6, 3, 2, [](auto c1, auto c2) { return c1 / c2; });
4007*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(0xF0F0, 0xAAAA, 0xA0A0, [](auto c1, auto c2) { return c1 & c2; });
4008*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(0xF0F0, 0xAAAA, 0xFAFA, [](auto c1, auto c2) { return c1 | c2; });
4009*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(0xF0F0, 0xAAAA, 0x5A5A, [](auto c1, auto c2) { return c1 ^ c2; });
4010*03ce13f7SAndroid Build Coastguard Worker
4011*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(2.f, 3.f, 5.f, [](auto c1, auto c2) { return c1 + c2; });
4012*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(5.f, 3.f, 2.f, [](auto c1, auto c2) { return c1 - c2; });
4013*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(2.f, 3.f, 6.f, [](auto c1, auto c2) { return c1 * c2; });
4014*03ce13f7SAndroid Build Coastguard Worker Arithmetic_ConstArgs(6.f, 3.f, 2.f, [](auto c1, auto c2) { return c1 / c2; });
4015*03ce13f7SAndroid Build Coastguard Worker }
4016*03ce13f7SAndroid Build Coastguard Worker
4017*03ce13f7SAndroid Build Coastguard Worker // Test for Subzero bad code-gen that was fixed in swiftshader-cl/50008
4018*03ce13f7SAndroid Build Coastguard Worker // This tests the case of copying enough arguments to local variables so that the locals
4019*03ce13f7SAndroid Build Coastguard Worker // get spilled to the stack when no more registers remain, and making sure these copies
4020*03ce13f7SAndroid Build Coastguard Worker // are generated correctly. Without the aforementioned fix, this fails 100% on Windows x86.
TEST(ReactorUnitTests,SpillLocalCopiesOfArgs)4021*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, SpillLocalCopiesOfArgs)
4022*03ce13f7SAndroid Build Coastguard Worker {
4023*03ce13f7SAndroid Build Coastguard Worker struct Helpers
4024*03ce13f7SAndroid Build Coastguard Worker {
4025*03ce13f7SAndroid Build Coastguard Worker static bool True() { return true; }
4026*03ce13f7SAndroid Build Coastguard Worker };
4027*03ce13f7SAndroid Build Coastguard Worker
4028*03ce13f7SAndroid Build Coastguard Worker const int numLoops = 5; // 2 should be enough, but loop more to make sure
4029*03ce13f7SAndroid Build Coastguard Worker
4030*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(int, int, int, int, int, int, int, int, int, int, int, int)> function;
4031*03ce13f7SAndroid Build Coastguard Worker {
4032*03ce13f7SAndroid Build Coastguard Worker Int result = 0;
4033*03ce13f7SAndroid Build Coastguard Worker Int a1 = function.Arg<0>();
4034*03ce13f7SAndroid Build Coastguard Worker Int a2 = function.Arg<1>();
4035*03ce13f7SAndroid Build Coastguard Worker Int a3 = function.Arg<2>();
4036*03ce13f7SAndroid Build Coastguard Worker Int a4 = function.Arg<3>();
4037*03ce13f7SAndroid Build Coastguard Worker Int a5 = function.Arg<4>();
4038*03ce13f7SAndroid Build Coastguard Worker Int a6 = function.Arg<5>();
4039*03ce13f7SAndroid Build Coastguard Worker Int a7 = function.Arg<6>();
4040*03ce13f7SAndroid Build Coastguard Worker Int a8 = function.Arg<7>();
4041*03ce13f7SAndroid Build Coastguard Worker Int a9 = function.Arg<8>();
4042*03ce13f7SAndroid Build Coastguard Worker Int a10 = function.Arg<9>();
4043*03ce13f7SAndroid Build Coastguard Worker Int a11 = function.Arg<10>();
4044*03ce13f7SAndroid Build Coastguard Worker Int a12 = function.Arg<11>();
4045*03ce13f7SAndroid Build Coastguard Worker
4046*03ce13f7SAndroid Build Coastguard Worker for(int i = 0; i < numLoops; ++i)
4047*03ce13f7SAndroid Build Coastguard Worker {
4048*03ce13f7SAndroid Build Coastguard Worker // Copy all arguments to locals so that Ice::LocalVariableSplitter::handleSimpleVarAssign
4049*03ce13f7SAndroid Build Coastguard Worker // creates Variable copies of arguments. We loop so that we create enough of these so
4050*03ce13f7SAndroid Build Coastguard Worker // that some spill over to the stack.
4051*03ce13f7SAndroid Build Coastguard Worker Int i1 = a1;
4052*03ce13f7SAndroid Build Coastguard Worker Int i2 = a2;
4053*03ce13f7SAndroid Build Coastguard Worker Int i3 = a3;
4054*03ce13f7SAndroid Build Coastguard Worker Int i4 = a4;
4055*03ce13f7SAndroid Build Coastguard Worker Int i5 = a5;
4056*03ce13f7SAndroid Build Coastguard Worker Int i6 = a6;
4057*03ce13f7SAndroid Build Coastguard Worker Int i7 = a7;
4058*03ce13f7SAndroid Build Coastguard Worker Int i8 = a8;
4059*03ce13f7SAndroid Build Coastguard Worker Int i9 = a9;
4060*03ce13f7SAndroid Build Coastguard Worker Int i10 = a10;
4061*03ce13f7SAndroid Build Coastguard Worker Int i11 = a11;
4062*03ce13f7SAndroid Build Coastguard Worker Int i12 = a12;
4063*03ce13f7SAndroid Build Coastguard Worker
4064*03ce13f7SAndroid Build Coastguard Worker // Forcibly materialize all variables so that Ice::Variable instances are created for each
4065*03ce13f7SAndroid Build Coastguard Worker // local; otherwise, Reactor r-value optimizations kick in, and the locals are elided.
4066*03ce13f7SAndroid Build Coastguard Worker Variable::materializeAll();
4067*03ce13f7SAndroid Build Coastguard Worker
4068*03ce13f7SAndroid Build Coastguard Worker // We also need to create a separate block that uses the variables declared above
4069*03ce13f7SAndroid Build Coastguard Worker // so that rr::optimize() doesn't optimize them out when attempting to eliminate stores
4070*03ce13f7SAndroid Build Coastguard Worker // followed by a load in the same block.
4071*03ce13f7SAndroid Build Coastguard Worker If(Call(Helpers::True))
4072*03ce13f7SAndroid Build Coastguard Worker {
4073*03ce13f7SAndroid Build Coastguard Worker result += (i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12);
4074*03ce13f7SAndroid Build Coastguard Worker }
4075*03ce13f7SAndroid Build Coastguard Worker }
4076*03ce13f7SAndroid Build Coastguard Worker
4077*03ce13f7SAndroid Build Coastguard Worker Return(result);
4078*03ce13f7SAndroid Build Coastguard Worker }
4079*03ce13f7SAndroid Build Coastguard Worker
4080*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
4081*03ce13f7SAndroid Build Coastguard Worker int result = routine(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
4082*03ce13f7SAndroid Build Coastguard Worker int expected = numLoops * (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12);
4083*03ce13f7SAndroid Build Coastguard Worker EXPECT_EQ(result, expected);
4084*03ce13f7SAndroid Build Coastguard Worker }
4085*03ce13f7SAndroid Build Coastguard Worker
4086*03ce13f7SAndroid Build Coastguard Worker #if defined(ENABLE_RR_EMIT_ASM_FILE)
TEST(ReactorUnitTests,EmitAsm)4087*03ce13f7SAndroid Build Coastguard Worker TEST(ReactorUnitTests, EmitAsm)
4088*03ce13f7SAndroid Build Coastguard Worker {
4089*03ce13f7SAndroid Build Coastguard Worker // Only supported by LLVM for now
4090*03ce13f7SAndroid Build Coastguard Worker if(Caps::backendName().find("LLVM") == std::string::npos) return;
4091*03ce13f7SAndroid Build Coastguard Worker
4092*03ce13f7SAndroid Build Coastguard Worker namespace fs = std::filesystem;
4093*03ce13f7SAndroid Build Coastguard Worker
4094*03ce13f7SAndroid Build Coastguard Worker FunctionT<int(void)> function;
4095*03ce13f7SAndroid Build Coastguard Worker {
4096*03ce13f7SAndroid Build Coastguard Worker Int sum;
4097*03ce13f7SAndroid Build Coastguard Worker For(Int i = 0, i < 10, i++)
4098*03ce13f7SAndroid Build Coastguard Worker {
4099*03ce13f7SAndroid Build Coastguard Worker sum += i;
4100*03ce13f7SAndroid Build Coastguard Worker }
4101*03ce13f7SAndroid Build Coastguard Worker Return(sum);
4102*03ce13f7SAndroid Build Coastguard Worker }
4103*03ce13f7SAndroid Build Coastguard Worker
4104*03ce13f7SAndroid Build Coastguard Worker auto routine = function(testName().c_str());
4105*03ce13f7SAndroid Build Coastguard Worker
4106*03ce13f7SAndroid Build Coastguard Worker // Returns path to first match of filename in current directory
4107*03ce13f7SAndroid Build Coastguard Worker auto findFile = [](const std::string filename) -> fs::path {
4108*03ce13f7SAndroid Build Coastguard Worker for(auto &p : fs::directory_iterator("."))
4109*03ce13f7SAndroid Build Coastguard Worker {
4110*03ce13f7SAndroid Build Coastguard Worker if(!p.is_regular_file())
4111*03ce13f7SAndroid Build Coastguard Worker continue;
4112*03ce13f7SAndroid Build Coastguard Worker auto currFilename = p.path().filename().string();
4113*03ce13f7SAndroid Build Coastguard Worker auto index = currFilename.find(testName());
4114*03ce13f7SAndroid Build Coastguard Worker if(index != std::string::npos)
4115*03ce13f7SAndroid Build Coastguard Worker {
4116*03ce13f7SAndroid Build Coastguard Worker return p.path();
4117*03ce13f7SAndroid Build Coastguard Worker }
4118*03ce13f7SAndroid Build Coastguard Worker }
4119*03ce13f7SAndroid Build Coastguard Worker return {};
4120*03ce13f7SAndroid Build Coastguard Worker };
4121*03ce13f7SAndroid Build Coastguard Worker
4122*03ce13f7SAndroid Build Coastguard Worker fs::path path = findFile(testName());
4123*03ce13f7SAndroid Build Coastguard Worker EXPECT_FALSE(path.empty());
4124*03ce13f7SAndroid Build Coastguard Worker
4125*03ce13f7SAndroid Build Coastguard Worker // Make sure an asm file was created
4126*03ce13f7SAndroid Build Coastguard Worker std::ifstream fin(path);
4127*03ce13f7SAndroid Build Coastguard Worker EXPECT_TRUE(fin);
4128*03ce13f7SAndroid Build Coastguard Worker
4129*03ce13f7SAndroid Build Coastguard Worker // Make sure address of routine is in the file
4130*03ce13f7SAndroid Build Coastguard Worker auto findAddressInFile = [](std::ifstream &fin, size_t address) {
4131*03ce13f7SAndroid Build Coastguard Worker std::string addressString = [&] {
4132*03ce13f7SAndroid Build Coastguard Worker std::stringstream addressSS;
4133*03ce13f7SAndroid Build Coastguard Worker addressSS << "0x" << std::uppercase << std::hex << address;
4134*03ce13f7SAndroid Build Coastguard Worker return addressSS.str();
4135*03ce13f7SAndroid Build Coastguard Worker }();
4136*03ce13f7SAndroid Build Coastguard Worker
4137*03ce13f7SAndroid Build Coastguard Worker std::string token;
4138*03ce13f7SAndroid Build Coastguard Worker while(fin >> token)
4139*03ce13f7SAndroid Build Coastguard Worker {
4140*03ce13f7SAndroid Build Coastguard Worker if(token.find(addressString) != std::string::npos)
4141*03ce13f7SAndroid Build Coastguard Worker return true;
4142*03ce13f7SAndroid Build Coastguard Worker }
4143*03ce13f7SAndroid Build Coastguard Worker return false;
4144*03ce13f7SAndroid Build Coastguard Worker };
4145*03ce13f7SAndroid Build Coastguard Worker
4146*03ce13f7SAndroid Build Coastguard Worker size_t address = reinterpret_cast<size_t>(routine.getEntry());
4147*03ce13f7SAndroid Build Coastguard Worker EXPECT_TRUE(findAddressInFile(fin, address));
4148*03ce13f7SAndroid Build Coastguard Worker
4149*03ce13f7SAndroid Build Coastguard Worker // Delete the file in case subsequent runs generate one with a different sequence number
4150*03ce13f7SAndroid Build Coastguard Worker fin.close();
4151*03ce13f7SAndroid Build Coastguard Worker std::filesystem::remove(path);
4152*03ce13f7SAndroid Build Coastguard Worker }
4153*03ce13f7SAndroid Build Coastguard Worker #endif
4154*03ce13f7SAndroid Build Coastguard Worker
4155*03ce13f7SAndroid Build Coastguard Worker ////////////////////////////////
4156*03ce13f7SAndroid Build Coastguard Worker // Trait compile time checks. //
4157*03ce13f7SAndroid Build Coastguard Worker ////////////////////////////////
4158*03ce13f7SAndroid Build Coastguard Worker
4159*03ce13f7SAndroid Build Coastguard Worker // Assert CToReactorT resolves to expected types.
4160*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<void>, Void>::value, "");
4161*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<bool>, Bool>::value, "");
4162*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint8_t>, Byte>::value, "");
4163*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<int8_t>, SByte>::value, "");
4164*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<int16_t>, Short>::value, "");
4165*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint16_t>, UShort>::value, "");
4166*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<int32_t>, Int>::value, "");
4167*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint64_t>, Long>::value, "");
4168*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint32_t>, UInt>::value, "");
4169*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<float>, Float>::value, "");
4170*03ce13f7SAndroid Build Coastguard Worker
4171*03ce13f7SAndroid Build Coastguard Worker // Assert CToReactorT for known pointer types resolves to expected types.
4172*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<void *>, Pointer<Byte>>::value, "");
4173*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<bool *>, Pointer<Bool>>::value, "");
4174*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint8_t *>, Pointer<Byte>>::value, "");
4175*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<int8_t *>, Pointer<SByte>>::value, "");
4176*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<int16_t *>, Pointer<Short>>::value, "");
4177*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint16_t *>, Pointer<UShort>>::value, "");
4178*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<int32_t *>, Pointer<Int>>::value, "");
4179*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint64_t *>, Pointer<Long>>::value, "");
4180*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint32_t *>, Pointer<UInt>>::value, "");
4181*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<float *>, Pointer<Float>>::value, "");
4182*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint16_t **>, Pointer<Pointer<UShort>>>::value, "");
4183*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<uint16_t ***>, Pointer<Pointer<Pointer<UShort>>>>::value, "");
4184*03ce13f7SAndroid Build Coastguard Worker
4185*03ce13f7SAndroid Build Coastguard Worker // Assert CToReactorT for unknown pointer types resolves to Pointer<Byte>.
4186*03ce13f7SAndroid Build Coastguard Worker struct S
4187*03ce13f7SAndroid Build Coastguard Worker {};
4188*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<S *>, Pointer<Byte>>::value, "");
4189*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<S **>, Pointer<Pointer<Byte>>>::value, "");
4190*03ce13f7SAndroid Build Coastguard Worker static_assert(std::is_same<CToReactorT<S ***>, Pointer<Pointer<Pointer<Byte>>>>::value, "");
4191*03ce13f7SAndroid Build Coastguard Worker
4192*03ce13f7SAndroid Build Coastguard Worker // Assert IsRValue<> resolves true for RValue<> types.
4193*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<Void>>::value, "");
4194*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<Bool>>::value, "");
4195*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<Byte>>::value, "");
4196*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<SByte>>::value, "");
4197*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<Short>>::value, "");
4198*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<UShort>>::value, "");
4199*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<Int>>::value, "");
4200*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<Long>>::value, "");
4201*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<UInt>>::value, "");
4202*03ce13f7SAndroid Build Coastguard Worker static_assert(IsRValue<RValue<Float>>::value, "");
4203*03ce13f7SAndroid Build Coastguard Worker
4204*03ce13f7SAndroid Build Coastguard Worker // Assert IsLValue<> resolves true for LValue types.
4205*03ce13f7SAndroid Build Coastguard Worker static_assert(IsLValue<Bool>::value, "");
4206*03ce13f7SAndroid Build Coastguard Worker static_assert(IsLValue<Byte>::value, "");
4207*03ce13f7SAndroid Build Coastguard Worker static_assert(IsLValue<SByte>::value, "");
4208*03ce13f7SAndroid Build Coastguard Worker static_assert(IsLValue<Short>::value, "");
4209*03ce13f7SAndroid Build Coastguard Worker static_assert(IsLValue<UShort>::value, "");
4210*03ce13f7SAndroid Build Coastguard Worker static_assert(IsLValue<Int>::value, "");
4211*03ce13f7SAndroid Build Coastguard Worker static_assert(IsLValue<Long>::value, "");
4212*03ce13f7SAndroid Build Coastguard Worker static_assert(IsLValue<UInt>::value, "");
4213*03ce13f7SAndroid Build Coastguard Worker static_assert(IsLValue<Float>::value, "");
4214*03ce13f7SAndroid Build Coastguard Worker
4215*03ce13f7SAndroid Build Coastguard Worker // Assert IsReference<> resolves true for Reference types.
4216*03ce13f7SAndroid Build Coastguard Worker static_assert(IsReference<Reference<Bool>>::value, "");
4217*03ce13f7SAndroid Build Coastguard Worker static_assert(IsReference<Reference<Byte>>::value, "");
4218*03ce13f7SAndroid Build Coastguard Worker static_assert(IsReference<Reference<SByte>>::value, "");
4219*03ce13f7SAndroid Build Coastguard Worker static_assert(IsReference<Reference<Short>>::value, "");
4220*03ce13f7SAndroid Build Coastguard Worker static_assert(IsReference<Reference<UShort>>::value, "");
4221*03ce13f7SAndroid Build Coastguard Worker static_assert(IsReference<Reference<Int>>::value, "");
4222*03ce13f7SAndroid Build Coastguard Worker static_assert(IsReference<Reference<Long>>::value, "");
4223*03ce13f7SAndroid Build Coastguard Worker static_assert(IsReference<Reference<UInt>>::value, "");
4224*03ce13f7SAndroid Build Coastguard Worker static_assert(IsReference<Reference<Float>>::value, "");
4225*03ce13f7SAndroid Build Coastguard Worker
4226*03ce13f7SAndroid Build Coastguard Worker // Assert IsRValue<> resolves false for LValue types.
4227*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Void>::value, "");
4228*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Bool>::value, "");
4229*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Byte>::value, "");
4230*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<SByte>::value, "");
4231*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Short>::value, "");
4232*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<UShort>::value, "");
4233*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Int>::value, "");
4234*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Long>::value, "");
4235*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<UInt>::value, "");
4236*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Float>::value, "");
4237*03ce13f7SAndroid Build Coastguard Worker
4238*03ce13f7SAndroid Build Coastguard Worker // Assert IsRValue<> resolves false for Reference types.
4239*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<Void>>::value, "");
4240*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<Bool>>::value, "");
4241*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<Byte>>::value, "");
4242*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<SByte>>::value, "");
4243*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<Short>>::value, "");
4244*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<UShort>>::value, "");
4245*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<Int>>::value, "");
4246*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<Long>>::value, "");
4247*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<UInt>>::value, "");
4248*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<Reference<Float>>::value, "");
4249*03ce13f7SAndroid Build Coastguard Worker
4250*03ce13f7SAndroid Build Coastguard Worker // Assert IsRValue<> resolves false for C types.
4251*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<void>::value, "");
4252*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<bool>::value, "");
4253*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<uint8_t>::value, "");
4254*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<int8_t>::value, "");
4255*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<int16_t>::value, "");
4256*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<uint16_t>::value, "");
4257*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<int32_t>::value, "");
4258*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<uint64_t>::value, "");
4259*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<uint32_t>::value, "");
4260*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsRValue<float>::value, "");
4261*03ce13f7SAndroid Build Coastguard Worker
4262*03ce13f7SAndroid Build Coastguard Worker // Assert IsLValue<> resolves false for RValue<> types.
4263*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<Void>>::value, "");
4264*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<Bool>>::value, "");
4265*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<Byte>>::value, "");
4266*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<SByte>>::value, "");
4267*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<Short>>::value, "");
4268*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<UShort>>::value, "");
4269*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<Int>>::value, "");
4270*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<Long>>::value, "");
4271*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<UInt>>::value, "");
4272*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<RValue<Float>>::value, "");
4273*03ce13f7SAndroid Build Coastguard Worker
4274*03ce13f7SAndroid Build Coastguard Worker // Assert IsLValue<> resolves false for Void type.
4275*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Void>::value, "");
4276*03ce13f7SAndroid Build Coastguard Worker
4277*03ce13f7SAndroid Build Coastguard Worker // Assert IsLValue<> resolves false for Reference<> types.
4278*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<Void>>::value, "");
4279*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<Bool>>::value, "");
4280*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<Byte>>::value, "");
4281*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<SByte>>::value, "");
4282*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<Short>>::value, "");
4283*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<UShort>>::value, "");
4284*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<Int>>::value, "");
4285*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<Long>>::value, "");
4286*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<UInt>>::value, "");
4287*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<Reference<Float>>::value, "");
4288*03ce13f7SAndroid Build Coastguard Worker
4289*03ce13f7SAndroid Build Coastguard Worker // Assert IsLValue<> resolves false for C types.
4290*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<void>::value, "");
4291*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<bool>::value, "");
4292*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<uint8_t>::value, "");
4293*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<int8_t>::value, "");
4294*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<int16_t>::value, "");
4295*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<uint16_t>::value, "");
4296*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<int32_t>::value, "");
4297*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<uint64_t>::value, "");
4298*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<uint32_t>::value, "");
4299*03ce13f7SAndroid Build Coastguard Worker static_assert(!IsLValue<float>::value, "");
4300*03ce13f7SAndroid Build Coastguard Worker
4301*03ce13f7SAndroid Build Coastguard Worker // Assert IsDefined<> resolves true for RValue<> types.
4302*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<Void>>::value, "");
4303*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<Bool>>::value, "");
4304*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<Byte>>::value, "");
4305*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<SByte>>::value, "");
4306*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<Short>>::value, "");
4307*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<UShort>>::value, "");
4308*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<Int>>::value, "");
4309*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<Long>>::value, "");
4310*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<UInt>>::value, "");
4311*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<RValue<Float>>::value, "");
4312*03ce13f7SAndroid Build Coastguard Worker
4313*03ce13f7SAndroid Build Coastguard Worker // Assert IsDefined<> resolves true for LValue types.
4314*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Void>::value, "");
4315*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Bool>::value, "");
4316*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Byte>::value, "");
4317*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<SByte>::value, "");
4318*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Short>::value, "");
4319*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<UShort>::value, "");
4320*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Int>::value, "");
4321*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Long>::value, "");
4322*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<UInt>::value, "");
4323*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Float>::value, "");
4324*03ce13f7SAndroid Build Coastguard Worker
4325*03ce13f7SAndroid Build Coastguard Worker // Assert IsDefined<> resolves true for Reference<> types.
4326*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Reference<Bool>>::value, "");
4327*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Reference<Byte>>::value, "");
4328*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Reference<SByte>>::value, "");
4329*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Reference<Short>>::value, "");
4330*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Reference<UShort>>::value, "");
4331*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Reference<Int>>::value, "");
4332*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Reference<Long>>::value, "");
4333*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Reference<UInt>>::value, "");
4334*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<Reference<Float>>::value, "");
4335*03ce13f7SAndroid Build Coastguard Worker
4336*03ce13f7SAndroid Build Coastguard Worker // Assert IsDefined<> resolves true for C types.
4337*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<void>::value, "");
4338*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<bool>::value, "");
4339*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<uint8_t>::value, "");
4340*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<int8_t>::value, "");
4341*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<int16_t>::value, "");
4342*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<uint16_t>::value, "");
4343*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<int32_t>::value, "");
4344*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<uint64_t>::value, "");
4345*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<uint32_t>::value, "");
4346*03ce13f7SAndroid Build Coastguard Worker static_assert(IsDefined<float>::value, "");
4347