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