[WTF] Add makeUnique<T>, which ensures T is fast-allocated, makeUnique / makeUniqueWi...
[WebKit-https.git] / Source / JavaScriptCore / b3 / testb3.h
1 /*
2  * Copyright (C) 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 "AirCode.h"
27 #include "AirInstInlines.h"
28 #include "AirValidate.h"
29 #include "AllowMacroScratchRegisterUsage.h"
30 #include "B3ArgumentRegValue.h"
31 #include "B3AtomicValue.h"
32 #include "B3BasicBlockInlines.h"
33 #include "B3BreakCriticalEdges.h"
34 #include "B3CCallValue.h"
35 #include "B3Compilation.h"
36 #include "B3Compile.h"
37 #include "B3ComputeDivisionMagic.h"
38 #include "B3Const32Value.h"
39 #include "B3Const64Value.h"
40 #include "B3ConstPtrValue.h"
41 #include "B3Effects.h"
42 #include "B3FenceValue.h"
43 #include "B3FixSSA.h"
44 #include "B3Generate.h"
45 #include "B3LowerToAir.h"
46 #include "B3MathExtras.h"
47 #include "B3MemoryValue.h"
48 #include "B3MoveConstants.h"
49 #include "B3NativeTraits.h"
50 #include "B3Procedure.h"
51 #include "B3ReduceStrength.h"
52 #include "B3SlotBaseValue.h"
53 #include "B3StackSlot.h"
54 #include "B3StackmapGenerationParams.h"
55 #include "B3SwitchValue.h"
56 #include "B3UpsilonValue.h"
57 #include "B3UseCounts.h"
58 #include "B3Validate.h"
59 #include "B3ValueInlines.h"
60 #include "B3VariableValue.h"
61 #include "B3WasmAddressValue.h"
62 #include "B3WasmBoundsCheckValue.h"
63 #include "CCallHelpers.h"
64 #include "FPRInfo.h"
65 #include "GPRInfo.h"
66 #include "InitializeThreading.h"
67 #include "JSCInlines.h"
68 #include "LinkBuffer.h"
69 #include "PureNaN.h"
70 #include <cmath>
71 #include <string>
72 #include <wtf/FastTLS.h>
73 #include <wtf/IndexSet.h>
74 #include <wtf/ListDump.h>
75 #include <wtf/Lock.h>
76 #include <wtf/NumberOfCores.h>
77 #include <wtf/StdList.h>
78 #include <wtf/Threading.h>
79 #include <wtf/text/StringCommon.h>
80
81 // We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
82 inline bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
83
84 inline void usage()
85 {
86     dataLog("Usage: testb3 [<filter>]\n");
87     if (hiddenTruthBecauseNoReturnIsStupid())
88         exit(1);
89 }
90
91 #if ENABLE(B3_JIT)
92
93 using namespace JSC;
94 using namespace JSC::B3;
95
96 inline bool shouldBeVerbose()
97 {
98     return shouldDumpIR(B3Mode);
99 }
100
101 extern Lock crashLock;
102
103 // Nothing fancy for now; we just use the existing WTF assertion machinery.
104 #define CHECK(x) do {                                                   \
105     if (!!(x))                                                      \
106         break;                                                      \
107     crashLock.lock();                                               \
108     WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #x); \
109     CRASH();                                                        \
110 } while (false)
111     
112 #define CHECK_EQ(x, y) do { \
113     auto __x = (x); \
114     auto __y = (y); \
115     if (__x == __y) \
116         break; \
117     crashLock.lock(); \
118     WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, toCString(#x " == " #y, " (" #x " == ", __x, ", " #y " == ", __y, ")").data()); \
119     CRASH(); \
120 } while (false)
121
122 #define PREFIX "O", Options::defaultB3OptLevel(), ": "
123
124 #define RUN(test) do {                             \
125     if (!shouldRun(filter, #test))                 \
126         break;                                     \
127     tasks.append(                                  \
128         createSharedTask<void()>(                  \
129             [&] () {                               \
130                 dataLog(PREFIX #test "...\n");     \
131                 test;                              \
132                 dataLog(PREFIX #test ": OK!\n");   \
133             }));                                   \
134     } while (false);
135
136 #define RUN_UNARY(test, values) \
137     for (auto a : values) {                             \
138         CString testStr = toCString(PREFIX #test, "(", a.name, ")"); \
139         if (!shouldRun(filter, testStr.data()))         \
140             continue;                                   \
141         tasks.append(createSharedTask<void()>(          \
142             [=] () {                                    \
143                 dataLog(toCString(testStr, "...\n"));   \
144                 test(a.value);                          \
145                 dataLog(toCString(testStr, ": OK!\n")); \
146             }));                                        \
147     }
148
149 #define RUN_NOW(test) do {                      \
150         if (!shouldRun(filter, #test))          \
151             break;                              \
152         dataLog(PREFIX #test "...\n");          \
153         test;                                   \
154         dataLog(PREFIX #test ": OK!\n");        \
155     } while (false)
156
157 #define RUN_BINARY(test, valuesA, valuesB) \
158     for (auto a : valuesA) {                                \
159         for (auto b : valuesB) {                            \
160             CString testStr = toCString(PREFIX #test, "(", a.name, ", ", b.name, ")"); \
161             if (!shouldRun(filter, testStr.data()))         \
162                 continue;                                   \
163             tasks.append(createSharedTask<void()>(          \
164                 [=] () {                                    \
165                     dataLog(toCString(testStr, "...\n"));   \
166                     test(a.value, b.value);                 \
167                     dataLog(toCString(testStr, ": OK!\n")); \
168                 }));                                        \
169         }                                                   \
170     }
171 #define RUN_TERNARY(test, valuesA, valuesB, valuesC) \
172     for (auto a : valuesA) {                                    \
173         for (auto b : valuesB) {                                \
174             for (auto c : valuesC) {                            \
175                 CString testStr = toCString(#test, "(", a.name, ", ", b.name, ",", c.name, ")"); \
176                 if (!shouldRun(filter, testStr.data()))         \
177                     continue;                                   \
178                 tasks.append(createSharedTask<void()>(          \
179                     [=] () {                                    \
180                         dataLog(toCString(testStr, "...\n"));   \
181                         test(a.value, b.value, c.value);        \
182                         dataLog(toCString(testStr, ": OK!\n")); \
183                     }));                                        \
184             }                                                   \
185         }                                                       \
186     }
187
188
189 inline std::unique_ptr<Compilation> compileProc(Procedure& procedure, unsigned optLevel = Options::defaultB3OptLevel())
190 {
191     procedure.setOptLevel(optLevel);
192     return makeUnique<Compilation>(B3::compile(procedure));
193 }
194
195 template<typename T, typename... Arguments>
196 T invoke(MacroAssemblerCodePtr<B3CompilationPtrTag> ptr, Arguments... arguments)
197 {
198     void* executableAddress = untagCFunctionPtr<B3CompilationPtrTag>(ptr.executableAddress());
199     T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(executableAddress);
200     return function(arguments...);
201 }
202
203 template<typename T, typename... Arguments>
204 T invoke(const Compilation& code, Arguments... arguments)
205 {
206     return invoke<T>(code.code(), arguments...);
207 }
208
209 template<typename T, typename... Arguments>
210 T compileAndRun(Procedure& procedure, Arguments... arguments)
211 {
212     return invoke<T>(*compileProc(procedure), arguments...);
213 }
214
215 inline void lowerToAirForTesting(Procedure& proc)
216 {
217     proc.resetReachability();
218     
219     if (shouldBeVerbose())
220         dataLog("B3 before lowering:\n", proc);
221     
222     validate(proc);
223     lowerToAir(proc);
224     
225     if (shouldBeVerbose())
226         dataLog("Air after lowering:\n", proc.code());
227     
228     Air::validate(proc.code());
229 }
230
231 template<typename Func>
232 void checkDisassembly(Compilation& compilation, const Func& func, const CString& failText)
233 {
234     CString disassembly = compilation.disassembly();
235     if (func(disassembly.data()))
236         return;
237     
238     crashLock.lock();
239     dataLog("Bad lowering!  ", failText, "\n");
240     dataLog(disassembly);
241     CRASH();
242 }
243
244 inline void checkUsesInstruction(Compilation& compilation, const char* text)
245 {
246     checkDisassembly(
247         compilation,
248         [&] (const char* disassembly) -> bool {
249             return strstr(disassembly, text);
250         },
251         toCString("Expected to find ", text, " but didnt!"));
252 }
253
254 inline void checkDoesNotUseInstruction(Compilation& compilation, const char* text)
255 {
256     checkDisassembly(
257         compilation,
258         [&] (const char* disassembly) -> bool {
259             return !strstr(disassembly, text);
260         },
261         toCString("Did not expected to find ", text, " but it's there!"));
262 }
263
264 template<typename Type>
265 struct Operand {
266     const char* name;
267     Type value;
268 };
269
270 typedef Operand<int64_t> Int64Operand;
271 typedef Operand<int32_t> Int32Operand;
272
273 #define MAKE_OPERAND(value) Operand<decltype(value)> { #value, value }
274
275 template<typename FloatType>
276 void populateWithInterestingValues(Vector<Operand<FloatType>>& operands)
277 {
278     operands.append({ "0.", static_cast<FloatType>(0.) });
279     operands.append({ "-0.", static_cast<FloatType>(-0.) });
280     operands.append({ "0.4", static_cast<FloatType>(0.5) });
281     operands.append({ "-0.4", static_cast<FloatType>(-0.5) });
282     operands.append({ "0.5", static_cast<FloatType>(0.5) });
283     operands.append({ "-0.5", static_cast<FloatType>(-0.5) });
284     operands.append({ "0.6", static_cast<FloatType>(0.6) });
285     operands.append({ "-0.6", static_cast<FloatType>(-0.6) });
286     operands.append({ "1.", static_cast<FloatType>(1.) });
287     operands.append({ "-1.", static_cast<FloatType>(-1.) });
288     operands.append({ "2.", static_cast<FloatType>(2.) });
289     operands.append({ "-2.", static_cast<FloatType>(-2.) });
290     operands.append({ "M_PI", static_cast<FloatType>(M_PI) });
291     operands.append({ "-M_PI", static_cast<FloatType>(-M_PI) });
292     operands.append({ "min", std::numeric_limits<FloatType>::min() });
293     operands.append({ "max", std::numeric_limits<FloatType>::max() });
294     operands.append({ "lowest", std::numeric_limits<FloatType>::lowest() });
295     operands.append({ "epsilon", std::numeric_limits<FloatType>::epsilon() });
296     operands.append({ "infiniti", std::numeric_limits<FloatType>::infinity() });
297     operands.append({ "-infiniti", - std::numeric_limits<FloatType>::infinity() });
298     operands.append({ "PNaN", static_cast<FloatType>(PNaN) });
299 }
300
301 template<typename FloatType>
302 Vector<Operand<FloatType>> floatingPointOperands()
303 {
304     Vector<Operand<FloatType>> operands;
305     populateWithInterestingValues(operands);
306     return operands;
307 };
308
309 inline Vector<Int64Operand> int64Operands()
310 {
311     Vector<Int64Operand> operands;
312     operands.append({ "0", 0 });
313     operands.append({ "1", 1 });
314     operands.append({ "-1", -1 });
315     operands.append({ "42", 42 });
316     operands.append({ "-42", -42 });
317     operands.append({ "int64-max", std::numeric_limits<int64_t>::max() });
318     operands.append({ "int64-min", std::numeric_limits<int64_t>::min() });
319     operands.append({ "int32-max", std::numeric_limits<int32_t>::max() });
320     operands.append({ "int32-min", std::numeric_limits<int32_t>::min() });
321     operands.append({ "uint64-max", static_cast<int64_t>(std::numeric_limits<uint64_t>::max()) });
322     operands.append({ "uint64-min", static_cast<int64_t>(std::numeric_limits<uint64_t>::min()) });
323     operands.append({ "uint32-max", static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) });
324     operands.append({ "uint32-min", static_cast<int64_t>(std::numeric_limits<uint32_t>::min()) });
325     
326     return operands;
327 }
328
329 inline Vector<Int32Operand> int32Operands()
330 {
331     Vector<Int32Operand> operands({
332         { "0", 0 },
333         { "1", 1 },
334         { "-1", -1 },
335         { "42", 42 },
336         { "-42", -42 },
337         { "int32-max", std::numeric_limits<int32_t>::max() },
338         { "int32-min", std::numeric_limits<int32_t>::min() },
339         { "uint32-max", static_cast<int32_t>(std::numeric_limits<uint32_t>::max()) },
340         { "uint32-min", static_cast<int32_t>(std::numeric_limits<uint32_t>::min()) }
341     });
342     return operands;
343 }
344
345 inline void add32(CCallHelpers& jit, GPRReg src1, GPRReg src2, GPRReg dest)
346 {
347     if (src2 == dest)
348         jit.add32(src1, dest);
349     else {
350         jit.move(src1, dest);
351         jit.add32(src2, dest);
352     }
353 }
354
355 template<typename LoadedType, typename EffectiveType>
356 EffectiveType modelLoad(EffectiveType value);
357
358 template<typename LoadedType, typename EffectiveType>
359 EffectiveType modelLoad(EffectiveType value)
360 {
361     union {
362         EffectiveType original;
363         LoadedType loaded;
364     } u;
365     
366     u.original = value;
367     if (std::is_signed<LoadedType>::value)
368         return static_cast<EffectiveType>(u.loaded);
369     return static_cast<EffectiveType>(static_cast<typename std::make_unsigned<EffectiveType>::type>(u.loaded));
370 }
371
372 template<>
373 inline float modelLoad<float, float>(float value) { return value; }
374
375 template<>
376 inline double modelLoad<double, double>(double value) { return value; }
377
378 void run(const char* filter);
379 void testBitAndSExt32(int32_t value, int64_t mask);
380 void testBasicSelect();
381 void testSelectTest();
382 void testSelectCompareDouble();
383 void testSelectCompareFloat(float, float);
384 void testSelectCompareFloatToDouble(float, float);
385 void testSelectDouble();
386 void testSelectDoubleTest();
387 void testSelectDoubleCompareDouble();
388 void testSelectDoubleCompareFloat(float, float);
389 void testSelectFloatCompareFloat(float, float);
390 void testSelectDoubleCompareDoubleWithAliasing();
391 void testSelectFloatCompareFloatWithAliasing();
392 void testSelectFold(intptr_t value);
393 void testSelectInvert();
394 void testCheckSelect();
395 void testCheckSelectCheckSelect();
396 void testCheckSelectAndCSE();
397 void testPowDoubleByIntegerLoop(double xOperand, int32_t yOperand);
398 double b3Pow(double x, int y);
399 void testTruncOrHigh();
400 void testTruncOrLow();
401 void testBitAndOrHigh();
402 void testBitAndOrLow();
403 void testBranch64Equal(int64_t left, int64_t right);
404 void testBranch64EqualImm(int64_t left, int64_t right);
405 void testBranch64EqualMem(int64_t left, int64_t right);
406 void testBranch64EqualMemImm(int64_t left, int64_t right);
407 void testStore8Load8Z(int32_t value);
408 void testStore16Load16Z(int32_t value);
409 void testTrivialInfiniteLoop();
410 void testFoldPathEqual();
411 void testLShiftSelf32();
412 void testRShiftSelf32();
413 void testURShiftSelf32();
414 void testLShiftSelf64();
415 void testRShiftSelf64();
416 void testURShiftSelf64();
417 void testPatchpointDoubleRegs();
418 void testSpillDefSmallerThanUse();
419 void testSpillUseLargerThanDef();
420 void testLateRegister();
421 void interpreterPrint(Vector<intptr_t>* stream, intptr_t value);
422 void testInterpreter();
423 void testReduceStrengthCheckBottomUseInAnotherBlock();
424 void testResetReachabilityDanglingReference();
425 void testEntrySwitchSimple();
426 void testEntrySwitchNoEntrySwitch();
427 void testEntrySwitchWithCommonPaths();
428 void testEntrySwitchWithCommonPathsAndNonTrivialEntrypoint();
429 void testEntrySwitchLoop();
430 void testSomeEarlyRegister();
431 void testBranchBitAndImmFusion(B3::Opcode valueModifier, Type valueType, int64_t constant, Air::Opcode expectedOpcode, Air::Arg::Kind firstKind);
432 void testTerminalPatchpointThatNeedsToBeSpilled();
433 void testTerminalPatchpointThatNeedsToBeSpilled2();
434 void testPatchpointTerminalReturnValue(bool successIsRare);
435 void testMemoryFence();
436 void testStoreFence();
437 void testLoadFence();
438 void testTrappingLoad();
439 void testTrappingStore();
440 void testTrappingLoadAddStore();
441 void testTrappingLoadDCE();
442 void testTrappingStoreElimination();
443 void testMoveConstants();
444 void testPCOriginMapDoesntInsertNops();
445 void testBitOrBitOrArgImmImm32(int, int, int c);
446 void testBitOrImmBitOrArgImm32(int, int, int c);
447 double bitOrDouble(double, double);
448 void testBitOrArgDouble(double);
449 void testBitOrArgsDouble(double, double);
450 void testBitOrArgImmDouble(double, double);
451 void testBitOrImmsDouble(double, double);
452 float bitOrFloat(float, float);
453 void testBitOrArgFloat(float);
454 void testBitOrArgsFloat(float, float);
455 void testBitOrArgImmFloat(float, float);
456 void testBitOrImmsFloat(float, float);
457 void testBitOrArgsFloatWithUselessDoubleConversion(float, float);
458 void testBitXorArgs(int64_t, int64_t);
459 void testBitXorSameArg(int64_t);
460 void testBitXorAndAndArgs(int64_t, int64_t, int64_t c);
461 void testBitXorAndSameArgs(int64_t, int64_t);
462 void testBitXorImms(int64_t, int64_t);
463 void testBitXorArgImm(int64_t, int64_t);
464 void testBitXorImmArg(int64_t, int64_t);
465 void testBitXorBitXorArgImmImm(int64_t, int64_t, int64_t c);
466 void testBitXorImmBitXorArgImm(int64_t, int64_t, int64_t c);
467 void testBitXorArgs32(int, int);
468 void testBitXorSameArg32(int);
469 void testBitXorImms32(int, int);
470 void testBitXorArgImm32(int, int);
471 void testBitXorImmArg32(int, int);
472 void testBitXorBitXorArgImmImm32(int, int, int c);
473 void testBitXorImmBitXorArgImm32(int, int, int c);
474 void testBitNotArg(int64_t);
475 void testBitNotImm(int64_t);
476 void testBitNotMem(int64_t);
477 void testBitNotArg32(int32_t);
478 void testBitNotImm32(int32_t);
479 void testBitNotMem32(int32_t);
480 void testNotOnBooleanAndBranch32(int64_t, int64_t);
481 void testBitNotOnBooleanAndBranch32(int64_t, int64_t);
482 void testShlArgs(int64_t, int64_t);
483 void testShlImms(int64_t, int64_t);
484 void testShlArgImm(int64_t, int64_t);
485 void testShlSShrArgImm(int64_t, int64_t);
486 void testShlArg32(int32_t);
487 void testShlArgs32(int32_t, int32_t);
488 void testShlImms32(int32_t, int32_t);
489 void testShlArgImm32(int32_t, int32_t);
490 void testShlZShrArgImm32(int32_t, int32_t);
491 void testClzArg64(int64_t);
492 void testClzMem64(int64_t);
493 void testClzArg32(int32_t);
494 void testClzMem32(int32_t);
495 void testAbsArg(double);
496 void testAbsImm(double);
497 void testAbsMem(double);
498 void testAbsAbsArg(double);
499 void testAbsNegArg(double);
500 void testAbsBitwiseCastArg(double);
501 void testBitwiseCastAbsBitwiseCastArg(double);
502 void testAbsArg(float);
503 void testAbsImm(float);
504 void testAbsMem(float);
505 void testAbsAbsArg(float);
506 void testAbsNegArg(float);
507 void testAbsBitwiseCastArg(float);
508 void testBitwiseCastAbsBitwiseCastArg(float);
509 void testAbsArgWithUselessDoubleConversion(float);
510 void testAbsArgWithEffectfulDoubleConversion(float);
511 void testCeilArg(double);
512 void testCeilImm(double);
513 void testCeilMem(double);
514 void testCeilCeilArg(double);
515 void testFloorCeilArg(double);
516 void testCeilIToD64(int64_t);
517 void testCeilIToD32(int64_t);
518 void testCeilArg(float);
519 void testCeilImm(float);
520 void testCeilMem(float);
521 void testCeilCeilArg(float);
522 void testFloorCeilArg(float);
523 void testCeilArgWithUselessDoubleConversion(float);
524 void testCeilArgWithEffectfulDoubleConversion(float);
525 void testFloorArg(double);
526 void testFloorImm(double);
527 void testFloorMem(double);
528 void testFloorFloorArg(double);
529 void testCeilFloorArg(double);
530 void testFloorIToD64(int64_t);
531 void testFloorIToD32(int64_t);
532 void testFloorArg(float);
533 void testFloorImm(float);
534 void testFloorMem(float);
535 void testFloorFloorArg(float);
536 void testCeilFloorArg(float);
537 void testFloorArgWithUselessDoubleConversion(float);
538 void testFloorArgWithEffectfulDoubleConversion(float);
539 double correctSqrt(double value);
540 void testSqrtArg(double);
541 void testSqrtImm(double);
542 void testSqrtMem(double);
543 void testSqrtArg(float);
544 void testSqrtImm(float);
545 void testSqrtMem(float);
546 void testSqrtArgWithUselessDoubleConversion(float);
547 void testSqrtArgWithEffectfulDoubleConversion(float);
548 void testCompareTwoFloatToDouble(float, float);
549 void testCompareOneFloatToDouble(float, double);
550 void testCompareFloatToDoubleThroughPhi(float, float);
551 void testDoubleToFloatThroughPhi(float value);
552 void testReduceFloatToDoubleValidates();
553 void testDoubleProducerPhiToFloatConversion(float value);
554 void testDoubleProducerPhiToFloatConversionWithDoubleConsumer(float value);
555 void testDoubleProducerPhiWithNonFloatConst(float value, double constValue);
556 void testDoubleArgToInt64BitwiseCast(double value);
557 void testDoubleImmToInt64BitwiseCast(double value);
558 void testTwoBitwiseCastOnDouble(double value);
559 void testBitwiseCastOnDoubleInMemory(double value);
560 void testBitwiseCastOnDoubleInMemoryIndexed(double value);
561 void testInt64BArgToDoubleBitwiseCast(int64_t value);
562 void testInt64BImmToDoubleBitwiseCast(int64_t value);
563 void testTwoBitwiseCastOnInt64(int64_t value);
564 void testBitwiseCastOnInt64InMemory(int64_t value);
565 void testBitwiseCastOnInt64InMemoryIndexed(int64_t value);
566 void testFloatImmToInt32BitwiseCast(float value);
567 void testBitwiseCastOnFloatInMemory(float value);
568 void testInt32BArgToFloatBitwiseCast(int32_t value);
569 void testInt32BImmToFloatBitwiseCast(int32_t value);
570 void testTwoBitwiseCastOnInt32(int32_t value);
571 void testBitwiseCastOnInt32InMemory(int32_t value);
572 void testConvertDoubleToFloatArg(double value);
573 void testConvertDoubleToFloatImm(double value);
574 void testConvertDoubleToFloatMem(double value);
575 void testConvertFloatToDoubleArg(float value);
576 void testConvertFloatToDoubleImm(float value);
577 void testConvertFloatToDoubleMem(float value);
578 void testConvertDoubleToFloatToDoubleToFloat(double value);
579 void testLoadFloatConvertDoubleConvertFloatStoreFloat(float value);
580 void testFroundArg(double value);
581 void testFroundMem(double value);
582 void testIToD64Arg();
583 void testIToF64Arg();
584 void testIToD32Arg();
585 void testIToF32Arg();
586 void testIToD64Mem();
587 void testIToF64Mem();
588 void testIToD32Mem();
589 void testIToF32Mem();
590 void testIToD64Imm(int64_t value);
591 void testIToF64Imm(int64_t value);
592 void testIToD32Imm(int32_t value);
593 void testIToF32Imm(int32_t value);
594 void testIToDReducedToIToF64Arg();
595 void testIToDReducedToIToF32Arg();
596 void testStore32(int value);
597 void testStoreConstant(int value);
598 void testStoreConstantPtr(intptr_t value);
599 void testStore8Arg();
600 void testStore8Imm();
601 void testStorePartial8BitRegisterOnX86();
602 void testStore16Arg();
603 void testStore16Imm();
604 void testTrunc(int64_t value);
605 void testAdd1(int value);
606 void testAdd1Ptr(intptr_t value);
607 void testNeg32(int32_t value);
608 void testNegPtr(intptr_t value);
609 void testStoreAddLoad32(int amount);
610 void testStoreRelAddLoadAcq32(int amount);
611 void testStoreAddLoadImm32(int amount);
612 void testStoreAddLoad8(int amount, B3::Opcode loadOpcode);
613 void testStoreRelAddLoadAcq8(int amount, B3::Opcode loadOpcode);
614 void testStoreRelAddFenceLoadAcq8(int amount, B3::Opcode loadOpcode);
615 void testStoreAddLoadImm8(int amount, B3::Opcode loadOpcode);
616 void testStoreAddLoad16(int amount, B3::Opcode loadOpcode);
617 void testStoreRelAddLoadAcq16(int amount, B3::Opcode loadOpcode);
618 void testStoreAddLoadImm16(int amount, B3::Opcode loadOpcode);
619 void testStoreAddLoad64(int amount);
620 void testStoreRelAddLoadAcq64(int amount);
621 void testStoreAddLoadImm64(int64_t amount);
622 void testStoreAddLoad32Index(int amount);
623 void testStoreAddLoadImm32Index(int amount);
624 void testStoreAddLoad8Index(int amount, B3::Opcode loadOpcode);
625 void testStoreAddLoadImm8Index(int amount, B3::Opcode loadOpcode);
626 void testStoreAddLoad16Index(int amount, B3::Opcode loadOpcode);
627 void testStoreAddLoadImm16Index(int amount, B3::Opcode loadOpcode);
628 void testStoreAddLoad64Index(int amount);
629 void testStoreAddLoadImm64Index(int64_t amount);
630 void testStoreSubLoad(int amount);
631 void testStoreAddLoadInterference(int amount);
632 void testStoreAddAndLoad(int amount, int mask);
633 void testStoreNegLoad32(int32_t value);
634 void testStoreNegLoadPtr(intptr_t value);
635 void testAdd1Uncommuted(int value);
636 void testLoadOffset();
637 void testLoadOffsetNotConstant();
638 void testLoadOffsetUsingAdd();
639 void testLoadOffsetUsingAddInterference();
640 void testLoadOffsetUsingAddNotConstant();
641 void testLoadAddrShift(unsigned shift);
642 void testFramePointer();
643 void testOverrideFramePointer();
644 void testStackSlot();
645 void testLoadFromFramePointer();
646 void testStoreLoadStackSlot(int value);
647 void testStoreFloat(double input);
648 void testStoreDoubleConstantAsFloat(double input);
649 void testSpillGP();
650 void testSpillFP();
651 void testInt32ToDoublePartialRegisterStall();
652 void testInt32ToDoublePartialRegisterWithoutStall();
653 void testBranch();
654 void testBranchPtr();
655 void testDiamond();
656 void testBranchNotEqual();
657 void testBranchNotEqualCommute();
658 void testBranchNotEqualNotEqual();
659 void testBranchEqual();
660 void testBranchEqualEqual();
661 void testBranchEqualCommute();
662 void testBranchEqualEqual1();
663 void testBranchEqualOrUnorderedArgs(double, double);
664 void testBranchEqualOrUnorderedArgs(float, float);
665 void testBranchNotEqualAndOrderedArgs(double, double);
666 void testBranchNotEqualAndOrderedArgs(float, float);
667 void testBranchEqualOrUnorderedDoubleArgImm(double, double);
668 void testBranchEqualOrUnorderedFloatArgImm(float, float);
669 void testBranchEqualOrUnorderedDoubleImms(double, double);
670 void testBranchEqualOrUnorderedFloatImms(float, float);
671 void testBranchEqualOrUnorderedFloatWithUselessDoubleConversion(float, float);
672 void testBranchFold(int value);
673 void testDiamondFold(int value);
674 void testBranchNotEqualFoldPtr(intptr_t value);
675 void testBranchEqualFoldPtr(intptr_t value);
676 void testBranchLoadPtr();
677 void testBranchLoad32();
678 void testBranchLoad8S();
679 void testBranchLoad8Z();
680 void testBranchLoad16S();
681 void testBranchLoad16Z();
682 void testBranch8WithLoad8ZIndex();
683 void testComplex(unsigned numVars, unsigned numConstructs);
684 void testBranchBitTest32TmpImm(uint32_t value, uint32_t imm);
685 void testBranchBitTest32AddrImm(uint32_t value, uint32_t imm);
686 void testBranchBitTest32TmpTmp(uint32_t value, uint32_t value2);
687 void testBranchBitTest64TmpTmp(uint64_t value, uint64_t value2);
688 void testBranchBitTest64AddrTmp(uint64_t value, uint64_t value2);
689 void testBranchBitTestNegation(uint64_t value, uint64_t value2);
690 void testBranchBitTestNegation2(uint64_t value, uint64_t value2);
691 void testSimplePatchpoint();
692 void testSimplePatchpointWithoutOuputClobbersGPArgs();
693 void testSimplePatchpointWithOuputClobbersGPArgs();
694 void testSimplePatchpointWithoutOuputClobbersFPArgs();
695 void testSimplePatchpointWithOuputClobbersFPArgs();
696 void testPatchpointWithEarlyClobber();
697 void testPatchpointCallArg();
698 void testPatchpointFixedRegister();
699 void testPatchpointAny(ValueRep rep);
700 void testPatchpointGPScratch();
701 void testPatchpointFPScratch();
702 void testPatchpointLotsOfLateAnys();
703 void testPatchpointAnyImm(ValueRep rep);
704 void testPatchpointManyWarmAnyImms();
705 void testPatchpointManyColdAnyImms();
706 void testPatchpointWithRegisterResult();
707 void testPatchpointWithStackArgumentResult();
708 void testPatchpointWithAnyResult();
709 void testSimpleCheck();
710 void testCheckFalse();
711 void testCheckTrue();
712 void testCheckLessThan();
713 void testCheckMegaCombo();
714 void testCheckTrickyMegaCombo();
715 void testCheckTwoMegaCombos();
716 void testCheckTwoNonRedundantMegaCombos();
717 void testCheckAddImm();
718 void testCheckAddImmCommute();
719 void testCheckAddImmSomeRegister();
720 void testCheckAdd();
721 void testCheckAdd64();
722 void testCheckAddFold(int, int);
723 void testCheckAddFoldFail(int, int);
724 void test42();
725 void testLoad42();
726 void testLoadAcq42();
727 void testLoadWithOffsetImpl(int32_t offset64, int32_t offset32);
728 void testLoadOffsetImm9Max();
729 void testLoadOffsetImm9MaxPlusOne();
730 void testLoadOffsetImm9MaxPlusTwo();
731 void testLoadOffsetImm9Min();
732 void testLoadOffsetImm9MinMinusOne();
733 void testLoadOffsetScaledUnsignedImm12Max();
734 void testLoadOffsetScaledUnsignedOverImm12Max();
735 void testAddTreeArg32(int32_t);
736 void testMulTreeArg32(int32_t);
737 void testArg(int argument);
738 void testReturnConst64(int64_t value);
739 void testReturnVoid();
740 void testAddArg(int);
741 void testAddArgs(int, int);
742 void testAddArgImm(int, int);
743 void testAddImmArg(int, int);
744 void testAddArgMem(int64_t, int64_t);
745 void testAddMemArg(int64_t, int64_t);
746 void testAddImmMem(int64_t, int64_t);
747 void testAddArg32(int);
748 void testAddArgs32(int, int);
749 void testAddArgMem32(int32_t, int32_t);
750 void testAddMemArg32(int32_t, int32_t);
751 void testAddImmMem32(int32_t, int32_t);
752 void testAddNeg1(int, int);
753 void testAddNeg2(int, int);
754 void testAddArgZeroImmZDef();
755 void testAddLoadTwice();
756 void testAddArgDouble(double);
757 void testCheckAddArgumentAliasing64();
758 void testCheckAddArgumentAliasing32();
759 void testCheckAddSelfOverflow64();
760 void testCheckAddSelfOverflow32();
761 void testCheckSubImm();
762 void testCheckSubBadImm();
763 void testCheckSub();
764 double doubleSub(double, double);
765 void testCheckSub64();
766 void testCheckSubFold(int, int);
767 void testCheckSubFoldFail(int, int);
768 void testCheckNeg();
769 void testCheckNeg64();
770 void testCheckMul();
771 void testCheckMulMemory();
772 void testCheckMul2();
773 void testCheckMul64();
774 void testCheckMulFold(int, int);
775 void testCheckMulFoldFail(int, int);
776 void testAddArgsDouble(double, double);
777 void testAddArgImmDouble(double, double);
778 void testAddImmArgDouble(double, double);
779 void testAddImmsDouble(double, double);
780 void testAddArgFloat(float);
781 void testAddArgsFloat(float, float);
782 void testAddFPRArgsFloat(float, float);
783 void testAddArgImmFloat(float, float);
784 void testAddImmArgFloat(float, float);
785 void testAddImmsFloat(float, float);
786 void testAddArgFloatWithUselessDoubleConversion(float);
787 void testAddArgsFloatWithUselessDoubleConversion(float, float);
788 void testAddArgsFloatWithEffectfulDoubleConversion(float, float);
789 void testAddMulMulArgs(int64_t, int64_t, int64_t c);
790 void testMulArg(int);
791 void testMulArgStore(int);
792 void testMulAddArg(int);
793 void testMulArgs(int, int);
794 void testMulArgNegArg(int, int);
795 void testCheckMulArgumentAliasing64();
796 void testCheckMulArgumentAliasing32();
797 void testCheckMul64SShr();
798 void testCompareImpl(B3::Opcode opcode, int64_t left, int64_t right);
799 void testCompare(B3::Opcode opcode, int64_t left, int64_t right);
800 void testEqualDouble(double left, double right, bool result);
801 void testCallSimple(int, int);
802 void testCallRare(int, int);
803 void testCallRareLive(int, int, int c);
804 void testCallSimplePure(int, int);
805 void testCallFunctionWithHellaArguments();
806 void testCallFunctionWithHellaArguments2();
807 void testCallFunctionWithHellaArguments3();
808 void testReturnDouble(double value);
809 void testReturnFloat(float value);
810 void testMulNegArgArg(int, int);
811 void testMulArgImm(int64_t, int64_t);
812 void testMulImmArg(int, int);
813 void testMulArgs32(int, int);
814 void testMulArgs32SignExtend(int, int);
815 void testMulImm32SignExtend(const int, int);
816 void testMulLoadTwice();
817 void testMulAddArgsLeft();
818 void testMulAddArgsRight();
819 void testMulAddArgsLeft32();
820 void testMulAddArgsRight32();
821 void testMulSubArgsLeft();
822 void testMulSubArgsRight();
823 void testMulSubArgsLeft32();
824 void testMulSubArgsRight32();
825 void testMulNegArgs();
826 void testMulNegArgs32();
827 void testMulArgDouble(double);
828 void testMulArgsDouble(double, double);
829 void testCallSimpleDouble(double, double);
830 void testCallSimpleFloat(float, float);
831 void testCallFunctionWithHellaDoubleArguments();
832 void testCallFunctionWithHellaFloatArguments();
833 void testLinearScanWithCalleeOnStack();
834 void testChillDiv(int num, int den, int res);
835 void testChillDivTwice(int num1, int den1, int num2, int den2, int res);
836 void testChillDiv64(int64_t num, int64_t den, int64_t res);
837 void testModArg(int64_t value);
838 void testModArgs(int64_t numerator, int64_t denominator);
839 void testModImms(int64_t numerator, int64_t denominator);
840 void testMulArgImmDouble(double, double);
841 void testMulImmArgDouble(double, double);
842 void testMulImmsDouble(double, double);
843 void testMulArgFloat(float);
844 void testMulArgsFloat(float, float);
845 void testMulArgImmFloat(float, float);
846 void testMulImmArgFloat(float, float);
847 void testMulImmsFloat(float, float);
848 void testMulArgFloatWithUselessDoubleConversion(float);
849 void testMulArgsFloatWithUselessDoubleConversion(float, float);
850 void testMulArgsFloatWithEffectfulDoubleConversion(float, float);
851 void testDivArgDouble(double);
852 void testDivArgsDouble(double, double);
853 void testDivArgImmDouble(double, double);
854 void testDivImmArgDouble(double, double);
855 void testDivImmsDouble(double, double);
856 void testDivArgFloat(float);
857 void testDivArgsFloat(float, float);
858 void testDivArgImmFloat(float, float);
859 void testModArg32(int32_t value);
860 void testModArgs32(int32_t numerator, int32_t denominator);
861 void testModImms32(int32_t numerator, int32_t denominator);
862 void testChillModArg(int64_t value);
863 void testChillModArgs(int64_t numerator, int64_t denominator);
864 void testChillModImms(int64_t numerator, int64_t denominator);
865 void testChillModArg32(int32_t value);
866 void testChillModArgs32(int32_t numerator, int32_t denominator);
867 void testChillModImms32(int32_t numerator, int32_t denominator);
868 void testLoopWithMultipleHeaderEdges();
869 void testSwitch(unsigned degree);
870 void testSwitch(unsigned degree, unsigned gap);
871 void testSwitchSameCaseAsDefault();
872 void testSwitchChillDiv(unsigned degree, unsigned gap);
873 void testSwitchTargettingSameBlock();
874 void testSwitchTargettingSameBlockFoldPathConstant();
875 void testTruncFold(int64_t value);
876 void testZExt32(int32_t value);
877 void testZExt32Fold(int32_t value);
878 void testSExt32(int32_t value);
879 void testSExt32Fold(int32_t value);
880 void testTruncZExt32(int32_t value);
881 void testPinRegisters();
882 void testX86LeaAddAddShlLeft();
883 void testX86LeaAddAddShlRight();
884 void testX86LeaAddAdd();
885 void testX86LeaAddShlRight();
886 void testX86LeaAddShlLeftScale1();
887 void testX86LeaAddShlLeftScale2();
888 void testX86LeaAddShlLeftScale4();
889 void testX86LeaAddShlLeftScale8();
890 void testAddShl32();
891 void testAddShl64();
892 void testAddShl65();
893 void testReduceStrengthReassociation(bool flip);
894 void testLoadBaseIndexShift2();
895 void testLoadBaseIndexShift32();
896 void testOptimizeMaterialization();
897 void testLICMPure();
898 void testLICMPureSideExits();
899 void testTruncSExt32(int32_t value);
900 void testSExt8(int32_t value);
901 void testSExt8Fold(int32_t value);
902 void testSExt8SExt8(int32_t value);
903 void testSExt8SExt16(int32_t value);
904 void testSExt8BitAnd(int32_t value, int32_t mask);
905 void testBitAndSExt8(int32_t value, int32_t mask);
906 void testSExt16(int32_t value);
907 void testSExt16Fold(int32_t value);
908 void testSExt16SExt16(int32_t value);
909 void testSExt16SExt8(int32_t value);
910 void testLICMPureWritesPinned();
911 void testLICMPureWrites();
912 void testLICMReadsLocalState();
913 void testLICMReadsPinned();
914 void testLICMReads();
915 void testLICMPureNotBackwardsDominant();
916 void testLICMPureFoiledByChild();
917 void testLICMPureNotBackwardsDominantFoiledByChild();
918 void testLICMExitsSideways();
919 void testLICMWritesLocalState();
920 void testLICMWrites();
921 void testLICMFence();
922 void testLICMWritesPinned();
923 void testLICMControlDependent();
924 void testLICMControlDependentNotBackwardsDominant();
925 void testLICMControlDependentSideExits();
926 void testLICMReadsPinnedWritesPinned();
927 void testLICMReadsWritesDifferentHeaps();
928 void testLICMReadsWritesOverlappingHeaps();
929 void testLICMDefaultCall();
930 void testDepend32();
931 void testDepend64();
932 void testWasmBoundsCheck(unsigned offset);
933 void testWasmAddress();
934 void testFastTLSLoad();
935 void testFastTLSStore();
936 void testDoubleLiteralComparison(double, double);
937 void testFloatEqualOrUnorderedFolding();
938 void testFloatEqualOrUnorderedFoldingNaN();
939 void testFloatEqualOrUnorderedDontFold();
940 void testSExt16BitAnd(int32_t value, int32_t mask);
941 void testBitAndSExt16(int32_t value, int32_t mask);
942 void testSExt32BitAnd(int32_t value, int32_t mask);
943 void testShuffleDoesntTrashCalleeSaves();
944 void testDemotePatchpointTerminal();
945 void testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead();
946 void testInfiniteLoopDoesntCauseBadHoisting();
947 void testDivImmArgFloat(float, float);
948 void testDivImmsFloat(float, float);
949 void testModArgDouble(double);
950 void testModArgsDouble(double, double);
951 void testModArgImmDouble(double, double);
952 void testModImmArgDouble(double, double);
953 void testModImmsDouble(double, double);
954 void testModArgFloat(float);
955 void testModArgsFloat(float, float);
956 void testModArgImmFloat(float, float);
957 void testModImmArgFloat(float, float);
958 void testModImmsFloat(float, float);
959 void testDivArgFloatWithUselessDoubleConversion(float);
960 void testDivArgsFloatWithUselessDoubleConversion(float, float);
961 void testDivArgsFloatWithEffectfulDoubleConversion(float, float);
962 void testUDivArgsInt32(uint32_t, uint32_t);
963 void testUDivArgsInt64(uint64_t, uint64_t);
964 void testUModArgsInt32(uint32_t, uint32_t);
965 void testUModArgsInt64(uint64_t, uint64_t);
966 void testSubArg(int);
967 void testSubArgs(int, int);
968 void testSubArgImm(int64_t, int64_t);
969 void testSubNeg(int, int);
970 void testNegSub(int, int);
971 void testNegValueSubOne(int);
972 void testSubSub(int, int, int c);
973 void testSubSub2(int, int, int c);
974 void testSubAdd(int, int, int c);
975 void testSubFirstNeg(int, int);
976 void testSubImmArg(int, int);
977 void testSubArgMem(int64_t, int64_t);
978 void testSubMemArg(int64_t, int64_t);
979 void testSubImmMem(int64_t, int64_t);
980 void testSubMemImm(int64_t, int64_t);
981 void testSubArgs32(int, int);
982 void testSubArgImm32(int, int);
983 void testSubImmArg32(int, int);
984 void testSubMemArg32(int32_t, int32_t);
985 void testSubArgMem32(int32_t, int32_t);
986 void testSubImmMem32(int32_t, int32_t);
987 void testSubMemImm32(int32_t, int32_t);
988 void testNegValueSubOne32(int);
989 void testNegMulArgImm(int64_t, int64_t);
990 void testSubMulMulArgs(int64_t, int64_t, int64_t c);
991 void testSubArgDouble(double);
992 void testSubArgsDouble(double, double);
993 void testSubArgImmDouble(double, double);
994 void testSubImmArgDouble(double, double);
995 void testSubImmsDouble(double, double);
996 void testSubArgFloat(float);
997 void testSubArgsFloat(float, float);
998 void testSubArgImmFloat(float, float);
999 void testSubImmArgFloat(float, float);
1000 void testSubImmsFloat(float, float);
1001 void testSubArgFloatWithUselessDoubleConversion(float);
1002 void testSubArgsFloatWithUselessDoubleConversion(float, float);
1003 void testSubArgsFloatWithEffectfulDoubleConversion(float, float);
1004 void testTernarySubInstructionSelection(B3::Opcode valueModifier, Type valueType, Air::Opcode expectedOpcode);
1005 void testNegDouble(double);
1006 void testNegFloat(float);
1007 void testNegFloatWithUselessDoubleConversion(float);
1008
1009 void addArgTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1010 void addBitTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1011 void addCallTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1012 void addSExtTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1013 void addSShrShTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1014 void addShrTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1015 void addAtomicTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1016 void addLoadTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1017 void addTupleTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1018
1019 bool shouldRun(const char* filter, const char* testName);
1020
1021 #endif // ENABLE(B3_JIT)