1/*
2 * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "testb3.h"
28
29#if ENABLE(B3_JIT)
30
31Lock crashLock;
32
33bool shouldRun(const char* filter, const char* testName)
34{
35 // FIXME: These tests fail <https://bugs.webkit.org/show_bug.cgi?id=199330>.
36 if (!filter && isARM64()) {
37 for (auto& failingTest : {
38 "testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead",
39 "testNegFloatWithUselessDoubleConversion",
40 "testPinRegisters",
41 }) {
42 if (WTF::findIgnoringASCIICaseWithoutLength(testName, failingTest) != WTF::notFound) {
43 dataLogLn("*** Warning: Skipping known-bad test: ", testName);
44 return false;
45 }
46 }
47 }
48 if (!filter && isX86()) {
49 for (auto& failingTest : {
50 "testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead",
51 }) {
52 if (WTF::findIgnoringASCIICaseWithoutLength(testName, failingTest) != WTF::notFound) {
53 dataLogLn("*** Warning: Skipping known-bad test: ", testName);
54 return false;
55 }
56 }
57 }
58 return !filter || WTF::findIgnoringASCIICaseWithoutLength(testName, filter) != WTF::notFound;
59}
60
61template<typename T>
62void testRotR(T valueInt, int32_t shift)
63{
64 Procedure proc;
65 BasicBlock* root = proc.addBlock();
66
67 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
68 if (sizeof(T) == 4)
69 value = root->appendNew<Value>(proc, Trunc, Origin(), value);
70
71 Value* ammount = root->appendNew<Value>(proc, Trunc, Origin(),
72 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
73 root->appendNewControlValue(proc, Return, Origin(),
74 root->appendNew<Value>(proc, RotR, Origin(), value, ammount));
75
76 CHECK_EQ(compileAndRun<T>(proc, valueInt, shift), rotateRight(valueInt, shift));
77}
78
79template<typename T>
80void testRotL(T valueInt, int32_t shift)
81{
82 Procedure proc;
83 BasicBlock* root = proc.addBlock();
84
85 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
86 if (sizeof(T) == 4)
87 value = root->appendNew<Value>(proc, Trunc, Origin(), value);
88
89 Value* ammount = root->appendNew<Value>(proc, Trunc, Origin(),
90 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
91 root->appendNewControlValue(proc, Return, Origin(),
92 root->appendNew<Value>(proc, RotL, Origin(), value, ammount));
93
94 CHECK_EQ(compileAndRun<T>(proc, valueInt, shift), rotateLeft(valueInt, shift));
95}
96
97
98template<typename T>
99void testRotRWithImmShift(T valueInt, int32_t shift)
100{
101 Procedure proc;
102 BasicBlock* root = proc.addBlock();
103
104 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
105 if (sizeof(T) == 4)
106 value = root->appendNew<Value>(proc, Trunc, Origin(), value);
107
108 Value* ammount = root->appendIntConstant(proc, Origin(), Int32, shift);
109 root->appendNewControlValue(proc, Return, Origin(),
110 root->appendNew<Value>(proc, RotR, Origin(), value, ammount));
111
112 CHECK_EQ(compileAndRun<T>(proc, valueInt, shift), rotateRight(valueInt, shift));
113}
114
115template<typename T>
116void testRotLWithImmShift(T valueInt, int32_t shift)
117{
118 Procedure proc;
119 BasicBlock* root = proc.addBlock();
120
121 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
122 if (sizeof(T) == 4)
123 value = root->appendNew<Value>(proc, Trunc, Origin(), value);
124
125 Value* ammount = root->appendIntConstant(proc, Origin(), Int32, shift);
126 root->appendNewControlValue(proc, Return, Origin(),
127 root->appendNew<Value>(proc, RotL, Origin(), value, ammount));
128
129 CHECK_EQ(compileAndRun<T>(proc, valueInt, shift), rotateLeft(valueInt, shift));
130}
131
132template<typename T>
133void testComputeDivisionMagic(T value, T magicMultiplier, unsigned shift)
134{
135 DivisionMagic<T> magic = computeDivisionMagic(value);
136 CHECK(magic.magicMultiplier == magicMultiplier);
137 CHECK(magic.shift == shift);
138}
139
140void run(const char* filter)
141{
142 Deque<RefPtr<SharedTask<void()>>> tasks;
143
144 RUN_NOW(testTerminalPatchpointThatNeedsToBeSpilled2());
145 RUN(test42());
146 RUN(testLoad42());
147 RUN(testLoadAcq42());
148 RUN(testLoadOffsetImm9Max());
149 RUN(testLoadOffsetImm9MaxPlusOne());
150 RUN(testLoadOffsetImm9MaxPlusTwo());
151 RUN(testLoadOffsetImm9Min());
152 RUN(testLoadOffsetImm9MinMinusOne());
153 RUN(testLoadOffsetScaledUnsignedImm12Max());
154 RUN(testLoadOffsetScaledUnsignedOverImm12Max());
155 RUN(testArg(43));
156 RUN(testReturnConst64(5));
157 RUN(testReturnConst64(-42));
158 RUN(testReturnVoid());
159
160 RUN_UNARY(testAddTreeArg32, int32Operands());
161 RUN_UNARY(testMulTreeArg32, int32Operands());
162
163 addArgTests(filter, tasks);
164
165 RUN_UNARY(testNegDouble, floatingPointOperands<double>());
166 RUN_UNARY(testNegFloat, floatingPointOperands<float>());
167 RUN_UNARY(testNegFloatWithUselessDoubleConversion, floatingPointOperands<float>());
168
169 addBitTests(filter, tasks);
170
171 RUN(testShlArgs(1, 0));
172 RUN(testShlArgs(1, 1));
173 RUN(testShlArgs(1, 62));
174 RUN(testShlArgs(0xffffffffffffffff, 0));
175 RUN(testShlArgs(0xffffffffffffffff, 1));
176 RUN(testShlArgs(0xffffffffffffffff, 63));
177 RUN(testShlImms(1, 0));
178 RUN(testShlImms(1, 1));
179 RUN(testShlImms(1, 62));
180 RUN(testShlImms(1, 65));
181 RUN(testShlImms(0xffffffffffffffff, 0));
182 RUN(testShlImms(0xffffffffffffffff, 1));
183 RUN(testShlImms(0xffffffffffffffff, 63));
184 RUN(testShlArgImm(1, 0));
185 RUN(testShlArgImm(1, 1));
186 RUN(testShlArgImm(1, 62));
187 RUN(testShlArgImm(1, 65));
188 RUN(testShlArgImm(0xffffffffffffffff, 0));
189 RUN(testShlArgImm(0xffffffffffffffff, 1));
190 RUN(testShlArgImm(0xffffffffffffffff, 63));
191 RUN(testShlSShrArgImm(1, 0));
192 RUN(testShlSShrArgImm(1, 1));
193 RUN(testShlSShrArgImm(1, 62));
194 RUN(testShlSShrArgImm(1, 65));
195 RUN(testShlSShrArgImm(0xffffffffffffffff, 0));
196 RUN(testShlSShrArgImm(0xffffffffffffffff, 1));
197 RUN(testShlSShrArgImm(0xffffffffffffffff, 63));
198 RUN(testShlArg32(2));
199 RUN(testShlArgs32(1, 0));
200 RUN(testShlArgs32(1, 1));
201 RUN(testShlArgs32(1, 62));
202 RUN(testShlImms32(1, 33));
203 RUN(testShlArgs32(0xffffffff, 0));
204 RUN(testShlArgs32(0xffffffff, 1));
205 RUN(testShlArgs32(0xffffffff, 63));
206 RUN(testShlImms32(1, 0));
207 RUN(testShlImms32(1, 1));
208 RUN(testShlImms32(1, 62));
209 RUN(testShlImms32(1, 33));
210 RUN(testShlImms32(0xffffffff, 0));
211 RUN(testShlImms32(0xffffffff, 1));
212 RUN(testShlImms32(0xffffffff, 63));
213 RUN(testShlArgImm32(1, 0));
214 RUN(testShlArgImm32(1, 1));
215 RUN(testShlArgImm32(1, 62));
216 RUN(testShlArgImm32(1, 33));
217 RUN(testShlArgImm32(0xffffffff, 0));
218 RUN(testShlArgImm32(0xffffffff, 1));
219 RUN(testShlArgImm32(0xffffffff, 63));
220 RUN(testShlZShrArgImm32(1, 0));
221 RUN(testShlZShrArgImm32(1, 1));
222 RUN(testShlZShrArgImm32(1, 62));
223 RUN(testShlZShrArgImm32(1, 33));
224 RUN(testShlZShrArgImm32(0xffffffff, 0));
225 RUN(testShlZShrArgImm32(0xffffffff, 1));
226 RUN(testShlZShrArgImm32(0xffffffff, 63));
227
228 addShrTests(filter, tasks);
229
230 RUN_UNARY(testClzArg64, int64Operands());
231 RUN_UNARY(testClzMem64, int64Operands());
232 RUN_UNARY(testClzArg32, int32Operands());
233 RUN_UNARY(testClzMem32, int64Operands());
234
235 RUN_UNARY(testAbsArg, floatingPointOperands<double>());
236 RUN_UNARY(testAbsImm, floatingPointOperands<double>());
237 RUN_UNARY(testAbsMem, floatingPointOperands<double>());
238 RUN_UNARY(testAbsAbsArg, floatingPointOperands<double>());
239 RUN_UNARY(testAbsNegArg, floatingPointOperands<double>());
240 RUN_UNARY(testAbsBitwiseCastArg, floatingPointOperands<double>());
241 RUN_UNARY(testBitwiseCastAbsBitwiseCastArg, floatingPointOperands<double>());
242 RUN_UNARY(testAbsArg, floatingPointOperands<float>());
243 RUN_UNARY(testAbsImm, floatingPointOperands<float>());
244 RUN_UNARY(testAbsMem, floatingPointOperands<float>());
245 RUN_UNARY(testAbsAbsArg, floatingPointOperands<float>());
246 RUN_UNARY(testAbsNegArg, floatingPointOperands<float>());
247 RUN_UNARY(testAbsBitwiseCastArg, floatingPointOperands<float>());
248 RUN_UNARY(testBitwiseCastAbsBitwiseCastArg, floatingPointOperands<float>());
249 RUN_UNARY(testAbsArgWithUselessDoubleConversion, floatingPointOperands<float>());
250 RUN_UNARY(testAbsArgWithEffectfulDoubleConversion, floatingPointOperands<float>());
251
252 RUN_UNARY(testCeilArg, floatingPointOperands<double>());
253 RUN_UNARY(testCeilImm, floatingPointOperands<double>());
254 RUN_UNARY(testCeilMem, floatingPointOperands<double>());
255 RUN_UNARY(testCeilCeilArg, floatingPointOperands<double>());
256 RUN_UNARY(testFloorCeilArg, floatingPointOperands<double>());
257 RUN_UNARY(testCeilIToD64, int64Operands());
258 RUN_UNARY(testCeilIToD32, int32Operands());
259 RUN_UNARY(testCeilArg, floatingPointOperands<float>());
260 RUN_UNARY(testCeilImm, floatingPointOperands<float>());
261 RUN_UNARY(testCeilMem, floatingPointOperands<float>());
262 RUN_UNARY(testCeilCeilArg, floatingPointOperands<float>());
263 RUN_UNARY(testFloorCeilArg, floatingPointOperands<float>());
264 RUN_UNARY(testCeilArgWithUselessDoubleConversion, floatingPointOperands<float>());
265 RUN_UNARY(testCeilArgWithEffectfulDoubleConversion, floatingPointOperands<float>());
266
267 RUN_UNARY(testFloorArg, floatingPointOperands<double>());
268 RUN_UNARY(testFloorImm, floatingPointOperands<double>());
269 RUN_UNARY(testFloorMem, floatingPointOperands<double>());
270 RUN_UNARY(testFloorFloorArg, floatingPointOperands<double>());
271 RUN_UNARY(testCeilFloorArg, floatingPointOperands<double>());
272 RUN_UNARY(testFloorIToD64, int64Operands());
273 RUN_UNARY(testFloorIToD32, int32Operands());
274 RUN_UNARY(testFloorArg, floatingPointOperands<float>());
275 RUN_UNARY(testFloorImm, floatingPointOperands<float>());
276 RUN_UNARY(testFloorMem, floatingPointOperands<float>());
277 RUN_UNARY(testFloorFloorArg, floatingPointOperands<float>());
278 RUN_UNARY(testCeilFloorArg, floatingPointOperands<float>());
279 RUN_UNARY(testFloorArgWithUselessDoubleConversion, floatingPointOperands<float>());
280 RUN_UNARY(testFloorArgWithEffectfulDoubleConversion, floatingPointOperands<float>());
281
282 RUN_UNARY(testSqrtArg, floatingPointOperands<double>());
283 RUN_UNARY(testSqrtImm, floatingPointOperands<double>());
284 RUN_UNARY(testSqrtMem, floatingPointOperands<double>());
285 RUN_UNARY(testSqrtArg, floatingPointOperands<float>());
286 RUN_UNARY(testSqrtImm, floatingPointOperands<float>());
287 RUN_UNARY(testSqrtMem, floatingPointOperands<float>());
288 RUN_UNARY(testSqrtArgWithUselessDoubleConversion, floatingPointOperands<float>());
289 RUN_UNARY(testSqrtArgWithEffectfulDoubleConversion, floatingPointOperands<float>());
290
291 RUN_BINARY(testCompareTwoFloatToDouble, floatingPointOperands<float>(), floatingPointOperands<float>());
292 RUN_BINARY(testCompareOneFloatToDouble, floatingPointOperands<float>(), floatingPointOperands<double>());
293 RUN_BINARY(testCompareFloatToDoubleThroughPhi, floatingPointOperands<float>(), floatingPointOperands<float>());
294 RUN_UNARY(testDoubleToFloatThroughPhi, floatingPointOperands<float>());
295 RUN(testReduceFloatToDoubleValidates());
296 RUN_UNARY(testDoubleProducerPhiToFloatConversion, floatingPointOperands<float>());
297 RUN_UNARY(testDoubleProducerPhiToFloatConversionWithDoubleConsumer, floatingPointOperands<float>());
298 RUN_BINARY(testDoubleProducerPhiWithNonFloatConst, floatingPointOperands<float>(), floatingPointOperands<double>());
299
300 RUN_UNARY(testDoubleArgToInt64BitwiseCast, floatingPointOperands<double>());
301 RUN_UNARY(testDoubleImmToInt64BitwiseCast, floatingPointOperands<double>());
302 RUN_UNARY(testTwoBitwiseCastOnDouble, floatingPointOperands<double>());
303 RUN_UNARY(testBitwiseCastOnDoubleInMemory, floatingPointOperands<double>());
304 RUN_UNARY(testBitwiseCastOnDoubleInMemoryIndexed, floatingPointOperands<double>());
305 RUN_UNARY(testInt64BArgToDoubleBitwiseCast, int64Operands());
306 RUN_UNARY(testInt64BImmToDoubleBitwiseCast, int64Operands());
307 RUN_UNARY(testTwoBitwiseCastOnInt64, int64Operands());
308 RUN_UNARY(testBitwiseCastOnInt64InMemory, int64Operands());
309 RUN_UNARY(testBitwiseCastOnInt64InMemoryIndexed, int64Operands());
310 RUN_UNARY(testFloatImmToInt32BitwiseCast, floatingPointOperands<float>());
311 RUN_UNARY(testBitwiseCastOnFloatInMemory, floatingPointOperands<float>());
312 RUN_UNARY(testInt32BArgToFloatBitwiseCast, int32Operands());
313 RUN_UNARY(testInt32BImmToFloatBitwiseCast, int32Operands());
314 RUN_UNARY(testTwoBitwiseCastOnInt32, int32Operands());
315 RUN_UNARY(testBitwiseCastOnInt32InMemory, int32Operands());
316
317 RUN_UNARY(testConvertDoubleToFloatArg, floatingPointOperands<double>());
318 RUN_UNARY(testConvertDoubleToFloatImm, floatingPointOperands<double>());
319 RUN_UNARY(testConvertDoubleToFloatMem, floatingPointOperands<double>());
320 RUN_UNARY(testConvertFloatToDoubleArg, floatingPointOperands<float>());
321 RUN_UNARY(testConvertFloatToDoubleImm, floatingPointOperands<float>());
322 RUN_UNARY(testConvertFloatToDoubleMem, floatingPointOperands<float>());
323 RUN_UNARY(testConvertDoubleToFloatToDoubleToFloat, floatingPointOperands<double>());
324 RUN_UNARY(testStoreFloat, floatingPointOperands<double>());
325 RUN_UNARY(testStoreDoubleConstantAsFloat, floatingPointOperands<double>());
326 RUN_UNARY(testLoadFloatConvertDoubleConvertFloatStoreFloat, floatingPointOperands<float>());
327 RUN_UNARY(testFroundArg, floatingPointOperands<double>());
328 RUN_UNARY(testFroundMem, floatingPointOperands<double>());
329
330 RUN(testIToD64Arg());
331 RUN(testIToF64Arg());
332 RUN(testIToD32Arg());
333 RUN(testIToF32Arg());
334 RUN(testIToD64Mem());
335 RUN(testIToF64Mem());
336 RUN(testIToD32Mem());
337 RUN(testIToF32Mem());
338 RUN_UNARY(testIToD64Imm, int64Operands());
339 RUN_UNARY(testIToF64Imm, int64Operands());
340 RUN_UNARY(testIToD32Imm, int32Operands());
341 RUN_UNARY(testIToF32Imm, int32Operands());
342 RUN(testIToDReducedToIToF64Arg());
343 RUN(testIToDReducedToIToF32Arg());
344
345 RUN_UNARY(testCheckAddRemoveCheckWithSExt8, int8Operands());
346 RUN_UNARY(testCheckAddRemoveCheckWithSExt16, int16Operands());
347 RUN_UNARY(testCheckAddRemoveCheckWithSExt32, int32Operands());
348 RUN_UNARY(testCheckAddRemoveCheckWithZExt32, int32Operands());
349
350 RUN(testStore32(44));
351 RUN(testStoreConstant(49));
352 RUN(testStoreConstantPtr(49));
353 RUN(testStore8Arg());
354 RUN(testStore8Imm());
355 RUN(testStorePartial8BitRegisterOnX86());
356 RUN(testStore16Arg());
357 RUN(testStore16Imm());
358 RUN(testTrunc((static_cast<int64_t>(1) << 40) + 42));
359 RUN(testAdd1(45));
360 RUN(testAdd1Ptr(51));
361 RUN(testAdd1Ptr(static_cast<intptr_t>(0xbaadbeef)));
362 RUN(testNeg32(52));
363 RUN(testNegPtr(53));
364 RUN(testStoreAddLoad32(46));
365 RUN(testStoreRelAddLoadAcq32(46));
366 RUN(testStoreAddLoadImm32(46));
367 RUN(testStoreAddLoad64(4600));
368 RUN(testStoreRelAddLoadAcq64(4600));
369 RUN(testStoreAddLoadImm64(4600));
370 RUN(testStoreAddLoad8(4, Load8Z));
371 RUN(testStoreRelAddLoadAcq8(4, Load8Z));
372 RUN(testStoreRelAddFenceLoadAcq8(4, Load8Z));
373 RUN(testStoreAddLoadImm8(4, Load8Z));
374 RUN(testStoreAddLoad8(4, Load8S));
375 RUN(testStoreRelAddLoadAcq8(4, Load8S));
376 RUN(testStoreAddLoadImm8(4, Load8S));
377 RUN(testStoreAddLoad16(6, Load16Z));
378 RUN(testStoreRelAddLoadAcq16(6, Load16Z));
379 RUN(testStoreAddLoadImm16(6, Load16Z));
380 RUN(testStoreAddLoad16(6, Load16S));
381 RUN(testStoreRelAddLoadAcq16(6, Load16S));
382 RUN(testStoreAddLoadImm16(6, Load16S));
383 RUN(testStoreAddLoad32Index(46));
384 RUN(testStoreAddLoadImm32Index(46));
385 RUN(testStoreAddLoad64Index(4600));
386 RUN(testStoreAddLoadImm64Index(4600));
387 RUN(testStoreAddLoad8Index(4, Load8Z));
388 RUN(testStoreAddLoadImm8Index(4, Load8Z));
389 RUN(testStoreAddLoad8Index(4, Load8S));
390 RUN(testStoreAddLoadImm8Index(4, Load8S));
391 RUN(testStoreAddLoad16Index(6, Load16Z));
392 RUN(testStoreAddLoadImm16Index(6, Load16Z));
393 RUN(testStoreAddLoad16Index(6, Load16S));
394 RUN(testStoreAddLoadImm16Index(6, Load16S));
395 RUN(testStoreSubLoad(46));
396 RUN(testStoreAddLoadInterference(52));
397 RUN(testStoreAddAndLoad(47, 0xffff));
398 RUN(testStoreAddAndLoad(470000, 0xffff));
399 RUN(testStoreNegLoad32(54));
400 RUN(testStoreNegLoadPtr(55));
401 RUN(testAdd1Uncommuted(48));
402 RUN(testLoadOffset());
403 RUN(testLoadOffsetNotConstant());
404 RUN(testLoadOffsetUsingAdd());
405 RUN(testLoadOffsetUsingAddInterference());
406 RUN(testLoadOffsetUsingAddNotConstant());
407 RUN(testLoadAddrShift(0));
408 RUN(testLoadAddrShift(1));
409 RUN(testLoadAddrShift(2));
410 RUN(testLoadAddrShift(3));
411 RUN(testFramePointer());
412 RUN(testOverrideFramePointer());
413 RUN(testStackSlot());
414 RUN(testLoadFromFramePointer());
415 RUN(testStoreLoadStackSlot(50));
416
417 RUN(testBranch());
418 RUN(testBranchPtr());
419 RUN(testDiamond());
420 RUN(testBranchNotEqual());
421 RUN(testBranchNotEqualCommute());
422 RUN(testBranchNotEqualNotEqual());
423 RUN(testBranchEqual());
424 RUN(testBranchEqualEqual());
425 RUN(testBranchEqualCommute());
426 RUN(testBranchEqualEqual1());
427 RUN_BINARY(testBranchEqualOrUnorderedArgs, floatingPointOperands<double>(), floatingPointOperands<double>());
428 RUN_BINARY(testBranchEqualOrUnorderedArgs, floatingPointOperands<float>(), floatingPointOperands<float>());
429 RUN_BINARY(testBranchNotEqualAndOrderedArgs, floatingPointOperands<double>(), floatingPointOperands<double>());
430 RUN_BINARY(testBranchNotEqualAndOrderedArgs, floatingPointOperands<float>(), floatingPointOperands<float>());
431 RUN_BINARY(testBranchEqualOrUnorderedDoubleArgImm, floatingPointOperands<double>(), floatingPointOperands<double>());
432 RUN_BINARY(testBranchEqualOrUnorderedFloatArgImm, floatingPointOperands<float>(), floatingPointOperands<float>());
433 RUN_BINARY(testBranchEqualOrUnorderedDoubleImms, floatingPointOperands<double>(), floatingPointOperands<double>());
434 RUN_BINARY(testBranchEqualOrUnorderedFloatImms, floatingPointOperands<float>(), floatingPointOperands<float>());
435 RUN_BINARY(testBranchEqualOrUnorderedFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
436 RUN_BINARY(testBranchNotEqualAndOrderedArgs, floatingPointOperands<double>(), floatingPointOperands<double>());
437 RUN_BINARY(testBranchNotEqualAndOrderedArgs, floatingPointOperands<float>(), floatingPointOperands<float>());
438 RUN(testBranchFold(42));
439 RUN(testBranchFold(0));
440 RUN(testDiamondFold(42));
441 RUN(testDiamondFold(0));
442 RUN(testBranchNotEqualFoldPtr(42));
443 RUN(testBranchNotEqualFoldPtr(0));
444 RUN(testBranchEqualFoldPtr(42));
445 RUN(testBranchEqualFoldPtr(0));
446 RUN(testBranchLoadPtr());
447 RUN(testBranchLoad32());
448 RUN(testBranchLoad8S());
449 RUN(testBranchLoad8Z());
450 RUN(testBranchLoad16S());
451 RUN(testBranchLoad16Z());
452 RUN(testBranch8WithLoad8ZIndex());
453
454 RUN(testComplex(64, 128));
455 RUN(testComplex(4, 128));
456 RUN(testComplex(4, 256));
457 RUN(testComplex(4, 384));
458
459 RUN_BINARY(testBranchBitTest32TmpImm, int32Operands(), int32Operands());
460 RUN_BINARY(testBranchBitTest32AddrImm, int32Operands(), int32Operands());
461 RUN_BINARY(testBranchBitTest32TmpTmp, int32Operands(), int32Operands());
462 RUN_BINARY(testBranchBitTest64TmpTmp, int64Operands(), int64Operands());
463 RUN_BINARY(testBranchBitTest64AddrTmp, int64Operands(), int64Operands());
464 RUN_BINARY(testBranchBitTestNegation, int64Operands(), int64Operands());
465 RUN_BINARY(testBranchBitTestNegation2, int64Operands(), int64Operands());
466
467 RUN(testSimplePatchpoint());
468 RUN(testSimplePatchpointWithoutOuputClobbersGPArgs());
469 RUN(testSimplePatchpointWithOuputClobbersGPArgs());
470 RUN(testSimplePatchpointWithoutOuputClobbersFPArgs());
471 RUN(testSimplePatchpointWithOuputClobbersFPArgs());
472 RUN(testPatchpointWithEarlyClobber());
473 RUN(testPatchpointCallArg());
474 RUN(testPatchpointFixedRegister());
475 RUN(testPatchpointAny(ValueRep::WarmAny));
476 RUN(testPatchpointAny(ValueRep::ColdAny));
477 RUN(testPatchpointGPScratch());
478 RUN(testPatchpointFPScratch());
479 RUN(testPatchpointLotsOfLateAnys());
480 RUN(testPatchpointAnyImm(ValueRep::WarmAny));
481 RUN(testPatchpointAnyImm(ValueRep::ColdAny));
482 RUN(testPatchpointAnyImm(ValueRep::LateColdAny));
483 RUN(testPatchpointManyWarmAnyImms());
484 RUN(testPatchpointManyColdAnyImms());
485 RUN(testPatchpointWithRegisterResult());
486 RUN(testPatchpointWithStackArgumentResult());
487 RUN(testPatchpointWithAnyResult());
488 RUN(testSimpleCheck());
489 RUN(testCheckFalse());
490 RUN(testCheckTrue());
491 RUN(testCheckLessThan());
492 RUN(testCheckMegaCombo());
493 RUN(testCheckTrickyMegaCombo());
494 RUN(testCheckTwoMegaCombos());
495 RUN(testCheckTwoNonRedundantMegaCombos());
496 RUN(testCheckAddImm());
497 RUN(testCheckAddImmCommute());
498 RUN(testCheckAddImmSomeRegister());
499 RUN(testCheckAdd());
500 RUN(testCheckAdd64());
501 RUN(testCheckAddFold(100, 200));
502 RUN(testCheckAddFoldFail(2147483647, 100));
503 RUN(testCheckAddArgumentAliasing64());
504 RUN(testCheckAddArgumentAliasing32());
505 RUN(testCheckAddSelfOverflow64());
506 RUN(testCheckAddSelfOverflow32());
507 RUN(testCheckSubImm());
508 RUN(testCheckSubBadImm());
509 RUN(testCheckSub());
510 RUN(testCheckSub64());
511 RUN(testCheckSubFold(100, 200));
512 RUN(testCheckSubFoldFail(-2147483647, 100));
513 RUN(testCheckNeg());
514 RUN(testCheckNeg64());
515 RUN(testCheckMul());
516 RUN(testCheckMulMemory());
517 RUN(testCheckMul2());
518 RUN(testCheckMul64());
519 RUN(testCheckMulFold(100, 200));
520 RUN(testCheckMulFoldFail(2147483647, 100));
521 RUN(testCheckMulArgumentAliasing64());
522 RUN(testCheckMulArgumentAliasing32());
523
524 RUN_BINARY([](int32_t a, int32_t b) { testCompare(Equal, a, b); }, int64Operands(), int64Operands());
525 RUN_BINARY([](int32_t a, int32_t b) { testCompare(NotEqual, a, b); }, int64Operands(), int64Operands());
526 RUN_BINARY([](int32_t a, int32_t b) { testCompare(LessThan, a, b); }, int64Operands(), int64Operands());
527 RUN_BINARY([](int32_t a, int32_t b) { testCompare(GreaterThan, a, b); }, int64Operands(), int64Operands());
528 RUN_BINARY([](int32_t a, int32_t b) { testCompare(LessEqual, a, b); }, int64Operands(), int64Operands());
529 RUN_BINARY([](int32_t a, int32_t b) { testCompare(GreaterEqual, a, b); }, int64Operands(), int64Operands());
530 RUN_BINARY([](int32_t a, int32_t b) { testCompare(Below, a, b); }, int64Operands(), int64Operands());
531 RUN_BINARY([](int32_t a, int32_t b) { testCompare(Above, a, b); }, int64Operands(), int64Operands());
532 RUN_BINARY([](int32_t a, int32_t b) { testCompare(BelowEqual, a, b); }, int64Operands(), int64Operands());
533 RUN_BINARY([](int32_t a, int32_t b) { testCompare(AboveEqual, a, b); }, int64Operands(), int64Operands());
534 RUN_BINARY([](int32_t a, int32_t b) { testCompare(BitAnd, a, b); }, int64Operands(), int64Operands());
535
536 RUN(testEqualDouble(42, 42, true));
537 RUN(testEqualDouble(0, -0, true));
538 RUN(testEqualDouble(42, 43, false));
539 RUN(testEqualDouble(PNaN, 42, false));
540 RUN(testEqualDouble(42, PNaN, false));
541 RUN(testEqualDouble(PNaN, PNaN, false));
542
543 addLoadTests(filter, tasks);
544 addTupleTests(filter, tasks);
545
546 addCopyTests(filter, tasks);
547
548 RUN(testSpillGP());
549 RUN(testSpillFP());
550
551 RUN(testInt32ToDoublePartialRegisterStall());
552 RUN(testInt32ToDoublePartialRegisterWithoutStall());
553
554 addCallTests(filter, tasks);
555
556 RUN(testLinearScanWithCalleeOnStack());
557
558 RUN(testChillDiv(4, 2, 2));
559 RUN(testChillDiv(1, 0, 0));
560 RUN(testChillDiv(0, 0, 0));
561 RUN(testChillDiv(1, -1, -1));
562 RUN(testChillDiv(-2147483647 - 1, 0, 0));
563 RUN(testChillDiv(-2147483647 - 1, 1, -2147483647 - 1));
564 RUN(testChillDiv(-2147483647 - 1, -1, -2147483647 - 1));
565 RUN(testChillDiv(-2147483647 - 1, 2, -1073741824));
566 RUN(testChillDiv64(4, 2, 2));
567 RUN(testChillDiv64(1, 0, 0));
568 RUN(testChillDiv64(0, 0, 0));
569 RUN(testChillDiv64(1, -1, -1));
570 RUN(testChillDiv64(-9223372036854775807ll - 1, 0, 0));
571 RUN(testChillDiv64(-9223372036854775807ll - 1, 1, -9223372036854775807ll - 1));
572 RUN(testChillDiv64(-9223372036854775807ll - 1, -1, -9223372036854775807ll - 1));
573 RUN(testChillDiv64(-9223372036854775807ll - 1, 2, -4611686018427387904));
574 RUN(testChillDivTwice(4, 2, 6, 2, 5));
575 RUN(testChillDivTwice(4, 0, 6, 2, 3));
576 RUN(testChillDivTwice(4, 2, 6, 0, 2));
577
578 RUN_UNARY(testModArg, int64Operands());
579 RUN_BINARY(testModArgs, int64Operands(), int64Operands());
580 RUN_BINARY(testModImms, int64Operands(), int64Operands());
581 RUN_UNARY(testModArg32, int32Operands());
582 RUN_BINARY(testModArgs32, int32Operands(), int32Operands());
583 RUN_BINARY(testModImms32, int32Operands(), int32Operands());
584 RUN_UNARY(testChillModArg, int64Operands());
585 RUN_BINARY(testChillModArgs, int64Operands(), int64Operands());
586 RUN_BINARY(testChillModImms, int64Operands(), int64Operands());
587 RUN_UNARY(testChillModArg32, int32Operands());
588 RUN_BINARY(testChillModArgs32, int32Operands(), int32Operands());
589 RUN_BINARY(testChillModImms32, int32Operands(), int32Operands());
590
591 RUN(testSwitch(0, 1));
592 RUN(testSwitch(1, 1));
593 RUN(testSwitch(2, 1));
594 RUN(testSwitch(2, 2));
595 RUN(testSwitch(10, 1));
596 RUN(testSwitch(10, 2));
597 RUN(testSwitch(100, 1));
598 RUN(testSwitch(100, 100));
599
600 RUN(testSwitchSameCaseAsDefault());
601
602 RUN(testSwitchChillDiv(0, 1));
603 RUN(testSwitchChillDiv(1, 1));
604 RUN(testSwitchChillDiv(2, 1));
605 RUN(testSwitchChillDiv(2, 2));
606 RUN(testSwitchChillDiv(10, 1));
607 RUN(testSwitchChillDiv(10, 2));
608 RUN(testSwitchChillDiv(100, 1));
609 RUN(testSwitchChillDiv(100, 100));
610
611 RUN(testSwitchTargettingSameBlock());
612 RUN(testSwitchTargettingSameBlockFoldPathConstant());
613
614 RUN(testTrunc(0));
615 RUN(testTrunc(1));
616 RUN(testTrunc(-1));
617 RUN(testTrunc(1000000000000ll));
618 RUN(testTrunc(-1000000000000ll));
619 RUN(testTruncFold(0));
620 RUN(testTruncFold(1));
621 RUN(testTruncFold(-1));
622 RUN(testTruncFold(1000000000000ll));
623 RUN(testTruncFold(-1000000000000ll));
624
625 RUN(testZExt32(0));
626 RUN(testZExt32(1));
627 RUN(testZExt32(-1));
628 RUN(testZExt32(1000000000ll));
629 RUN(testZExt32(-1000000000ll));
630 RUN(testZExt32Fold(0));
631 RUN(testZExt32Fold(1));
632 RUN(testZExt32Fold(-1));
633 RUN(testZExt32Fold(1000000000ll));
634 RUN(testZExt32Fold(-1000000000ll));
635
636 RUN(testSExt32(0));
637 RUN(testSExt32(1));
638 RUN(testSExt32(-1));
639 RUN(testSExt32(1000000000ll));
640 RUN(testSExt32(-1000000000ll));
641 RUN(testSExt32Fold(0));
642 RUN(testSExt32Fold(1));
643 RUN(testSExt32Fold(-1));
644 RUN(testSExt32Fold(1000000000ll));
645 RUN(testSExt32Fold(-1000000000ll));
646
647 RUN(testTruncZExt32(0));
648 RUN(testTruncZExt32(1));
649 RUN(testTruncZExt32(-1));
650 RUN(testTruncZExt32(1000000000ll));
651 RUN(testTruncZExt32(-1000000000ll));
652 RUN(testTruncSExt32(0));
653 RUN(testTruncSExt32(1));
654 RUN(testTruncSExt32(-1));
655 RUN(testTruncSExt32(1000000000ll));
656 RUN(testTruncSExt32(-1000000000ll));
657
658 addSExtTests(filter, tasks);
659
660 RUN(testBasicSelect());
661 RUN(testSelectTest());
662 RUN(testSelectCompareDouble());
663 RUN_BINARY(testSelectCompareFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
664 RUN_BINARY(testSelectCompareFloatToDouble, floatingPointOperands<float>(), floatingPointOperands<float>());
665 RUN(testSelectDouble());
666 RUN(testSelectDoubleTest());
667 RUN(testSelectDoubleCompareDouble());
668 RUN_BINARY(testSelectDoubleCompareFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
669 RUN_BINARY(testSelectFloatCompareFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
670 RUN(testSelectDoubleCompareDoubleWithAliasing());
671 RUN(testSelectFloatCompareFloatWithAliasing());
672 RUN(testSelectFold(42));
673 RUN(testSelectFold(43));
674 RUN(testSelectInvert());
675 RUN(testCheckSelect());
676 RUN(testCheckSelectCheckSelect());
677 RUN(testCheckSelectAndCSE());
678 RUN_BINARY(testPowDoubleByIntegerLoop, floatingPointOperands<double>(), int64Operands());
679
680 RUN(testTruncOrHigh());
681 RUN(testTruncOrLow());
682 RUN(testBitAndOrHigh());
683 RUN(testBitAndOrLow());
684
685 RUN(testBranch64Equal(0, 0));
686 RUN(testBranch64Equal(1, 1));
687 RUN(testBranch64Equal(-1, -1));
688 RUN(testBranch64Equal(1, -1));
689 RUN(testBranch64Equal(-1, 1));
690 RUN(testBranch64EqualImm(0, 0));
691 RUN(testBranch64EqualImm(1, 1));
692 RUN(testBranch64EqualImm(-1, -1));
693 RUN(testBranch64EqualImm(1, -1));
694 RUN(testBranch64EqualImm(-1, 1));
695 RUN(testBranch64EqualMem(0, 0));
696 RUN(testBranch64EqualMem(1, 1));
697 RUN(testBranch64EqualMem(-1, -1));
698 RUN(testBranch64EqualMem(1, -1));
699 RUN(testBranch64EqualMem(-1, 1));
700 RUN(testBranch64EqualMemImm(0, 0));
701 RUN(testBranch64EqualMemImm(1, 1));
702 RUN(testBranch64EqualMemImm(-1, -1));
703 RUN(testBranch64EqualMemImm(1, -1));
704 RUN(testBranch64EqualMemImm(-1, 1));
705
706 RUN(testStore8Load8Z(0));
707 RUN(testStore8Load8Z(123));
708 RUN(testStore8Load8Z(12345));
709 RUN(testStore8Load8Z(-123));
710
711 RUN(testStore16Load16Z(0));
712 RUN(testStore16Load16Z(123));
713 RUN(testStore16Load16Z(12345));
714 RUN(testStore16Load16Z(12345678));
715 RUN(testStore16Load16Z(-123));
716
717 addSShrShTests(filter, tasks);
718
719 RUN(testCheckMul64SShr());
720
721 RUN_BINARY(testRotR, int32Operands(), int32Operands());
722 RUN_BINARY(testRotR, int64Operands(), int32Operands());
723 RUN_BINARY(testRotL, int32Operands(), int32Operands());
724 RUN_BINARY(testRotL, int64Operands(), int32Operands());
725
726 RUN_BINARY(testRotRWithImmShift, int32Operands(), int32Operands());
727 RUN_BINARY(testRotRWithImmShift, int64Operands(), int32Operands());
728 RUN_BINARY(testRotLWithImmShift, int32Operands(), int32Operands());
729 RUN_BINARY(testRotLWithImmShift, int64Operands(), int32Operands());
730
731 RUN(testComputeDivisionMagic<int32_t>(2, -2147483647, 0));
732 RUN(testTrivialInfiniteLoop());
733 RUN(testFoldPathEqual());
734
735 RUN(testRShiftSelf32());
736 RUN(testURShiftSelf32());
737 RUN(testLShiftSelf32());
738 RUN(testRShiftSelf64());
739 RUN(testURShiftSelf64());
740 RUN(testLShiftSelf64());
741
742 RUN(testPatchpointDoubleRegs());
743 RUN(testSpillDefSmallerThanUse());
744 RUN(testSpillUseLargerThanDef());
745 RUN(testLateRegister());
746 RUN(testInterpreter());
747 RUN(testReduceStrengthCheckBottomUseInAnotherBlock());
748 RUN(testResetReachabilityDanglingReference());
749
750 RUN(testEntrySwitchSimple());
751 RUN(testEntrySwitchNoEntrySwitch());
752 RUN(testEntrySwitchWithCommonPaths());
753 RUN(testEntrySwitchWithCommonPathsAndNonTrivialEntrypoint());
754 RUN(testEntrySwitchLoop());
755
756 RUN(testSomeEarlyRegister());
757 RUN(testPatchpointTerminalReturnValue(true));
758 RUN(testPatchpointTerminalReturnValue(false));
759 RUN(testTerminalPatchpointThatNeedsToBeSpilled());
760
761 RUN(testMemoryFence());
762 RUN(testStoreFence());
763 RUN(testLoadFence());
764 RUN(testTrappingLoad());
765 RUN(testTrappingStore());
766 RUN(testTrappingLoadAddStore());
767 RUN(testTrappingLoadDCE());
768 RUN(testTrappingStoreElimination());
769 RUN(testMoveConstants());
770 RUN(testPCOriginMapDoesntInsertNops());
771 RUN(testPinRegisters());
772 RUN(testReduceStrengthReassociation(true));
773 RUN(testReduceStrengthReassociation(false));
774 RUN(testAddShl32());
775 RUN(testAddShl64());
776 RUN(testAddShl65());
777 RUN(testLoadBaseIndexShift2());
778 RUN(testLoadBaseIndexShift32());
779 RUN(testOptimizeMaterialization());
780 RUN(testLICMPure());
781 RUN(testLICMPureSideExits());
782 RUN(testLICMPureWritesPinned());
783 RUN(testLICMPureWrites());
784 RUN(testLICMReadsLocalState());
785 RUN(testLICMReadsPinned());
786 RUN(testLICMReads());
787 RUN(testLICMPureNotBackwardsDominant());
788 RUN(testLICMPureFoiledByChild());
789 RUN(testLICMPureNotBackwardsDominantFoiledByChild());
790 RUN(testLICMExitsSideways());
791 RUN(testLICMWritesLocalState());
792 RUN(testLICMWrites());
793 RUN(testLICMWritesPinned());
794 RUN(testLICMFence());
795 RUN(testLICMControlDependent());
796 RUN(testLICMControlDependentNotBackwardsDominant());
797 RUN(testLICMControlDependentSideExits());
798 RUN(testLICMReadsPinnedWritesPinned());
799 RUN(testLICMReadsWritesDifferentHeaps());
800 RUN(testLICMReadsWritesOverlappingHeaps());
801 RUN(testLICMDefaultCall());
802
803 addAtomicTests(filter, tasks);
804 RUN(testDepend32());
805 RUN(testDepend64());
806
807 RUN(testWasmBoundsCheck(0));
808 RUN(testWasmBoundsCheck(100));
809 RUN(testWasmBoundsCheck(10000));
810 RUN(testWasmBoundsCheck(std::numeric_limits<unsigned>::max() - 5));
811
812 RUN(testWasmAddress());
813
814 RUN(testFastTLSLoad());
815 RUN(testFastTLSStore());
816
817 RUN(testDoubleLiteralComparison(bitwise_cast<double>(0x8000000000000001ull), bitwise_cast<double>(0x0000000000000000ull)));
818 RUN(testDoubleLiteralComparison(bitwise_cast<double>(0x0000000000000000ull), bitwise_cast<double>(0x8000000000000001ull)));
819 RUN(testDoubleLiteralComparison(125.3144446948241, 125.3144446948242));
820 RUN(testDoubleLiteralComparison(125.3144446948242, 125.3144446948241));
821
822 RUN(testFloatEqualOrUnorderedFolding());
823 RUN(testFloatEqualOrUnorderedFoldingNaN());
824 RUN(testFloatEqualOrUnorderedDontFold());
825
826 RUN(testShuffleDoesntTrashCalleeSaves());
827 RUN(testDemotePatchpointTerminal());
828
829 RUN(testLoopWithMultipleHeaderEdges());
830
831 RUN(testInfiniteLoopDoesntCauseBadHoisting());
832
833 if (isX86()) {
834 RUN(testBranchBitAndImmFusion(Identity, Int64, 1, Air::BranchTest32, Air::Arg::Tmp));
835 RUN(testBranchBitAndImmFusion(Identity, Int64, 0xff, Air::BranchTest32, Air::Arg::Tmp));
836 RUN(testBranchBitAndImmFusion(Trunc, Int32, 1, Air::BranchTest32, Air::Arg::Tmp));
837 RUN(testBranchBitAndImmFusion(Trunc, Int32, 0xff, Air::BranchTest32, Air::Arg::Tmp));
838 RUN(testBranchBitAndImmFusion(Load8S, Int32, 1, Air::BranchTest8, Air::Arg::Addr));
839 RUN(testBranchBitAndImmFusion(Load8Z, Int32, 1, Air::BranchTest8, Air::Arg::Addr));
840 RUN(testBranchBitAndImmFusion(Load, Int32, 1, Air::BranchTest32, Air::Arg::Addr));
841 RUN(testBranchBitAndImmFusion(Load, Int64, 1, Air::BranchTest32, Air::Arg::Addr));
842 RUN(testX86LeaAddAddShlLeft());
843 RUN(testX86LeaAddAddShlRight());
844 RUN(testX86LeaAddAdd());
845 RUN(testX86LeaAddShlRight());
846 RUN(testX86LeaAddShlLeftScale1());
847 RUN(testX86LeaAddShlLeftScale2());
848 RUN(testX86LeaAddShlLeftScale4());
849 RUN(testX86LeaAddShlLeftScale8());
850 }
851
852 if (isARM64()) {
853 RUN(testTernarySubInstructionSelection(Identity, Int64, Air::Sub64));
854 RUN(testTernarySubInstructionSelection(Trunc, Int32, Air::Sub32));
855 }
856
857 RUN(testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead());
858
859 if (tasks.isEmpty())
860 usage();
861
862 Lock lock;
863
864 Vector<Ref<Thread>> threads;
865 for (unsigned i = filter ? 1 : WTF::numberOfProcessorCores(); i--;) {
866 threads.append(
867 Thread::create(
868 "testb3 thread",
869 [&] () {
870 for (;;) {
871 RefPtr<SharedTask<void()>> task;
872 {
873 LockHolder locker(lock);
874 if (tasks.isEmpty())
875 return;
876 task = tasks.takeFirst();
877 }
878
879 task->run();
880 }
881 }));
882 }
883
884 for (auto& thread : threads)
885 thread->waitForCompletion();
886 crashLock.lock();
887 crashLock.unlock();
888}
889
890#else // ENABLE(B3_JIT)
891
892static void run(const char*)
893{
894 dataLog("B3 JIT is not enabled.\n");
895}
896
897#endif // ENABLE(B3_JIT)
898
899int main(int argc, char** argv)
900{
901 const char* filter = nullptr;
902 switch (argc) {
903 case 1:
904 break;
905 case 2:
906 filter = argv[1];
907 break;
908 default:
909 usage();
910 break;
911 }
912
913 WTF::initializeMainThread();
914 JSC::initializeThreading();
915
916 for (unsigned i = 0; i <= 2; ++i) {
917 JSC::Options::defaultB3OptLevel() = i;
918 run(filter);
919 }
920
921 return 0;
922}
923
924#if OS(WINDOWS)
925extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[])
926{
927 return main(argc, const_cast<char**>(argv));
928}
929#endif
930