[JSC] 32bit bitwide operation with all-one (-1) is wrong in B3
[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 testBitXorAndAndArgs32(int32_t, int32_t, int32_t c);
463 void testBitXorAndSameArgs(int64_t, int64_t);
464 void testBitXorAndSameArgs32(int32_t, int32_t);
465 void testBitXorImms(int64_t, int64_t);
466 void testBitXorArgImm(int64_t, int64_t);
467 void testBitXorImmArg(int64_t, int64_t);
468 void testBitXorBitXorArgImmImm(int64_t, int64_t, int64_t c);
469 void testBitXorImmBitXorArgImm(int64_t, int64_t, int64_t c);
470 void testBitXorArgs32(int, int);
471 void testBitXorSameArg32(int);
472 void testBitXorImms32(int, int);
473 void testBitXorArgImm32(int, int);
474 void testBitXorImmArg32(int, int);
475 void testBitXorBitXorArgImmImm32(int, int, int c);
476 void testBitXorImmBitXorArgImm32(int, int, int c);
477 void testBitNotArg(int64_t);
478 void testBitNotImm(int64_t);
479 void testBitNotMem(int64_t);
480 void testBitNotArg32(int32_t);
481 void testBitNotImm32(int32_t);
482 void testBitNotMem32(int32_t);
483 void testNotOnBooleanAndBranch32(int64_t, int64_t);
484 void testBitNotOnBooleanAndBranch32(int64_t, int64_t);
485 void testShlArgs(int64_t, int64_t);
486 void testShlImms(int64_t, int64_t);
487 void testShlArgImm(int64_t, int64_t);
488 void testShlSShrArgImm(int64_t, int64_t);
489 void testShlArg32(int32_t);
490 void testShlArgs32(int32_t, int32_t);
491 void testShlImms32(int32_t, int32_t);
492 void testShlArgImm32(int32_t, int32_t);
493 void testShlZShrArgImm32(int32_t, int32_t);
494 void testClzArg64(int64_t);
495 void testClzMem64(int64_t);
496 void testClzArg32(int32_t);
497 void testClzMem32(int32_t);
498 void testAbsArg(double);
499 void testAbsImm(double);
500 void testAbsMem(double);
501 void testAbsAbsArg(double);
502 void testAbsNegArg(double);
503 void testAbsBitwiseCastArg(double);
504 void testBitwiseCastAbsBitwiseCastArg(double);
505 void testAbsArg(float);
506 void testAbsImm(float);
507 void testAbsMem(float);
508 void testAbsAbsArg(float);
509 void testAbsNegArg(float);
510 void testAbsBitwiseCastArg(float);
511 void testBitwiseCastAbsBitwiseCastArg(float);
512 void testAbsArgWithUselessDoubleConversion(float);
513 void testAbsArgWithEffectfulDoubleConversion(float);
514 void testCeilArg(double);
515 void testCeilImm(double);
516 void testCeilMem(double);
517 void testCeilCeilArg(double);
518 void testFloorCeilArg(double);
519 void testCeilIToD64(int64_t);
520 void testCeilIToD32(int64_t);
521 void testCeilArg(float);
522 void testCeilImm(float);
523 void testCeilMem(float);
524 void testCeilCeilArg(float);
525 void testFloorCeilArg(float);
526 void testCeilArgWithUselessDoubleConversion(float);
527 void testCeilArgWithEffectfulDoubleConversion(float);
528 void testFloorArg(double);
529 void testFloorImm(double);
530 void testFloorMem(double);
531 void testFloorFloorArg(double);
532 void testCeilFloorArg(double);
533 void testFloorIToD64(int64_t);
534 void testFloorIToD32(int64_t);
535 void testFloorArg(float);
536 void testFloorImm(float);
537 void testFloorMem(float);
538 void testFloorFloorArg(float);
539 void testCeilFloorArg(float);
540 void testFloorArgWithUselessDoubleConversion(float);
541 void testFloorArgWithEffectfulDoubleConversion(float);
542 double correctSqrt(double value);
543 void testSqrtArg(double);
544 void testSqrtImm(double);
545 void testSqrtMem(double);
546 void testSqrtArg(float);
547 void testSqrtImm(float);
548 void testSqrtMem(float);
549 void testSqrtArgWithUselessDoubleConversion(float);
550 void testSqrtArgWithEffectfulDoubleConversion(float);
551 void testCompareTwoFloatToDouble(float, float);
552 void testCompareOneFloatToDouble(float, double);
553 void testCompareFloatToDoubleThroughPhi(float, float);
554 void testDoubleToFloatThroughPhi(float value);
555 void testReduceFloatToDoubleValidates();
556 void testDoubleProducerPhiToFloatConversion(float value);
557 void testDoubleProducerPhiToFloatConversionWithDoubleConsumer(float value);
558 void testDoubleProducerPhiWithNonFloatConst(float value, double constValue);
559 void testDoubleArgToInt64BitwiseCast(double value);
560 void testDoubleImmToInt64BitwiseCast(double value);
561 void testTwoBitwiseCastOnDouble(double value);
562 void testBitwiseCastOnDoubleInMemory(double value);
563 void testBitwiseCastOnDoubleInMemoryIndexed(double value);
564 void testInt64BArgToDoubleBitwiseCast(int64_t value);
565 void testInt64BImmToDoubleBitwiseCast(int64_t value);
566 void testTwoBitwiseCastOnInt64(int64_t value);
567 void testBitwiseCastOnInt64InMemory(int64_t value);
568 void testBitwiseCastOnInt64InMemoryIndexed(int64_t value);
569 void testFloatImmToInt32BitwiseCast(float value);
570 void testBitwiseCastOnFloatInMemory(float value);
571 void testInt32BArgToFloatBitwiseCast(int32_t value);
572 void testInt32BImmToFloatBitwiseCast(int32_t value);
573 void testTwoBitwiseCastOnInt32(int32_t value);
574 void testBitwiseCastOnInt32InMemory(int32_t value);
575 void testConvertDoubleToFloatArg(double value);
576 void testConvertDoubleToFloatImm(double value);
577 void testConvertDoubleToFloatMem(double value);
578 void testConvertFloatToDoubleArg(float value);
579 void testConvertFloatToDoubleImm(float value);
580 void testConvertFloatToDoubleMem(float value);
581 void testConvertDoubleToFloatToDoubleToFloat(double value);
582 void testLoadFloatConvertDoubleConvertFloatStoreFloat(float value);
583 void testFroundArg(double value);
584 void testFroundMem(double value);
585 void testIToD64Arg();
586 void testIToF64Arg();
587 void testIToD32Arg();
588 void testIToF32Arg();
589 void testIToD64Mem();
590 void testIToF64Mem();
591 void testIToD32Mem();
592 void testIToF32Mem();
593 void testIToD64Imm(int64_t value);
594 void testIToF64Imm(int64_t value);
595 void testIToD32Imm(int32_t value);
596 void testIToF32Imm(int32_t value);
597 void testIToDReducedToIToF64Arg();
598 void testIToDReducedToIToF32Arg();
599 void testStore32(int value);
600 void testStoreConstant(int value);
601 void testStoreConstantPtr(intptr_t value);
602 void testStore8Arg();
603 void testStore8Imm();
604 void testStorePartial8BitRegisterOnX86();
605 void testStore16Arg();
606 void testStore16Imm();
607 void testTrunc(int64_t value);
608 void testAdd1(int value);
609 void testAdd1Ptr(intptr_t value);
610 void testNeg32(int32_t value);
611 void testNegPtr(intptr_t value);
612 void testStoreAddLoad32(int amount);
613 void testStoreRelAddLoadAcq32(int amount);
614 void testStoreAddLoadImm32(int amount);
615 void testStoreAddLoad8(int amount, B3::Opcode loadOpcode);
616 void testStoreRelAddLoadAcq8(int amount, B3::Opcode loadOpcode);
617 void testStoreRelAddFenceLoadAcq8(int amount, B3::Opcode loadOpcode);
618 void testStoreAddLoadImm8(int amount, B3::Opcode loadOpcode);
619 void testStoreAddLoad16(int amount, B3::Opcode loadOpcode);
620 void testStoreRelAddLoadAcq16(int amount, B3::Opcode loadOpcode);
621 void testStoreAddLoadImm16(int amount, B3::Opcode loadOpcode);
622 void testStoreAddLoad64(int amount);
623 void testStoreRelAddLoadAcq64(int amount);
624 void testStoreAddLoadImm64(int64_t amount);
625 void testStoreAddLoad32Index(int amount);
626 void testStoreAddLoadImm32Index(int amount);
627 void testStoreAddLoad8Index(int amount, B3::Opcode loadOpcode);
628 void testStoreAddLoadImm8Index(int amount, B3::Opcode loadOpcode);
629 void testStoreAddLoad16Index(int amount, B3::Opcode loadOpcode);
630 void testStoreAddLoadImm16Index(int amount, B3::Opcode loadOpcode);
631 void testStoreAddLoad64Index(int amount);
632 void testStoreAddLoadImm64Index(int64_t amount);
633 void testStoreSubLoad(int amount);
634 void testStoreAddLoadInterference(int amount);
635 void testStoreAddAndLoad(int amount, int mask);
636 void testStoreNegLoad32(int32_t value);
637 void testStoreNegLoadPtr(intptr_t value);
638 void testAdd1Uncommuted(int value);
639 void testLoadOffset();
640 void testLoadOffsetNotConstant();
641 void testLoadOffsetUsingAdd();
642 void testLoadOffsetUsingAddInterference();
643 void testLoadOffsetUsingAddNotConstant();
644 void testLoadAddrShift(unsigned shift);
645 void testFramePointer();
646 void testOverrideFramePointer();
647 void testStackSlot();
648 void testLoadFromFramePointer();
649 void testStoreLoadStackSlot(int value);
650 void testStoreFloat(double input);
651 void testStoreDoubleConstantAsFloat(double input);
652 void testSpillGP();
653 void testSpillFP();
654 void testInt32ToDoublePartialRegisterStall();
655 void testInt32ToDoublePartialRegisterWithoutStall();
656 void testBranch();
657 void testBranchPtr();
658 void testDiamond();
659 void testBranchNotEqual();
660 void testBranchNotEqualCommute();
661 void testBranchNotEqualNotEqual();
662 void testBranchEqual();
663 void testBranchEqualEqual();
664 void testBranchEqualCommute();
665 void testBranchEqualEqual1();
666 void testBranchEqualOrUnorderedArgs(double, double);
667 void testBranchEqualOrUnorderedArgs(float, float);
668 void testBranchNotEqualAndOrderedArgs(double, double);
669 void testBranchNotEqualAndOrderedArgs(float, float);
670 void testBranchEqualOrUnorderedDoubleArgImm(double, double);
671 void testBranchEqualOrUnorderedFloatArgImm(float, float);
672 void testBranchEqualOrUnorderedDoubleImms(double, double);
673 void testBranchEqualOrUnorderedFloatImms(float, float);
674 void testBranchEqualOrUnorderedFloatWithUselessDoubleConversion(float, float);
675 void testBranchFold(int value);
676 void testDiamondFold(int value);
677 void testBranchNotEqualFoldPtr(intptr_t value);
678 void testBranchEqualFoldPtr(intptr_t value);
679 void testBranchLoadPtr();
680 void testBranchLoad32();
681 void testBranchLoad8S();
682 void testBranchLoad8Z();
683 void testBranchLoad16S();
684 void testBranchLoad16Z();
685 void testBranch8WithLoad8ZIndex();
686 void testComplex(unsigned numVars, unsigned numConstructs);
687 void testBranchBitTest32TmpImm(uint32_t value, uint32_t imm);
688 void testBranchBitTest32AddrImm(uint32_t value, uint32_t imm);
689 void testBranchBitTest32TmpTmp(uint32_t value, uint32_t value2);
690 void testBranchBitTest64TmpTmp(uint64_t value, uint64_t value2);
691 void testBranchBitTest64AddrTmp(uint64_t value, uint64_t value2);
692 void testBranchBitTestNegation(uint64_t value, uint64_t value2);
693 void testBranchBitTestNegation2(uint64_t value, uint64_t value2);
694 void testSimplePatchpoint();
695 void testSimplePatchpointWithoutOuputClobbersGPArgs();
696 void testSimplePatchpointWithOuputClobbersGPArgs();
697 void testSimplePatchpointWithoutOuputClobbersFPArgs();
698 void testSimplePatchpointWithOuputClobbersFPArgs();
699 void testPatchpointWithEarlyClobber();
700 void testPatchpointCallArg();
701 void testPatchpointFixedRegister();
702 void testPatchpointAny(ValueRep rep);
703 void testPatchpointGPScratch();
704 void testPatchpointFPScratch();
705 void testPatchpointLotsOfLateAnys();
706 void testPatchpointAnyImm(ValueRep rep);
707 void testPatchpointManyWarmAnyImms();
708 void testPatchpointManyColdAnyImms();
709 void testPatchpointWithRegisterResult();
710 void testPatchpointWithStackArgumentResult();
711 void testPatchpointWithAnyResult();
712 void testSimpleCheck();
713 void testCheckFalse();
714 void testCheckTrue();
715 void testCheckLessThan();
716 void testCheckMegaCombo();
717 void testCheckTrickyMegaCombo();
718 void testCheckTwoMegaCombos();
719 void testCheckTwoNonRedundantMegaCombos();
720 void testCheckAddImm();
721 void testCheckAddImmCommute();
722 void testCheckAddImmSomeRegister();
723 void testCheckAdd();
724 void testCheckAdd64();
725 void testCheckAddFold(int, int);
726 void testCheckAddFoldFail(int, int);
727 void test42();
728 void testLoad42();
729 void testLoadAcq42();
730 void testLoadWithOffsetImpl(int32_t offset64, int32_t offset32);
731 void testLoadOffsetImm9Max();
732 void testLoadOffsetImm9MaxPlusOne();
733 void testLoadOffsetImm9MaxPlusTwo();
734 void testLoadOffsetImm9Min();
735 void testLoadOffsetImm9MinMinusOne();
736 void testLoadOffsetScaledUnsignedImm12Max();
737 void testLoadOffsetScaledUnsignedOverImm12Max();
738 void testAddTreeArg32(int32_t);
739 void testMulTreeArg32(int32_t);
740 void testArg(int argument);
741 void testReturnConst64(int64_t value);
742 void testReturnVoid();
743 void testAddArg(int);
744 void testAddArgs(int, int);
745 void testAddArgImm(int, int);
746 void testAddImmArg(int, int);
747 void testAddArgMem(int64_t, int64_t);
748 void testAddMemArg(int64_t, int64_t);
749 void testAddImmMem(int64_t, int64_t);
750 void testAddArg32(int);
751 void testAddArgs32(int, int);
752 void testAddArgMem32(int32_t, int32_t);
753 void testAddMemArg32(int32_t, int32_t);
754 void testAddImmMem32(int32_t, int32_t);
755 void testAddNeg1(int, int);
756 void testAddNeg2(int, int);
757 void testAddArgZeroImmZDef();
758 void testAddLoadTwice();
759 void testAddArgDouble(double);
760 void testCheckAddArgumentAliasing64();
761 void testCheckAddArgumentAliasing32();
762 void testCheckAddSelfOverflow64();
763 void testCheckAddSelfOverflow32();
764 void testCheckSubImm();
765 void testCheckSubBadImm();
766 void testCheckSub();
767 double doubleSub(double, double);
768 void testCheckSub64();
769 void testCheckSubFold(int, int);
770 void testCheckSubFoldFail(int, int);
771 void testCheckNeg();
772 void testCheckNeg64();
773 void testCheckMul();
774 void testCheckMulMemory();
775 void testCheckMul2();
776 void testCheckMul64();
777 void testCheckMulFold(int, int);
778 void testCheckMulFoldFail(int, int);
779 void testAddArgsDouble(double, double);
780 void testAddArgImmDouble(double, double);
781 void testAddImmArgDouble(double, double);
782 void testAddImmsDouble(double, double);
783 void testAddArgFloat(float);
784 void testAddArgsFloat(float, float);
785 void testAddFPRArgsFloat(float, float);
786 void testAddArgImmFloat(float, float);
787 void testAddImmArgFloat(float, float);
788 void testAddImmsFloat(float, float);
789 void testAddArgFloatWithUselessDoubleConversion(float);
790 void testAddArgsFloatWithUselessDoubleConversion(float, float);
791 void testAddArgsFloatWithEffectfulDoubleConversion(float, float);
792 void testAddMulMulArgs(int64_t, int64_t, int64_t c);
793 void testMulArg(int);
794 void testMulArgStore(int);
795 void testMulAddArg(int);
796 void testMulArgs(int, int);
797 void testMulArgNegArg(int, int);
798 void testCheckMulArgumentAliasing64();
799 void testCheckMulArgumentAliasing32();
800 void testCheckMul64SShr();
801 void testCompareImpl(B3::Opcode opcode, int64_t left, int64_t right);
802 void testCompare(B3::Opcode opcode, int64_t left, int64_t right);
803 void testEqualDouble(double left, double right, bool result);
804 void testCallSimple(int, int);
805 void testCallRare(int, int);
806 void testCallRareLive(int, int, int c);
807 void testCallSimplePure(int, int);
808 void testCallFunctionWithHellaArguments();
809 void testCallFunctionWithHellaArguments2();
810 void testCallFunctionWithHellaArguments3();
811 void testReturnDouble(double value);
812 void testReturnFloat(float value);
813 void testMulNegArgArg(int, int);
814 void testMulArgImm(int64_t, int64_t);
815 void testMulImmArg(int, int);
816 void testMulArgs32(int, int);
817 void testMulArgs32SignExtend(int, int);
818 void testMulImm32SignExtend(const int, int);
819 void testMulLoadTwice();
820 void testMulAddArgsLeft();
821 void testMulAddArgsRight();
822 void testMulAddArgsLeft32();
823 void testMulAddArgsRight32();
824 void testMulSubArgsLeft();
825 void testMulSubArgsRight();
826 void testMulSubArgsLeft32();
827 void testMulSubArgsRight32();
828 void testMulNegArgs();
829 void testMulNegArgs32();
830 void testMulArgDouble(double);
831 void testMulArgsDouble(double, double);
832 void testCallSimpleDouble(double, double);
833 void testCallSimpleFloat(float, float);
834 void testCallFunctionWithHellaDoubleArguments();
835 void testCallFunctionWithHellaFloatArguments();
836 void testLinearScanWithCalleeOnStack();
837 void testChillDiv(int num, int den, int res);
838 void testChillDivTwice(int num1, int den1, int num2, int den2, int res);
839 void testChillDiv64(int64_t num, int64_t den, int64_t res);
840 void testModArg(int64_t value);
841 void testModArgs(int64_t numerator, int64_t denominator);
842 void testModImms(int64_t numerator, int64_t denominator);
843 void testMulArgImmDouble(double, double);
844 void testMulImmArgDouble(double, double);
845 void testMulImmsDouble(double, double);
846 void testMulArgFloat(float);
847 void testMulArgsFloat(float, float);
848 void testMulArgImmFloat(float, float);
849 void testMulImmArgFloat(float, float);
850 void testMulImmsFloat(float, float);
851 void testMulArgFloatWithUselessDoubleConversion(float);
852 void testMulArgsFloatWithUselessDoubleConversion(float, float);
853 void testMulArgsFloatWithEffectfulDoubleConversion(float, float);
854 void testDivArgDouble(double);
855 void testDivArgsDouble(double, double);
856 void testDivArgImmDouble(double, double);
857 void testDivImmArgDouble(double, double);
858 void testDivImmsDouble(double, double);
859 void testDivArgFloat(float);
860 void testDivArgsFloat(float, float);
861 void testDivArgImmFloat(float, float);
862 void testModArg32(int32_t value);
863 void testModArgs32(int32_t numerator, int32_t denominator);
864 void testModImms32(int32_t numerator, int32_t denominator);
865 void testChillModArg(int64_t value);
866 void testChillModArgs(int64_t numerator, int64_t denominator);
867 void testChillModImms(int64_t numerator, int64_t denominator);
868 void testChillModArg32(int32_t value);
869 void testChillModArgs32(int32_t numerator, int32_t denominator);
870 void testChillModImms32(int32_t numerator, int32_t denominator);
871 void testLoopWithMultipleHeaderEdges();
872 void testSwitch(unsigned degree);
873 void testSwitch(unsigned degree, unsigned gap);
874 void testSwitchSameCaseAsDefault();
875 void testSwitchChillDiv(unsigned degree, unsigned gap);
876 void testSwitchTargettingSameBlock();
877 void testSwitchTargettingSameBlockFoldPathConstant();
878 void testTruncFold(int64_t value);
879 void testZExt32(int32_t value);
880 void testZExt32Fold(int32_t value);
881 void testSExt32(int32_t value);
882 void testSExt32Fold(int32_t value);
883 void testTruncZExt32(int32_t value);
884 void testPinRegisters();
885 void testX86LeaAddAddShlLeft();
886 void testX86LeaAddAddShlRight();
887 void testX86LeaAddAdd();
888 void testX86LeaAddShlRight();
889 void testX86LeaAddShlLeftScale1();
890 void testX86LeaAddShlLeftScale2();
891 void testX86LeaAddShlLeftScale4();
892 void testX86LeaAddShlLeftScale8();
893 void testAddShl32();
894 void testAddShl64();
895 void testAddShl65();
896 void testReduceStrengthReassociation(bool flip);
897 void testLoadBaseIndexShift2();
898 void testLoadBaseIndexShift32();
899 void testOptimizeMaterialization();
900 void testLICMPure();
901 void testLICMPureSideExits();
902 void testTruncSExt32(int32_t value);
903 void testSExt8(int32_t value);
904 void testSExt8Fold(int32_t value);
905 void testSExt8SExt8(int32_t value);
906 void testSExt8SExt16(int32_t value);
907 void testSExt8BitAnd(int32_t value, int32_t mask);
908 void testBitAndSExt8(int32_t value, int32_t mask);
909 void testSExt16(int32_t value);
910 void testSExt16Fold(int32_t value);
911 void testSExt16SExt16(int32_t value);
912 void testSExt16SExt8(int32_t value);
913 void testLICMPureWritesPinned();
914 void testLICMPureWrites();
915 void testLICMReadsLocalState();
916 void testLICMReadsPinned();
917 void testLICMReads();
918 void testLICMPureNotBackwardsDominant();
919 void testLICMPureFoiledByChild();
920 void testLICMPureNotBackwardsDominantFoiledByChild();
921 void testLICMExitsSideways();
922 void testLICMWritesLocalState();
923 void testLICMWrites();
924 void testLICMFence();
925 void testLICMWritesPinned();
926 void testLICMControlDependent();
927 void testLICMControlDependentNotBackwardsDominant();
928 void testLICMControlDependentSideExits();
929 void testLICMReadsPinnedWritesPinned();
930 void testLICMReadsWritesDifferentHeaps();
931 void testLICMReadsWritesOverlappingHeaps();
932 void testLICMDefaultCall();
933 void testDepend32();
934 void testDepend64();
935 void testWasmBoundsCheck(unsigned offset);
936 void testWasmAddress();
937 void testFastTLSLoad();
938 void testFastTLSStore();
939 void testDoubleLiteralComparison(double, double);
940 void testFloatEqualOrUnorderedFolding();
941 void testFloatEqualOrUnorderedFoldingNaN();
942 void testFloatEqualOrUnorderedDontFold();
943 void testSExt16BitAnd(int32_t value, int32_t mask);
944 void testBitAndSExt16(int32_t value, int32_t mask);
945 void testSExt32BitAnd(int32_t value, int32_t mask);
946 void testShuffleDoesntTrashCalleeSaves();
947 void testDemotePatchpointTerminal();
948 void testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead();
949 void testInfiniteLoopDoesntCauseBadHoisting();
950 void testDivImmArgFloat(float, float);
951 void testDivImmsFloat(float, float);
952 void testModArgDouble(double);
953 void testModArgsDouble(double, double);
954 void testModArgImmDouble(double, double);
955 void testModImmArgDouble(double, double);
956 void testModImmsDouble(double, double);
957 void testModArgFloat(float);
958 void testModArgsFloat(float, float);
959 void testModArgImmFloat(float, float);
960 void testModImmArgFloat(float, float);
961 void testModImmsFloat(float, float);
962 void testDivArgFloatWithUselessDoubleConversion(float);
963 void testDivArgsFloatWithUselessDoubleConversion(float, float);
964 void testDivArgsFloatWithEffectfulDoubleConversion(float, float);
965 void testUDivArgsInt32(uint32_t, uint32_t);
966 void testUDivArgsInt64(uint64_t, uint64_t);
967 void testUModArgsInt32(uint32_t, uint32_t);
968 void testUModArgsInt64(uint64_t, uint64_t);
969 void testSubArg(int);
970 void testSubArgs(int, int);
971 void testSubArgImm(int64_t, int64_t);
972 void testSubNeg(int, int);
973 void testNegSub(int, int);
974 void testNegValueSubOne(int);
975 void testSubSub(int, int, int c);
976 void testSubSub2(int, int, int c);
977 void testSubAdd(int, int, int c);
978 void testSubFirstNeg(int, int);
979 void testSubImmArg(int, int);
980 void testSubArgMem(int64_t, int64_t);
981 void testSubMemArg(int64_t, int64_t);
982 void testSubImmMem(int64_t, int64_t);
983 void testSubMemImm(int64_t, int64_t);
984 void testSubArgs32(int, int);
985 void testSubArgImm32(int, int);
986 void testSubImmArg32(int, int);
987 void testSubMemArg32(int32_t, int32_t);
988 void testSubArgMem32(int32_t, int32_t);
989 void testSubImmMem32(int32_t, int32_t);
990 void testSubMemImm32(int32_t, int32_t);
991 void testNegValueSubOne32(int);
992 void testNegMulArgImm(int64_t, int64_t);
993 void testSubMulMulArgs(int64_t, int64_t, int64_t c);
994 void testSubArgDouble(double);
995 void testSubArgsDouble(double, double);
996 void testSubArgImmDouble(double, double);
997 void testSubImmArgDouble(double, double);
998 void testSubImmsDouble(double, double);
999 void testSubArgFloat(float);
1000 void testSubArgsFloat(float, float);
1001 void testSubArgImmFloat(float, float);
1002 void testSubImmArgFloat(float, float);
1003 void testSubImmsFloat(float, float);
1004 void testSubArgFloatWithUselessDoubleConversion(float);
1005 void testSubArgsFloatWithUselessDoubleConversion(float, float);
1006 void testSubArgsFloatWithEffectfulDoubleConversion(float, float);
1007 void testTernarySubInstructionSelection(B3::Opcode valueModifier, Type valueType, Air::Opcode expectedOpcode);
1008 void testNegDouble(double);
1009 void testNegFloat(float);
1010 void testNegFloatWithUselessDoubleConversion(float);
1011
1012 void addArgTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1013 void addBitTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1014 void addCallTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1015 void addSExtTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1016 void addSShrShTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1017 void addShrTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1018 void addAtomicTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1019 void addLoadTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1020 void addTupleTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1021
1022 void testFastForwardCopy32();
1023 void testByteCopyLoop();
1024 void testByteCopyLoopStartIsLoopDependent();
1025 void testByteCopyLoopBoundIsLoopDependent();
1026
1027 void addCopyTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>&);
1028
1029 bool shouldRun(const char* filter, const char* testName);
1030
1031 #endif // ENABLE(B3_JIT)