2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "AirInstInlines.h"
30 #include "AirValidate.h"
31 #include "AllowMacroScratchRegisterUsage.h"
32 #include "B3ArgumentRegValue.h"
33 #include "B3BasicBlockInlines.h"
34 #include "B3CCallValue.h"
35 #include "B3Compilation.h"
36 #include "B3Compile.h"
37 #include "B3ComputeDivisionMagic.h"
38 #include "B3Const32Value.h"
39 #include "B3ConstPtrValue.h"
40 #include "B3Effects.h"
41 #include "B3FenceValue.h"
42 #include "B3Generate.h"
43 #include "B3LowerToAir.h"
44 #include "B3MathExtras.h"
45 #include "B3MemoryValue.h"
46 #include "B3MoveConstants.h"
47 #include "B3Procedure.h"
48 #include "B3ReduceStrength.h"
49 #include "B3SlotBaseValue.h"
50 #include "B3StackSlot.h"
51 #include "B3StackmapGenerationParams.h"
52 #include "B3SwitchValue.h"
53 #include "B3UpsilonValue.h"
54 #include "B3UseCounts.h"
55 #include "B3Validate.h"
56 #include "B3ValueInlines.h"
57 #include "B3VariableValue.h"
58 #include "B3WasmAddressValue.h"
59 #include "B3WasmBoundsCheckValue.h"
60 #include "CCallHelpers.h"
63 #include "InitializeThreading.h"
64 #include "JSCInlines.h"
65 #include "LinkBuffer.h"
70 #include <wtf/ListDump.h>
72 #include <wtf/NumberOfCores.h>
73 #include <wtf/Threading.h>
75 // We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
76 static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
80 dataLog("Usage: testb3 [<filter>]\n");
81 if (hiddenTruthBecauseNoReturnIsStupid())
88 using namespace JSC::B3;
92 bool shouldBeVerbose()
94 return shouldDumpIR(B3Mode);
99 // Nothing fancy for now; we just use the existing WTF assertion machinery.
100 #define CHECK(x) do { \
104 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #x); \
108 #define CHECK_EQ(x, y) do { \
114 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, toCString(#x " == " #y, " (" #x " == ", __x, ", " #y " == ", __y, ")").data()); \
120 std::unique_ptr<Compilation> compile(Procedure& procedure, unsigned optLevel = 1)
122 return std::make_unique<Compilation>(B3::compile(*vm, procedure, optLevel));
125 template<typename T, typename... Arguments>
126 T invoke(MacroAssemblerCodePtr ptr, Arguments... arguments)
128 T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(ptr.executableAddress());
129 return function(arguments...);
132 template<typename T, typename... Arguments>
133 T invoke(const Compilation& code, Arguments... arguments)
135 return invoke<T>(code.code(), arguments...);
138 template<typename T, typename... Arguments>
139 T compileAndRun(Procedure& procedure, Arguments... arguments)
141 return invoke<T>(*compile(procedure), arguments...);
144 void lowerToAirForTesting(Procedure& proc)
146 proc.resetReachability();
148 if (shouldBeVerbose())
149 dataLog("B3 before lowering:\n", proc);
154 if (shouldBeVerbose())
155 dataLog("Air after lowering:\n", proc.code());
157 Air::validate(proc.code());
160 template<typename Func>
161 void checkDisassembly(Compilation& compilation, const Func& func, CString failText)
163 CString disassembly = compilation.disassembly();
164 if (func(disassembly.data()))
168 dataLog("Bad lowering! ", failText, "\n");
169 dataLog(disassembly);
173 void checkUsesInstruction(Compilation& compilation, const char* text)
177 [&] (const char* disassembly) -> bool {
178 return strstr(disassembly, text);
180 toCString("Expected to find ", text, " but didnt!"));
183 void checkDoesNotUseInstruction(Compilation& compilation, const char* text)
187 [&] (const char* disassembly) -> bool {
188 return !strstr(disassembly, text);
190 toCString("Did not expected to find ", text, " but it's there!"));
193 template<typename Type>
199 typedef Operand<int64_t> Int64Operand;
200 typedef Operand<int32_t> Int32Operand;
202 template<typename FloatType>
203 void populateWithInterestingValues(Vector<Operand<FloatType>>& operands)
205 operands.append({ "0.", static_cast<FloatType>(0.) });
206 operands.append({ "-0.", static_cast<FloatType>(-0.) });
207 operands.append({ "0.4", static_cast<FloatType>(0.5) });
208 operands.append({ "-0.4", static_cast<FloatType>(-0.5) });
209 operands.append({ "0.5", static_cast<FloatType>(0.5) });
210 operands.append({ "-0.5", static_cast<FloatType>(-0.5) });
211 operands.append({ "0.6", static_cast<FloatType>(0.5) });
212 operands.append({ "-0.6", static_cast<FloatType>(-0.5) });
213 operands.append({ "1.", static_cast<FloatType>(1.) });
214 operands.append({ "-1.", static_cast<FloatType>(-1.) });
215 operands.append({ "2.", static_cast<FloatType>(2.) });
216 operands.append({ "-2.", static_cast<FloatType>(-2.) });
217 operands.append({ "M_PI", static_cast<FloatType>(M_PI) });
218 operands.append({ "-M_PI", static_cast<FloatType>(-M_PI) });
219 operands.append({ "min", std::numeric_limits<FloatType>::min() });
220 operands.append({ "max", std::numeric_limits<FloatType>::max() });
221 operands.append({ "lowest", std::numeric_limits<FloatType>::lowest() });
222 operands.append({ "epsilon", std::numeric_limits<FloatType>::epsilon() });
223 operands.append({ "infiniti", std::numeric_limits<FloatType>::infinity() });
224 operands.append({ "-infiniti", - std::numeric_limits<FloatType>::infinity() });
225 operands.append({ "PNaN", static_cast<FloatType>(PNaN) });
228 template<typename FloatType>
229 Vector<Operand<FloatType>> floatingPointOperands()
231 Vector<Operand<FloatType>> operands;
232 populateWithInterestingValues(operands);
236 static Vector<Int64Operand> int64Operands()
238 Vector<Int64Operand> operands;
239 operands.append({ "0", 0 });
240 operands.append({ "1", 1 });
241 operands.append({ "-1", -1 });
242 operands.append({ "42", 42 });
243 operands.append({ "-42", -42 });
244 operands.append({ "int64-max", std::numeric_limits<int64_t>::max() });
245 operands.append({ "int64-min", std::numeric_limits<int64_t>::min() });
246 operands.append({ "int32-max", std::numeric_limits<int32_t>::max() });
247 operands.append({ "int32-min", std::numeric_limits<int32_t>::min() });
252 static Vector<Int32Operand> int32Operands()
254 Vector<Int32Operand> operands({
260 { "int32-max", std::numeric_limits<int32_t>::max() },
261 { "int32-min", std::numeric_limits<int32_t>::min() }
266 void add32(CCallHelpers& jit, GPRReg src1, GPRReg src2, GPRReg dest)
269 jit.add32(src1, dest);
271 jit.move(src1, dest);
272 jit.add32(src2, dest);
279 BasicBlock* root = proc.addBlock();
280 Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
281 root->appendNewControlValue(proc, Return, Origin(), const42);
283 CHECK(compileAndRun<int>(proc) == 42);
289 BasicBlock* root = proc.addBlock();
291 root->appendNewControlValue(
292 proc, Return, Origin(),
293 root->appendNew<MemoryValue>(
294 proc, Load, Int32, Origin(),
295 root->appendNew<ConstPtrValue>(proc, Origin(), &x)));
297 CHECK(compileAndRun<int>(proc) == 42);
300 void testLoadWithOffsetImpl(int32_t offset64, int32_t offset32)
304 BasicBlock* root = proc.addBlock();
306 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
307 root->appendNewControlValue(
308 proc, Return, Origin(),
309 root->appendNew<MemoryValue>(
310 proc, Load, Int64, Origin(),
314 char* address = reinterpret_cast<char*>(&x) - offset64;
315 CHECK(compileAndRun<int64_t>(proc, address) == -42);
319 BasicBlock* root = proc.addBlock();
321 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
322 root->appendNewControlValue(
323 proc, Return, Origin(),
324 root->appendNew<MemoryValue>(
325 proc, Load, Int32, Origin(),
329 char* address = reinterpret_cast<char*>(&x) - offset32;
330 CHECK(compileAndRun<int32_t>(proc, address) == -42);
334 void testLoadOffsetImm9Max()
336 testLoadWithOffsetImpl(255, 255);
339 void testLoadOffsetImm9MaxPlusOne()
341 testLoadWithOffsetImpl(256, 256);
344 void testLoadOffsetImm9MaxPlusTwo()
346 testLoadWithOffsetImpl(257, 257);
349 void testLoadOffsetImm9Min()
351 testLoadWithOffsetImpl(-256, -256);
354 void testLoadOffsetImm9MinMinusOne()
356 testLoadWithOffsetImpl(-257, -257);
359 void testLoadOffsetScaledUnsignedImm12Max()
361 testLoadWithOffsetImpl(32760, 16380);
364 void testLoadOffsetScaledUnsignedOverImm12Max()
366 testLoadWithOffsetImpl(32760, 32760);
367 testLoadWithOffsetImpl(32761, 16381);
368 testLoadWithOffsetImpl(32768, 16384);
371 void testArg(int argument)
374 BasicBlock* root = proc.addBlock();
375 root->appendNewControlValue(
376 proc, Return, Origin(),
377 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
379 CHECK(compileAndRun<int>(proc, argument) == argument);
382 void testReturnConst64(int64_t value)
385 BasicBlock* root = proc.addBlock();
386 root->appendNewControlValue(
387 proc, Return, Origin(),
388 root->appendNew<Const64Value>(proc, Origin(), value));
390 CHECK(compileAndRun<int64_t>(proc) == value);
393 void testReturnVoid()
396 BasicBlock* root = proc.addBlock();
397 root->appendNewControlValue(proc, Return, Origin());
398 compileAndRun<void>(proc);
401 void testAddArg(int a)
404 BasicBlock* root = proc.addBlock();
405 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
406 root->appendNewControlValue(
407 proc, Return, Origin(),
408 root->appendNew<Value>(proc, Add, Origin(), value, value));
410 CHECK(compileAndRun<int>(proc, a) == a + a);
413 void testAddArgs(int a, int b)
416 BasicBlock* root = proc.addBlock();
417 root->appendNewControlValue(
418 proc, Return, Origin(),
419 root->appendNew<Value>(
421 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
422 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
424 CHECK(compileAndRun<int>(proc, a, b) == a + b);
427 void testAddArgImm(int a, int b)
430 BasicBlock* root = proc.addBlock();
431 root->appendNewControlValue(
432 proc, Return, Origin(),
433 root->appendNew<Value>(
435 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
436 root->appendNew<Const64Value>(proc, Origin(), b)));
438 CHECK(compileAndRun<int>(proc, a) == a + b);
441 void testAddImmArg(int a, int b)
444 BasicBlock* root = proc.addBlock();
445 root->appendNewControlValue(
446 proc, Return, Origin(),
447 root->appendNew<Value>(
449 root->appendNew<Const64Value>(proc, Origin(), a),
450 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
452 CHECK(compileAndRun<int>(proc, b) == a + b);
455 void testAddArgMem(int64_t a, int64_t b)
458 BasicBlock* root = proc.addBlock();
459 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
460 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
461 Value* result = root->appendNew<Value>(proc, Add, Origin(),
462 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
464 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
465 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
467 int64_t inputOutput = b;
468 CHECK(!compileAndRun<int64_t>(proc, a, &inputOutput));
469 CHECK(inputOutput == a + b);
472 void testAddMemArg(int64_t a, int64_t b)
475 BasicBlock* root = proc.addBlock();
476 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
477 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
478 Value* result = root->appendNew<Value>(proc, Add, Origin(),
480 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
481 root->appendNewControlValue(proc, Return, Origin(), result);
483 CHECK(compileAndRun<int64_t>(proc, &a, b) == a + b);
486 void testAddImmMem(int64_t a, int64_t b)
489 BasicBlock* root = proc.addBlock();
490 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
491 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
492 Value* result = root->appendNew<Value>(proc, Add, Origin(),
493 root->appendNew<Const64Value>(proc, Origin(), a),
495 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
496 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
498 int64_t inputOutput = b;
499 CHECK(!compileAndRun<int>(proc, &inputOutput));
500 CHECK(inputOutput == a + b);
503 void testAddArg32(int a)
506 BasicBlock* root = proc.addBlock();
507 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
508 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
509 root->appendNewControlValue(
510 proc, Return, Origin(),
511 root->appendNew<Value>(proc, Add, Origin(), value, value));
513 CHECK(compileAndRun<int>(proc, a) == a + a);
516 void testAddArgs32(int a, int b)
519 BasicBlock* root = proc.addBlock();
520 root->appendNewControlValue(
521 proc, Return, Origin(),
522 root->appendNew<Value>(
524 root->appendNew<Value>(
525 proc, Trunc, Origin(),
526 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
527 root->appendNew<Value>(
528 proc, Trunc, Origin(),
529 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
531 CHECK(compileAndRun<int>(proc, a, b) == a + b);
534 void testAddArgMem32(int32_t a, int32_t b)
537 BasicBlock* root = proc.addBlock();
538 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
539 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
540 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
541 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
542 Value* result = root->appendNew<Value>(proc, Add, Origin(), argument, load);
543 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
544 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
546 int32_t inputOutput = b;
547 CHECK(!compileAndRun<int32_t>(proc, a, &inputOutput));
548 CHECK(inputOutput == a + b);
551 void testAddMemArg32(int32_t a, int32_t b)
554 BasicBlock* root = proc.addBlock();
555 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
556 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
557 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
558 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
559 Value* result = root->appendNew<Value>(proc, Add, Origin(), load, argument);
560 root->appendNewControlValue(proc, Return, Origin(), result);
562 CHECK(compileAndRun<int32_t>(proc, &a, b) == a + b);
565 void testAddImmMem32(int32_t a, int32_t b)
568 BasicBlock* root = proc.addBlock();
569 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
570 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
571 Value* result = root->appendNew<Value>(proc, Add, Origin(),
572 root->appendNew<Const32Value>(proc, Origin(), a),
574 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
575 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
577 int32_t inputOutput = b;
578 CHECK(!compileAndRun<int>(proc, &inputOutput));
579 CHECK(inputOutput == a + b);
582 void testAddArgZeroImmZDef()
585 BasicBlock* root = proc.addBlock();
586 Value* arg = root->appendNew<Value>(
587 proc, Trunc, Origin(),
588 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
589 Value* constZero = root->appendNew<Const32Value>(proc, Origin(), 0);
590 root->appendNewControlValue(
591 proc, Return, Origin(),
592 root->appendNew<Value>(
597 auto code = compile(proc, 0);
598 CHECK(invoke<int64_t>(*code, 0x0123456789abcdef) == 0x89abcdef);
601 void testAddLoadTwice()
603 auto test = [&] (unsigned optLevel) {
605 BasicBlock* root = proc.addBlock();
607 Value* load = root->appendNew<MemoryValue>(
608 proc, Load, Int32, Origin(),
609 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
610 root->appendNewControlValue(
611 proc, Return, Origin(),
612 root->appendNew<Value>(proc, Add, Origin(), load, load));
614 auto code = compile(proc, optLevel);
615 CHECK(invoke<int32_t>(*code) == 42 * 2);
622 void testAddArgDouble(double a)
625 BasicBlock* root = proc.addBlock();
626 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
627 root->appendNewControlValue(
628 proc, Return, Origin(),
629 root->appendNew<Value>(proc, Add, Origin(), value, value));
631 CHECK(isIdentical(compileAndRun<double>(proc, a), a + a));
634 void testAddArgsDouble(double a, double b)
637 BasicBlock* root = proc.addBlock();
638 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
639 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
640 root->appendNewControlValue(
641 proc, Return, Origin(),
642 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
644 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a + b));
647 void testAddArgImmDouble(double a, double b)
650 BasicBlock* root = proc.addBlock();
651 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
652 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
653 root->appendNewControlValue(
654 proc, Return, Origin(),
655 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
657 CHECK(isIdentical(compileAndRun<double>(proc, a), a + b));
660 void testAddImmArgDouble(double a, double b)
663 BasicBlock* root = proc.addBlock();
664 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
665 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
666 root->appendNewControlValue(
667 proc, Return, Origin(),
668 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
670 CHECK(isIdentical(compileAndRun<double>(proc, b), a + b));
673 void testAddImmsDouble(double a, double b)
676 BasicBlock* root = proc.addBlock();
677 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
678 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
679 root->appendNewControlValue(
680 proc, Return, Origin(),
681 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
683 CHECK(isIdentical(compileAndRun<double>(proc), a + b));
686 void testAddArgFloat(float a)
689 BasicBlock* root = proc.addBlock();
690 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
691 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
692 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
693 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, floatValue);
694 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
695 root->appendNewControlValue(proc, Return, Origin(), result32);
698 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
701 void testAddArgsFloat(float a, float b)
704 BasicBlock* root = proc.addBlock();
705 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
706 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
707 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
708 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
709 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
710 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
711 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue1, floatValue2);
712 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
713 root->appendNewControlValue(proc, Return, Origin(), result32);
715 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
718 void testAddFPRArgsFloat(float a, float b)
721 BasicBlock* root = proc.addBlock();
722 Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
723 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
724 Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
725 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1));
726 Value* result = root->appendNew<Value>(proc, Add, Origin(), argument1, argument2);
727 root->appendNewControlValue(proc, Return, Origin(), result);
729 CHECK(isIdentical(compileAndRun<float>(proc, a, b), a + b));
732 void testAddArgImmFloat(float a, float b)
735 BasicBlock* root = proc.addBlock();
736 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
737 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
738 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
739 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
740 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, constValue);
741 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
742 root->appendNewControlValue(proc, Return, Origin(), result32);
744 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + b)));
747 void testAddImmArgFloat(float a, float b)
750 BasicBlock* root = proc.addBlock();
751 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
752 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
753 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
754 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
755 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue, floatValue);
756 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
757 root->appendNewControlValue(proc, Return, Origin(), result32);
759 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
762 void testAddImmsFloat(float a, float b)
765 BasicBlock* root = proc.addBlock();
766 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
767 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
768 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue1, constValue2);
769 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
770 root->appendNewControlValue(proc, Return, Origin(), result32);
772 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a + b)));
775 void testAddArgFloatWithUselessDoubleConversion(float a)
778 BasicBlock* root = proc.addBlock();
779 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
780 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
781 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
782 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
783 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble, asDouble);
784 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
785 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
786 root->appendNewControlValue(proc, Return, Origin(), result32);
788 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
791 void testAddArgsFloatWithUselessDoubleConversion(float a, float b)
794 BasicBlock* root = proc.addBlock();
795 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
796 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
797 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
798 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
799 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
800 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
801 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
802 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
803 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
804 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
805 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
806 root->appendNewControlValue(proc, Return, Origin(), result32);
808 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
811 void testAddArgsFloatWithEffectfulDoubleConversion(float a, float b)
814 BasicBlock* root = proc.addBlock();
815 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
816 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
817 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
818 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
819 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
820 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
821 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
822 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
823 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
824 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
825 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
826 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
827 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
828 root->appendNewControlValue(proc, Return, Origin(), result32);
831 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a + b)));
832 CHECK(isIdentical(effect, static_cast<double>(a) + static_cast<double>(b)));
835 void testMulArg(int a)
838 BasicBlock* root = proc.addBlock();
839 Value* value = root->appendNew<Value>(
840 proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
841 root->appendNewControlValue(
842 proc, Return, Origin(),
843 root->appendNew<Value>(proc, Mul, Origin(), value, value));
845 CHECK(compileAndRun<int>(proc, a) == a * a);
848 void testMulArgStore(int a)
851 BasicBlock* root = proc.addBlock();
856 Value* value = root->appendNew<Value>(
857 proc, Trunc, Origin(),
858 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
859 Value* mul = root->appendNew<Value>(proc, Mul, Origin(), value, value);
861 root->appendNew<MemoryValue>(
862 proc, Store, Origin(), value,
863 root->appendNew<ConstPtrValue>(proc, Origin(), &valueSlot));
864 root->appendNew<MemoryValue>(
865 proc, Store, Origin(), mul,
866 root->appendNew<ConstPtrValue>(proc, Origin(), &mulSlot));
868 root->appendNewControlValue(
869 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
871 CHECK(!compileAndRun<int>(proc, a));
872 CHECK(mulSlot == a * a);
873 CHECK(valueSlot == a);
876 void testMulAddArg(int a)
879 BasicBlock* root = proc.addBlock();
880 Value* value = root->appendNew<Value>(
881 proc, Trunc, Origin(),
882 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
883 root->appendNewControlValue(
884 proc, Return, Origin(),
885 root->appendNew<Value>(
887 root->appendNew<Value>(proc, Mul, Origin(), value, value),
890 CHECK(compileAndRun<int>(proc, a) == a * a + a);
893 void testMulArgs(int a, int b)
896 BasicBlock* root = proc.addBlock();
897 root->appendNewControlValue(
898 proc, Return, Origin(),
899 root->appendNew<Value>(
901 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
902 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
904 CHECK(compileAndRun<int>(proc, a, b) == a * b);
907 void testMulArgImm(int64_t a, int64_t b)
910 BasicBlock* root = proc.addBlock();
911 root->appendNewControlValue(
912 proc, Return, Origin(),
913 root->appendNew<Value>(
915 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
916 root->appendNew<Const64Value>(proc, Origin(), b)));
918 CHECK(compileAndRun<int64_t>(proc, a) == a * b);
921 void testMulImmArg(int a, int b)
924 BasicBlock* root = proc.addBlock();
925 root->appendNewControlValue(
926 proc, Return, Origin(),
927 root->appendNew<Value>(
929 root->appendNew<Const64Value>(proc, Origin(), a),
930 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
932 CHECK(compileAndRun<int>(proc, b) == a * b);
935 void testMulArgs32(int a, int b)
938 BasicBlock* root = proc.addBlock();
939 root->appendNewControlValue(
940 proc, Return, Origin(),
941 root->appendNew<Value>(
943 root->appendNew<Value>(
944 proc, Trunc, Origin(),
945 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
946 root->appendNew<Value>(
947 proc, Trunc, Origin(),
948 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
950 CHECK(compileAndRun<int>(proc, a, b) == a * b);
953 void testMulLoadTwice()
955 auto test = [&] (unsigned optLevel) {
957 BasicBlock* root = proc.addBlock();
959 Value* load = root->appendNew<MemoryValue>(
960 proc, Load, Int32, Origin(),
961 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
962 root->appendNewControlValue(
963 proc, Return, Origin(),
964 root->appendNew<Value>(proc, Mul, Origin(), load, load));
966 auto code = compile(proc, optLevel);
967 CHECK(invoke<int32_t>(*code) == 42 * 42);
974 void testMulAddArgsLeft()
977 BasicBlock* root = proc.addBlock();
979 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
980 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
981 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
982 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
983 Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
984 root->appendNewControlValue(proc, Return, Origin(), added);
986 auto code = compile(proc);
988 auto testValues = int64Operands();
989 for (auto a : testValues) {
990 for (auto b : testValues) {
991 for (auto c : testValues) {
992 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
998 void testMulAddArgsRight()
1001 BasicBlock* root = proc.addBlock();
1003 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1004 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1005 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1006 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1007 Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
1008 root->appendNewControlValue(proc, Return, Origin(), added);
1010 auto code = compile(proc);
1012 auto testValues = int64Operands();
1013 for (auto a : testValues) {
1014 for (auto b : testValues) {
1015 for (auto c : testValues) {
1016 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
1022 void testMulAddArgsLeft32()
1025 BasicBlock* root = proc.addBlock();
1027 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1028 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1029 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1030 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1031 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1032 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1033 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1034 Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
1035 root->appendNewControlValue(proc, Return, Origin(), added);
1037 auto code = compile(proc);
1039 auto testValues = int32Operands();
1040 for (auto a : testValues) {
1041 for (auto b : testValues) {
1042 for (auto c : testValues) {
1043 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
1049 void testMulAddArgsRight32()
1052 BasicBlock* root = proc.addBlock();
1054 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1055 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1056 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1057 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1058 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1059 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1060 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1061 Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
1062 root->appendNewControlValue(proc, Return, Origin(), added);
1064 auto code = compile(proc);
1066 auto testValues = int32Operands();
1067 for (auto a : testValues) {
1068 for (auto b : testValues) {
1069 for (auto c : testValues) {
1070 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
1076 void testMulSubArgsLeft()
1079 BasicBlock* root = proc.addBlock();
1081 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1082 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1083 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1084 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1085 Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
1086 root->appendNewControlValue(proc, Return, Origin(), added);
1088 auto code = compile(proc);
1090 auto testValues = int64Operands();
1091 for (auto a : testValues) {
1092 for (auto b : testValues) {
1093 for (auto c : testValues) {
1094 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
1100 void testMulSubArgsRight()
1103 BasicBlock* root = proc.addBlock();
1105 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1106 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1107 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1108 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1109 Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
1110 root->appendNewControlValue(proc, Return, Origin(), added);
1112 auto code = compile(proc);
1114 auto testValues = int64Operands();
1115 for (auto a : testValues) {
1116 for (auto b : testValues) {
1117 for (auto c : testValues) {
1118 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
1124 void testMulSubArgsLeft32()
1127 BasicBlock* root = proc.addBlock();
1129 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1130 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1131 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1132 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1133 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1134 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1135 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1136 Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
1137 root->appendNewControlValue(proc, Return, Origin(), added);
1139 auto code = compile(proc);
1141 auto testValues = int32Operands();
1142 for (auto a : testValues) {
1143 for (auto b : testValues) {
1144 for (auto c : testValues) {
1145 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
1151 void testMulSubArgsRight32()
1154 BasicBlock* root = proc.addBlock();
1156 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1157 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1158 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1159 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1160 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1161 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1162 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1163 Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
1164 root->appendNewControlValue(proc, Return, Origin(), added);
1166 auto code = compile(proc);
1168 auto testValues = int32Operands();
1169 for (auto a : testValues) {
1170 for (auto b : testValues) {
1171 for (auto c : testValues) {
1172 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
1178 void testMulNegArgs()
1181 BasicBlock* root = proc.addBlock();
1183 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1184 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1185 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1186 Value* zero = root->appendNew<Const64Value>(proc, Origin(), 0);
1187 Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
1188 root->appendNewControlValue(proc, Return, Origin(), added);
1190 auto code = compile(proc);
1192 auto testValues = int64Operands();
1193 for (auto a : testValues) {
1194 for (auto b : testValues) {
1195 CHECK(invoke<int64_t>(*code, a.value, b.value) == -(a.value * b.value));
1200 void testMulNegArgs32()
1203 BasicBlock* root = proc.addBlock();
1205 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1206 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1207 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1208 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1209 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1210 Value* zero = root->appendNew<Const32Value>(proc, Origin(), 0);
1211 Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
1212 root->appendNewControlValue(proc, Return, Origin(), added);
1214 auto code = compile(proc);
1216 auto testValues = int32Operands();
1217 for (auto a : testValues) {
1218 for (auto b : testValues) {
1219 CHECK(invoke<int32_t>(*code, a.value, b.value) == -(a.value * b.value));
1224 void testMulArgDouble(double a)
1227 BasicBlock* root = proc.addBlock();
1228 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1229 root->appendNewControlValue(
1230 proc, Return, Origin(),
1231 root->appendNew<Value>(proc, Mul, Origin(), value, value));
1233 CHECK(isIdentical(compileAndRun<double>(proc, a), a * a));
1236 void testMulArgsDouble(double a, double b)
1239 BasicBlock* root = proc.addBlock();
1240 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1241 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1242 root->appendNewControlValue(
1243 proc, Return, Origin(),
1244 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1246 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a * b));
1249 void testMulArgImmDouble(double a, double b)
1252 BasicBlock* root = proc.addBlock();
1253 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1254 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1255 root->appendNewControlValue(
1256 proc, Return, Origin(),
1257 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1259 CHECK(isIdentical(compileAndRun<double>(proc, a), a * b));
1262 void testMulImmArgDouble(double a, double b)
1265 BasicBlock* root = proc.addBlock();
1266 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1267 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1268 root->appendNewControlValue(
1269 proc, Return, Origin(),
1270 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1272 CHECK(isIdentical(compileAndRun<double>(proc, b), a * b));
1275 void testMulImmsDouble(double a, double b)
1278 BasicBlock* root = proc.addBlock();
1279 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1280 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1281 root->appendNewControlValue(
1282 proc, Return, Origin(),
1283 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1285 CHECK(isIdentical(compileAndRun<double>(proc), a * b));
1288 void testMulArgFloat(float a)
1291 BasicBlock* root = proc.addBlock();
1292 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1293 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1294 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1295 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, floatValue);
1296 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1297 root->appendNewControlValue(proc, Return, Origin(), result32);
1300 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
1303 void testMulArgsFloat(float a, float b)
1306 BasicBlock* root = proc.addBlock();
1307 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1308 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1309 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1310 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1311 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1312 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1313 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue1, floatValue2);
1314 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1315 root->appendNewControlValue(proc, Return, Origin(), result32);
1317 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1320 void testMulArgImmFloat(float a, float b)
1323 BasicBlock* root = proc.addBlock();
1324 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1325 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1326 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1327 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1328 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, constValue);
1329 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1330 root->appendNewControlValue(proc, Return, Origin(), result32);
1332 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * b)));
1335 void testMulImmArgFloat(float a, float b)
1338 BasicBlock* root = proc.addBlock();
1339 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1340 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1341 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1342 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1343 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue, floatValue);
1344 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1345 root->appendNewControlValue(proc, Return, Origin(), result32);
1347 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1350 void testMulImmsFloat(float a, float b)
1353 BasicBlock* root = proc.addBlock();
1354 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1355 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1356 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue1, constValue2);
1357 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1358 root->appendNewControlValue(proc, Return, Origin(), result32);
1360 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a * b)));
1363 void testMulArgFloatWithUselessDoubleConversion(float a)
1366 BasicBlock* root = proc.addBlock();
1367 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1368 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1369 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1370 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1371 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble, asDouble);
1372 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1373 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1374 root->appendNewControlValue(proc, Return, Origin(), result32);
1376 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
1379 void testMulArgsFloatWithUselessDoubleConversion(float a, float b)
1382 BasicBlock* root = proc.addBlock();
1383 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1384 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1385 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1386 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1387 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1388 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1389 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1390 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1391 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
1392 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1393 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1394 root->appendNewControlValue(proc, Return, Origin(), result32);
1396 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1399 void testMulArgsFloatWithEffectfulDoubleConversion(float a, float b)
1402 BasicBlock* root = proc.addBlock();
1403 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1404 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1405 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1406 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1407 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1408 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1409 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1410 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1411 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
1412 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1413 Value* doubleMulress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1414 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleMulress);
1415 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1416 root->appendNewControlValue(proc, Return, Origin(), result32);
1419 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a * b)));
1420 CHECK(isIdentical(effect, static_cast<double>(a) * static_cast<double>(b)));
1423 void testDivArgDouble(double a)
1426 BasicBlock* root = proc.addBlock();
1427 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1428 root->appendNewControlValue(
1429 proc, Return, Origin(),
1430 root->appendNew<Value>(proc, Div, Origin(), value, value));
1432 CHECK(isIdentical(compileAndRun<double>(proc, a), a / a));
1435 void testDivArgsDouble(double a, double b)
1438 BasicBlock* root = proc.addBlock();
1439 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1440 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1441 root->appendNewControlValue(
1442 proc, Return, Origin(),
1443 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1445 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a / b));
1448 void testDivArgImmDouble(double a, double b)
1451 BasicBlock* root = proc.addBlock();
1452 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1453 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1454 root->appendNewControlValue(
1455 proc, Return, Origin(),
1456 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1458 CHECK(isIdentical(compileAndRun<double>(proc, a), a / b));
1461 void testDivImmArgDouble(double a, double b)
1464 BasicBlock* root = proc.addBlock();
1465 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1466 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1467 root->appendNewControlValue(
1468 proc, Return, Origin(),
1469 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1471 CHECK(isIdentical(compileAndRun<double>(proc, b), a / b));
1474 void testDivImmsDouble(double a, double b)
1477 BasicBlock* root = proc.addBlock();
1478 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1479 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1480 root->appendNewControlValue(
1481 proc, Return, Origin(),
1482 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1484 CHECK(isIdentical(compileAndRun<double>(proc), a / b));
1487 void testDivArgFloat(float a)
1490 BasicBlock* root = proc.addBlock();
1491 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1492 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1493 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1494 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, floatValue);
1495 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1496 root->appendNewControlValue(proc, Return, Origin(), result32);
1499 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1502 void testDivArgsFloat(float a, float b)
1505 BasicBlock* root = proc.addBlock();
1506 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1507 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1508 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1509 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1510 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1511 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1512 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue1, floatValue2);
1513 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1514 root->appendNewControlValue(proc, Return, Origin(), result32);
1516 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1519 void testDivArgImmFloat(float a, float b)
1522 BasicBlock* root = proc.addBlock();
1523 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1524 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1525 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1526 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1527 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, constValue);
1528 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1529 root->appendNewControlValue(proc, Return, Origin(), result32);
1531 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / b)));
1534 void testDivImmArgFloat(float a, float b)
1537 BasicBlock* root = proc.addBlock();
1538 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1539 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1540 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1541 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1542 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue, floatValue);
1543 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1544 root->appendNewControlValue(proc, Return, Origin(), result32);
1546 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1549 void testDivImmsFloat(float a, float b)
1552 BasicBlock* root = proc.addBlock();
1553 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1554 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1555 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue1, constValue2);
1556 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1557 root->appendNewControlValue(proc, Return, Origin(), result32);
1559 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a / b)));
1562 void testModArgDouble(double a)
1565 BasicBlock* root = proc.addBlock();
1566 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1567 root->appendNewControlValue(
1568 proc, Return, Origin(),
1569 root->appendNew<Value>(proc, Mod, Origin(), value, value));
1571 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, a)));
1574 void testModArgsDouble(double a, double b)
1577 BasicBlock* root = proc.addBlock();
1578 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1579 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1580 root->appendNewControlValue(
1581 proc, Return, Origin(),
1582 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1584 CHECK(isIdentical(compileAndRun<double>(proc, a, b), fmod(a, b)));
1587 void testModArgImmDouble(double a, double b)
1590 BasicBlock* root = proc.addBlock();
1591 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1592 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1593 root->appendNewControlValue(
1594 proc, Return, Origin(),
1595 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1597 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, b)));
1600 void testModImmArgDouble(double a, double b)
1603 BasicBlock* root = proc.addBlock();
1604 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1605 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1606 root->appendNewControlValue(
1607 proc, Return, Origin(),
1608 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1610 CHECK(isIdentical(compileAndRun<double>(proc, b), fmod(a, b)));
1613 void testModImmsDouble(double a, double b)
1616 BasicBlock* root = proc.addBlock();
1617 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1618 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1619 root->appendNewControlValue(
1620 proc, Return, Origin(),
1621 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1623 CHECK(isIdentical(compileAndRun<double>(proc), fmod(a, b)));
1626 void testModArgFloat(float a)
1629 BasicBlock* root = proc.addBlock();
1630 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1631 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1632 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1633 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, floatValue);
1634 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1635 root->appendNewControlValue(proc, Return, Origin(), result32);
1638 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, a)))));
1641 void testModArgsFloat(float a, float b)
1644 BasicBlock* root = proc.addBlock();
1645 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1646 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1647 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1648 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1649 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1650 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1651 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue1, floatValue2);
1652 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1653 root->appendNewControlValue(proc, Return, Origin(), result32);
1655 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1658 void testModArgImmFloat(float a, float b)
1661 BasicBlock* root = proc.addBlock();
1662 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1663 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1664 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1665 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1666 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, constValue);
1667 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1668 root->appendNewControlValue(proc, Return, Origin(), result32);
1670 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1673 void testModImmArgFloat(float a, float b)
1676 BasicBlock* root = proc.addBlock();
1677 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1678 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1679 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1680 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1681 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue, floatValue);
1682 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1683 root->appendNewControlValue(proc, Return, Origin(), result32);
1685 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1688 void testModImmsFloat(float a, float b)
1691 BasicBlock* root = proc.addBlock();
1692 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1693 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1694 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue1, constValue2);
1695 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1696 root->appendNewControlValue(proc, Return, Origin(), result32);
1698 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1701 void testDivArgFloatWithUselessDoubleConversion(float a)
1704 BasicBlock* root = proc.addBlock();
1705 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1706 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1707 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1708 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1709 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble, asDouble);
1710 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1711 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1712 root->appendNewControlValue(proc, Return, Origin(), result32);
1714 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1717 void testDivArgsFloatWithUselessDoubleConversion(float a, float b)
1720 BasicBlock* root = proc.addBlock();
1721 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1722 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1723 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1724 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1725 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1726 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1727 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1728 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1729 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1730 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1731 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1732 root->appendNewControlValue(proc, Return, Origin(), result32);
1734 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1737 void testDivArgsFloatWithEffectfulDoubleConversion(float a, float b)
1740 BasicBlock* root = proc.addBlock();
1741 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1742 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1743 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1744 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1745 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1746 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1747 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1748 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1749 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1750 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1751 Value* doubleDivress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1752 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleDivress);
1753 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1754 root->appendNewControlValue(proc, Return, Origin(), result32);
1757 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a / b)));
1758 CHECK(isIdentical(effect, static_cast<double>(a) / static_cast<double>(b)));
1761 void testUDivArgsInt32(uint32_t a, uint32_t b)
1763 // UDiv with denominator == 0 is invalid.
1768 BasicBlock* root = proc.addBlock();
1769 Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
1770 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1771 Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
1772 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1773 Value* result = root->appendNew<Value>(proc, UDiv, Origin(), argument1, argument2);
1774 root->appendNew<Value>(proc, Return, Origin(), result);
1776 CHECK_EQ(compileAndRun<uint32_t>(proc, a, b), a / b);
1779 void testUDivArgsInt64(uint64_t a, uint64_t b)
1781 // UDiv with denominator == 0 is invalid.
1786 BasicBlock* root = proc.addBlock();
1787 Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1788 Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1789 Value* result = root->appendNew<Value>(proc, UDiv, Origin(), argument1, argument2);
1790 root->appendNew<Value>(proc, Return, Origin(), result);
1792 CHECK_EQ(compileAndRun<uint64_t>(proc, a, b), a / b);
1795 void testUModArgsInt32(uint32_t a, uint32_t b)
1797 // UMod with denominator == 0 is invalid.
1802 BasicBlock* root = proc.addBlock();
1803 Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
1804 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1805 Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
1806 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1807 Value* result = root->appendNew<Value>(proc, UMod, Origin(), argument1, argument2);
1808 root->appendNew<Value>(proc, Return, Origin(), result);
1810 CHECK_EQ(compileAndRun<uint32_t>(proc, a, b), a % b);
1813 void testUModArgsInt64(uint64_t a, uint64_t b)
1815 // UMod with denominator == 0 is invalid.
1820 BasicBlock* root = proc.addBlock();
1821 Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1822 Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1823 Value* result = root->appendNew<Value>(proc, UMod, Origin(), argument1, argument2);
1824 root->appendNew<Value>(proc, Return, Origin(), result);
1826 CHECK_EQ(compileAndRun<uint64_t>(proc, a, b), a % b);
1829 void testSubArg(int a)
1832 BasicBlock* root = proc.addBlock();
1833 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1834 root->appendNewControlValue(
1835 proc, Return, Origin(),
1836 root->appendNew<Value>(proc, Sub, Origin(), value, value));
1838 CHECK(!compileAndRun<int>(proc, a));
1841 void testSubArgs(int a, int b)
1844 BasicBlock* root = proc.addBlock();
1845 root->appendNewControlValue(
1846 proc, Return, Origin(),
1847 root->appendNew<Value>(
1848 proc, Sub, Origin(),
1849 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1850 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
1852 CHECK(compileAndRun<int>(proc, a, b) == a - b);
1855 void testSubArgImm(int64_t a, int64_t b)
1858 BasicBlock* root = proc.addBlock();
1859 root->appendNewControlValue(
1860 proc, Return, Origin(),
1861 root->appendNew<Value>(
1862 proc, Sub, Origin(),
1863 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1864 root->appendNew<Const64Value>(proc, Origin(), b)));
1866 CHECK(compileAndRun<int64_t>(proc, a) == a - b);
1869 void testNegValueSubOne(int a)
1872 BasicBlock* root = proc.addBlock();
1873 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1874 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
1875 root->appendNew<Const64Value>(proc, Origin(), 0),
1877 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
1879 root->appendNew<Const64Value>(proc, Origin(), 1));
1880 root->appendNewControlValue(proc, Return, Origin(), negArgumentMinusOne);
1881 CHECK(compileAndRun<int>(proc, a) == -a - 1);
1884 void testSubImmArg(int a, int b)
1887 BasicBlock* root = proc.addBlock();
1888 root->appendNewControlValue(
1889 proc, Return, Origin(),
1890 root->appendNew<Value>(
1891 proc, Sub, Origin(),
1892 root->appendNew<Const64Value>(proc, Origin(), a),
1893 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1895 CHECK(compileAndRun<int>(proc, b) == a - b);
1898 void testSubArgMem(int64_t a, int64_t b)
1901 BasicBlock* root = proc.addBlock();
1902 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1903 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1904 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1905 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1907 root->appendNewControlValue(proc, Return, Origin(), result);
1909 CHECK(compileAndRun<int64_t>(proc, a, &b) == a - b);
1912 void testSubMemArg(int64_t a, int64_t b)
1915 BasicBlock* root = proc.addBlock();
1916 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1917 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1918 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1920 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1921 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1922 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1924 int64_t inputOutput = a;
1925 CHECK(!compileAndRun<int64_t>(proc, &inputOutput, b));
1926 CHECK(inputOutput == a - b);
1929 void testSubImmMem(int64_t a, int64_t b)
1932 BasicBlock* root = proc.addBlock();
1933 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1934 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1935 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1936 root->appendNew<Const64Value>(proc, Origin(), a),
1938 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1939 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1941 int64_t inputOutput = b;
1942 CHECK(!compileAndRun<int>(proc, &inputOutput));
1943 CHECK(inputOutput == a - b);
1946 void testSubMemImm(int64_t a, int64_t b)
1949 BasicBlock* root = proc.addBlock();
1950 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1951 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1952 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1954 root->appendNew<Const64Value>(proc, Origin(), b));
1955 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1956 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1958 int64_t inputOutput = a;
1959 CHECK(!compileAndRun<int>(proc, &inputOutput));
1960 CHECK(inputOutput == a - b);
1964 void testSubArgs32(int a, int b)
1967 BasicBlock* root = proc.addBlock();
1968 root->appendNewControlValue(
1969 proc, Return, Origin(),
1970 root->appendNew<Value>(
1971 proc, Sub, Origin(),
1972 root->appendNew<Value>(
1973 proc, Trunc, Origin(),
1974 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1975 root->appendNew<Value>(
1976 proc, Trunc, Origin(),
1977 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1979 CHECK(compileAndRun<int>(proc, a, b) == a - b);
1982 void testSubArgImm32(int a, int b)
1985 BasicBlock* root = proc.addBlock();
1986 root->appendNewControlValue(
1987 proc, Return, Origin(),
1988 root->appendNew<Value>(
1989 proc, Sub, Origin(),
1990 root->appendNew<Value>(
1991 proc, Trunc, Origin(),
1992 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1993 root->appendNew<Const32Value>(proc, Origin(), b)));
1995 CHECK(compileAndRun<int>(proc, a) == a - b);
1998 void testSubImmArg32(int a, int b)
2001 BasicBlock* root = proc.addBlock();
2002 root->appendNewControlValue(
2003 proc, Return, Origin(),
2004 root->appendNew<Value>(
2005 proc, Sub, Origin(),
2006 root->appendNew<Const32Value>(proc, Origin(), a),
2007 root->appendNew<Value>(
2008 proc, Trunc, Origin(),
2009 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2011 CHECK(compileAndRun<int>(proc, b) == a - b);
2014 void testSubMemArg32(int32_t a, int32_t b)
2017 BasicBlock* root = proc.addBlock();
2018 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2019 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2020 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2021 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2022 Value* result = root->appendNew<Value>(proc, Sub, Origin(), load, argument);
2023 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2024 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2026 int32_t inputOutput = a;
2027 CHECK(!compileAndRun<int32_t>(proc, &inputOutput, b));
2028 CHECK(inputOutput == a - b);
2031 void testSubArgMem32(int32_t a, int32_t b)
2034 BasicBlock* root = proc.addBlock();
2035 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2036 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2037 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2038 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2039 Value* result = root->appendNew<Value>(proc, Sub, Origin(), argument, load);
2040 root->appendNewControlValue(proc, Return, Origin(), result);
2042 CHECK(compileAndRun<int32_t>(proc, a, &b) == a - b);
2045 void testSubImmMem32(int32_t a, int32_t b)
2048 BasicBlock* root = proc.addBlock();
2049 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2050 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2051 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2052 root->appendNew<Const32Value>(proc, Origin(), a),
2054 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2055 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2057 int32_t inputOutput = b;
2058 CHECK(!compileAndRun<int>(proc, &inputOutput));
2059 CHECK(inputOutput == a - b);
2062 void testSubMemImm32(int32_t a, int32_t b)
2065 BasicBlock* root = proc.addBlock();
2066 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2067 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2068 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2070 root->appendNew<Const32Value>(proc, Origin(), b));
2071 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2072 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2074 int32_t inputOutput = a;
2075 CHECK(!compileAndRun<int>(proc, &inputOutput));
2076 CHECK(inputOutput == a - b);
2079 void testNegValueSubOne32(int a)
2082 BasicBlock* root = proc.addBlock();
2083 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2084 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2085 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
2086 root->appendNew<Const32Value>(proc, Origin(), 0),
2088 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
2090 root->appendNew<Const32Value>(proc, Origin(), 1));
2091 root->appendNewControlValue(proc, Return, Origin(), negArgumentMinusOne);
2092 CHECK(compileAndRun<int>(proc, a) == -a - 1);
2095 void testSubArgDouble(double a)
2098 BasicBlock* root = proc.addBlock();
2099 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2100 root->appendNewControlValue(
2101 proc, Return, Origin(),
2102 root->appendNew<Value>(proc, Sub, Origin(), value, value));
2104 CHECK(isIdentical(compileAndRun<double>(proc, a), a - a));
2107 void testSubArgsDouble(double a, double b)
2110 BasicBlock* root = proc.addBlock();
2111 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2112 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
2113 root->appendNewControlValue(
2114 proc, Return, Origin(),
2115 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2117 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a - b));
2120 void testSubArgImmDouble(double a, double b)
2123 BasicBlock* root = proc.addBlock();
2124 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2125 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2126 root->appendNewControlValue(
2127 proc, Return, Origin(),
2128 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2130 CHECK(isIdentical(compileAndRun<double>(proc, a), a - b));
2133 void testSubImmArgDouble(double a, double b)
2136 BasicBlock* root = proc.addBlock();
2137 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2138 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2139 root->appendNewControlValue(
2140 proc, Return, Origin(),
2141 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2143 CHECK(isIdentical(compileAndRun<double>(proc, b), a - b));
2146 void testSubImmsDouble(double a, double b)
2149 BasicBlock* root = proc.addBlock();
2150 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2151 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2152 root->appendNewControlValue(
2153 proc, Return, Origin(),
2154 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2156 CHECK(isIdentical(compileAndRun<double>(proc), a - b));
2159 void testSubArgFloat(float a)
2162 BasicBlock* root = proc.addBlock();
2163 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2164 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2165 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2166 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, floatValue);
2167 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2168 root->appendNewControlValue(proc, Return, Origin(), result32);
2171 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
2174 void testSubArgsFloat(float a, float b)
2177 BasicBlock* root = proc.addBlock();
2178 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2179 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2180 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2181 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2182 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2183 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2184 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue1, floatValue2);
2185 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2186 root->appendNewControlValue(proc, Return, Origin(), result32);
2188 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2191 void testSubArgImmFloat(float a, float b)
2194 BasicBlock* root = proc.addBlock();
2195 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2196 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2197 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2198 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2199 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, constValue);
2200 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2201 root->appendNewControlValue(proc, Return, Origin(), result32);
2203 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - b)));
2206 void testSubImmArgFloat(float a, float b)
2209 BasicBlock* root = proc.addBlock();
2210 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2211 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2212 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2213 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2214 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue, floatValue);
2215 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2216 root->appendNewControlValue(proc, Return, Origin(), result32);
2218 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2221 void testSubImmsFloat(float a, float b)
2224 BasicBlock* root = proc.addBlock();
2225 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2226 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2227 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue1, constValue2);
2228 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2229 root->appendNewControlValue(proc, Return, Origin(), result32);
2231 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a - b)));
2234 void testSubArgFloatWithUselessDoubleConversion(float a)
2237 BasicBlock* root = proc.addBlock();
2238 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
2239 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2240 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
2241 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2242 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble, asDouble);
2243 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2244 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2245 root->appendNewControlValue(proc, Return, Origin(), result32);
2247 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
2250 void testSubArgsFloatWithUselessDoubleConversion(float a, float b)
2253 BasicBlock* root = proc.addBlock();
2254 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2255 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2256 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2257 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2258 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2259 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2260 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
2261 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
2262 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
2263 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2264 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2265 root->appendNewControlValue(proc, Return, Origin(), result32);
2267 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2270 void testSubArgsFloatWithEffectfulDoubleConversion(float a, float b)
2273 BasicBlock* root = proc.addBlock();
2274 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2275 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2276 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2277 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2278 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2279 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2280 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
2281 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
2282 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
2283 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2284 Value* doubleSubress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2285 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleSubress);
2286 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2287 root->appendNewControlValue(proc, Return, Origin(), result32);
2290 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a - b)));
2291 CHECK(isIdentical(effect, static_cast<double>(a) - static_cast<double>(b)));
2294 void testTernarySubInstructionSelection(B3::Opcode valueModifier, Type valueType, Air::Opcode expectedOpcode)
2297 BasicBlock* root = proc.addBlock();
2299 Value* left = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2300 Value* right = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2302 if (valueModifier == Trunc) {
2303 left = root->appendNew<Value>(proc, valueModifier, valueType, Origin(), left);
2304 right = root->appendNew<Value>(proc, valueModifier, valueType, Origin(), right);
2307 root->appendNewControlValue(
2308 proc, Return, Origin(),
2309 root->appendNew<Value>(proc, Sub, Origin(), left, right));
2311 lowerToAirForTesting(proc);
2313 auto block = proc.code()[0];
2314 unsigned numberOfSubInstructions = 0;
2315 for (auto instruction : *block) {
2316 if (instruction.kind.opcode == expectedOpcode) {
2317 CHECK_EQ(instruction.args.size(), 3ul);
2318 CHECK_EQ(instruction.args[0].kind(), Air::Arg::Tmp);
2319 CHECK_EQ(instruction.args[1].kind(), Air::Arg::Tmp);
2320 CHECK_EQ(instruction.args[2].kind(), Air::Arg::Tmp);
2321 numberOfSubInstructions++;
2324 CHECK_EQ(numberOfSubInstructions, 1ul);
2327 void testNegDouble(double a)
2330 BasicBlock* root = proc.addBlock();
2331 root->appendNewControlValue(
2332 proc, Return, Origin(),
2333 root->appendNew<Value>(
2334 proc, Neg, Origin(),
2335 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
2337 CHECK(isIdentical(compileAndRun<double>(proc, a), -a));
2340 void testNegFloat(float a)
2343 BasicBlock* root = proc.addBlock();
2344 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2345 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2346 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2347 root->appendNewControlValue(
2348 proc, Return, Origin(),
2349 root->appendNew<Value>(proc, Neg, Origin(), floatValue));
2351 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), -a));
2354 void testNegFloatWithUselessDoubleConversion(float a)
2357 BasicBlock* root = proc.addBlock();
2358 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
2359 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2360 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
2361 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2362 Value* result = root->appendNew<Value>(proc, Neg, Origin(), asDouble);
2363 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2364 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2366 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), -a));
2369 void testBitAndArgs(int64_t a, int64_t b)
2372 BasicBlock* root = proc.addBlock();
2373 root->appendNewControlValue(
2374 proc, Return, Origin(),
2375 root->appendNew<Value>(
2376 proc, BitAnd, Origin(),
2377 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2378 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2380 CHECK(compileAndRun<int64_t>(proc, a, b) == (a & b));
2383 void testBitAndSameArg(int64_t a)
2386 BasicBlock* root = proc.addBlock();
2387 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2388 root->appendNewControlValue(
2389 proc, Return, Origin(),
2390 root->appendNew<Value>(
2391 proc, BitAnd, Origin(),
2395 CHECK(compileAndRun<int64_t>(proc, a) == a);
2398 void testBitAndImms(int64_t a, int64_t b)
2401 BasicBlock* root = proc.addBlock();
2402 root->appendNewControlValue(
2403 proc, Return, Origin(),
2404 root->appendNew<Value>(
2405 proc, BitAnd, Origin(),
2406 root->appendNew<Const64Value>(proc, Origin(), a),
2407 root->appendNew<Const64Value>(proc, Origin(), b)));
2409 CHECK(compileAndRun<int64_t>(proc) == (a & b));
2412 void testBitAndArgImm(int64_t a, int64_t b)
2415 BasicBlock* root = proc.addBlock();
2416 root->appendNewControlValue(
2417 proc, Return, Origin(),
2418 root->appendNew<Value>(
2419 proc, BitAnd, Origin(),
2420 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2421 root->appendNew<Const64Value>(proc, Origin(), b)));
2423 CHECK(compileAndRun<int64_t>(proc, a) == (a & b));
2426 void testBitAndImmArg(int64_t a, int64_t b)
2429 BasicBlock* root = proc.addBlock();
2430 root->appendNewControlValue(
2431 proc, Return, Origin(),
2432 root->appendNew<Value>(
2433 proc, BitAnd, Origin(),
2434 root->appendNew<Const64Value>(proc, Origin(), a),
2435 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2437 CHECK(compileAndRun<int64_t>(proc, b) == (a & b));
2440 void testBitAndBitAndArgImmImm(int64_t a, int64_t b, int64_t c)
2443 BasicBlock* root = proc.addBlock();
2444 Value* innerBitAnd = root->appendNew<Value>(
2445 proc, BitAnd, Origin(),
2446 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2447 root->appendNew<Const64Value>(proc, Origin(), b));
2448 root->appendNewControlValue(
2449 proc, Return, Origin(),
2450 root->appendNew<Value>(
2451 proc, BitAnd, Origin(),
2453 root->appendNew<Const64Value>(proc, Origin(), c)));
2455 CHECK(compileAndRun<int64_t>(proc, a) == ((a & b) & c));
2458 void testBitAndImmBitAndArgImm(int64_t a, int64_t b, int64_t c)
2461 BasicBlock* root = proc.addBlock();
2462 Value* innerBitAnd = root->appendNew<Value>(
2463 proc, BitAnd, Origin(),
2464 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2465 root->appendNew<Const64Value>(proc, Origin(), c));
2466 root->appendNewControlValue(
2467 proc, Return, Origin(),
2468 root->appendNew<Value>(
2469 proc, BitAnd, Origin(),
2470 root->appendNew<Const64Value>(proc, Origin(), a),
2473 CHECK(compileAndRun<int64_t>(proc, b) == (a & (b & c)));
2476 void testBitAndArgs32(int a, int b)
2479 BasicBlock* root = proc.addBlock();
2480 root->appendNewControlValue(
2481 proc, Return, Origin(),
2482 root->appendNew<Value>(
2483 proc, BitAnd, Origin(),
2484 root->appendNew<Value>(
2485 proc, Trunc, Origin(),
2486 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2487 root->appendNew<Value>(
2488 proc, Trunc, Origin(),
2489 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2491 CHECK(compileAndRun<int>(proc, a, b) == (a & b));
2494 void testBitAndSameArg32(int a)
2497 BasicBlock* root = proc.addBlock();
2498 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2499 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2500 root->appendNewControlValue(
2501 proc, Return, Origin(),
2502 root->appendNew<Value>(
2503 proc, BitAnd, Origin(),
2507 CHECK(compileAndRun<int>(proc, a) == a);
2510 void testBitAndImms32(int a, int b)
2513 BasicBlock* root = proc.addBlock();
2514 root->appendNewControlValue(
2515 proc, Return, Origin(),
2516 root->appendNew<Value>(
2517 proc, BitAnd, Origin(),
2518 root->appendNew<Const32Value>(proc, Origin(), a),
2519 root->appendNew<Const32Value>(proc, Origin(), b)));
2521 CHECK(compileAndRun<int>(proc) == (a & b));
2524 void testBitAndArgImm32(int a, int b)
2527 BasicBlock* root = proc.addBlock();
2528 root->appendNewControlValue(
2529 proc, Return, Origin(),
2530 root->appendNew<Value>(
2531 proc, BitAnd, Origin(),
2532 root->appendNew<Value>(
2533 proc, Trunc, Origin(),
2534 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2535 root->appendNew<Const32Value>(proc, Origin(), b)));
2537 CHECK(compileAndRun<int>(proc, a) == (a & b));
2540 void testBitAndImmArg32(int a, int b)
2543 BasicBlock* root = proc.addBlock();
2544 root->appendNewControlValue(
2545 proc, Return, Origin(),
2546 root->appendNew<Value>(
2547 proc, BitAnd, Origin(),
2548 root->appendNew<Const32Value>(proc, Origin(), a),
2549 root->appendNew<Value>(
2550 proc, Trunc, Origin(),
2551 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2553 CHECK(compileAndRun<int>(proc, b) == (a & b));
2556 void testBitAndBitAndArgImmImm32(int a, int b, int c)
2559 BasicBlock* root = proc.addBlock();
2560 Value* innerBitAnd = root->appendNew<Value>(
2561 proc, BitAnd, Origin(),
2562 root->appendNew<Value>(
2563 proc, Trunc, Origin(),
2564 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2565 root->appendNew<Const32Value>(proc, Origin(), b));
2566 root->appendNewControlValue(
2567 proc, Return, Origin(),
2568 root->appendNew<Value>(
2569 proc, BitAnd, Origin(),
2571 root->appendNew<Const32Value>(proc, Origin(), c)));
2573 CHECK(compileAndRun<int>(proc, a) == ((a & b) & c));
2576 void testBitAndImmBitAndArgImm32(int a, int b, int c)
2579 BasicBlock* root = proc.addBlock();
2580 Value* innerBitAnd = root->appendNew<Value>(
2581 proc, BitAnd, Origin(),
2582 root->appendNew<Value>(
2583 proc, Trunc, Origin(),
2584 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2585 root->appendNew<Const32Value>(proc, Origin(), c));
2586 root->appendNewControlValue(
2587 proc, Return, Origin(),
2588 root->appendNew<Value>(
2589 proc, BitAnd, Origin(),
2590 root->appendNew<Const32Value>(proc, Origin(), a),
2593 CHECK(compileAndRun<int>(proc, b) == (a & (b & c)));
2596 void testBitAndWithMaskReturnsBooleans(int64_t a, int64_t b)
2599 BasicBlock* root = proc.addBlock();
2600 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2601 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2602 Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg0, arg1);
2603 Value* maskedEqual = root->appendNew<Value>(proc, BitAnd, Origin(),
2604 root->appendNew<Const32Value>(proc, Origin(), 0x5),
2606 Value* inverted = root->appendNew<Value>(proc, BitXor, Origin(),
2607 root->appendNew<Const32Value>(proc, Origin(), 0x1),
2609 Value* select = root->appendNew<Value>(proc, Select, Origin(), inverted,
2610 root->appendNew<Const64Value>(proc, Origin(), 42),
2611 root->appendNew<Const64Value>(proc, Origin(), -5));
2613 root->appendNewControlValue(proc, Return, Origin(), select);
2615 int64_t expected = (a == b) ? -5 : 42;
2616 CHECK(compileAndRun<int64_t>(proc, a, b) == expected);
2619 double bitAndDouble(double a, double b)
2621 return bitwise_cast<double>(bitwise_cast<uint64_t>(a) & bitwise_cast<uint64_t>(b));
2624 void testBitAndArgDouble(double a)
2627 BasicBlock* root = proc.addBlock();
2628 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2629 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2630 root->appendNewControlValue(proc, Return, Origin(), result);
2632 CHECK(isIdentical(compileAndRun<double>(proc, a), bitAndDouble(a, a)));
2635 void testBitAndArgsDouble(double a, double b)
2638 BasicBlock* root = proc.addBlock();
2639 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2640 Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
2641 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2642 root->appendNewControlValue(proc, Return, Origin(), result);
2644 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2647 void testBitAndArgImmDouble(double a, double b)
2650 BasicBlock* root = proc.addBlock();
2651 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2652 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2653 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2654 root->appendNewControlValue(proc, Return, Origin(), result);
2656 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2659 void testBitAndImmsDouble(double a, double b)
2662 BasicBlock* root = proc.addBlock();
2663 Value* argumentA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2664 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2665 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2666 root->appendNewControlValue(proc, Return, Origin(), result);
2668 CHECK(isIdentical(compileAndRun<double>(proc), bitAndDouble(a, b)));
2671 float bitAndFloat(float a, float b)
2673 return bitwise_cast<float>(bitwise_cast<uint32_t>(a) & bitwise_cast<uint32_t>(b));
2676 void testBitAndArgFloat(float a)
2679 BasicBlock* root = proc.addBlock();
2680 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2681 root->appendNew<Value>(proc, Trunc, Origin(),
2682 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2683 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2684 root->appendNewControlValue(proc, Return, Origin(), result);
2686 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), bitAndFloat(a, a)));
2689 void testBitAndArgsFloat(float a, float b)
2692 BasicBlock* root = proc.addBlock();
2693 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2694 root->appendNew<Value>(proc, Trunc, Origin(),
2695 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2696 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2697 root->appendNew<Value>(proc, Trunc, Origin(),
2698 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2699 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2700 root->appendNewControlValue(proc, Return, Origin(), result);
2702 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2705 void testBitAndArgImmFloat(float a, float b)
2708 BasicBlock* root = proc.addBlock();
2709 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2710 root->appendNew<Value>(proc, Trunc, Origin(),
2711 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2712 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2713 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2714 root->appendNewControlValue(proc, Return, Origin(), result);
2716 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2719 void testBitAndImmsFloat(float a, float b)
2722 BasicBlock* root = proc.addBlock();
2723 Value* argumentA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2724 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2725 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2726 root->appendNewControlValue(proc, Return, Origin(), result);
2728 CHECK(isIdentical(compileAndRun<float>(proc), bitAndFloat(a, b)));
2731 void testBitAndArgsFloatWithUselessDoubleConversion(float a, float b)
2734 BasicBlock* root = proc.addBlock();
2735 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2736 root->appendNew<Value>(proc, Trunc, Origin(),
2737 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2738 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2739 root->appendNew<Value>(proc, Trunc, Origin(),
2740 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2741 Value* argumentAasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentA);
2742 Value* argumentBasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentB);
2743 Value* doubleResult = root->appendNew<Value>(proc, BitAnd, Origin(), argumentAasDouble, argumentBasDouble);
2744 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleResult);
2745 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2749 float expected = static_cast<float>(bitAndDouble(doubleA, doubleB));
2750 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), expected));
2753 void testBitOrArgs(int64_t a, int64_t b)
2756 BasicBlock* root = proc.addBlock();
2757 root->appendNewControlValue(
2758 proc, Return, Origin(),
2759 root->appendNew<Value>(
2760 proc, BitOr, Origin(),
2761 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2762 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2764 CHECK(compileAndRun<int64_t>(proc, a, b) == (a | b));
2767 void testBitOrSameArg(int64_t a)
2770 BasicBlock* root = proc.addBlock();
2771 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2772 root->appendNewControlValue(
2773 proc, Return, Origin(),
2774 root->appendNew<Value>(
2775 proc, BitOr, Origin(),
2779 CHECK(compileAndRun<int64_t>(proc, a) == a);
2782 void testBitOrImms(int64_t a, int64_t b)
2785 BasicBlock* root = proc.addBlock();
2786 root->appendNewControlValue(
2787 proc, Return, Origin(),
2788 root->appendNew<Value>(
2789 proc, BitOr, Origin(),
2790 root->appendNew<Const64Value>(proc, Origin(), a),
2791 root->appendNew<Const64Value>(proc, Origin(), b)));
2793 CHECK(compileAndRun<int64_t>(proc) == (a | b));
2796 void testBitOrArgImm(int64_t a, int64_t b)
2799 BasicBlock* root = proc.addBlock();
2800 root->appendNewControlValue(
2801 proc, Return, Origin(),
2802 root->appendNew<Value>(
2803 proc, BitOr, Origin(),
2804 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2805 root->appendNew<Const64Value>(proc, Origin(), b)));
2807 CHECK(compileAndRun<int64_t>(proc, a) == (a | b));
2810 void testBitOrImmArg(int64_t a, int64_t b)
2813 BasicBlock* root = proc.addBlock();
2814 root->appendNewControlValue(
2815 proc, Return, Origin(),
2816 root->appendNew<Value>(
2817 proc, BitOr, Origin(),
2818 root->appendNew<Const64Value>(proc, Origin(), a),
2819 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2821 CHECK(compileAndRun<int64_t>(proc, b) == (a | b));
2824 void testBitOrBitOrArgImmImm(int64_t a, int64_t b, int64_t c)
2827 BasicBlock* root = proc.addBlock();
2828 Value* innerBitOr = root->appendNew<Value>(
2829 proc, BitOr, Origin(),
2830 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2831 root->appendNew<Const64Value>(proc, Origin(), b));
2832 root->appendNewControlValue(
2833 proc, Return, Origin(),
2834 root->appendNew<Value>(
2835 proc, BitOr, Origin(),
2837 root->appendNew<Const64Value>(proc, Origin(), c)));
2839 CHECK(compileAndRun<int64_t>(proc, a) == ((a | b) | c));
2842 void testBitOrImmBitOrArgImm(int64_t a, int64_t b, int64_t c)
2845 BasicBlock* root = proc.addBlock();
2846 Value* innerBitOr = root->appendNew<Value>(
2847 proc, BitOr, Origin(),
2848 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2849 root->appendNew<Const64Value>(proc, Origin(), c));
2850 root->appendNewControlValue(
2851 proc, Return, Origin(),
2852 root->appendNew<Value>(
2853 proc, BitOr, Origin(),
2854 root->appendNew<Const64Value>(proc, Origin(), a),
2857 CHECK(compileAndRun<int64_t>(proc, b) == (a | (b | c)));
2860 void testBitOrArgs32(int a, int b)
2863 BasicBlock* root = proc.addBlock();
2864 root->appendNewControlValue(
2865 proc, Return, Origin(),
2866 root->appendNew<Value>(
2867 proc, BitOr, Origin(),
2868 root->appendNew<Value>(
2869 proc, Trunc, Origin(),
2870 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2871 root->appendNew<Value>(
2872 proc, Trunc, Origin(),
2873 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2875 CHECK(compileAndRun<int>(proc, a, b) == (a | b));
2878 void testBitOrSameArg32(int a)
2881 BasicBlock* root = proc.addBlock();
2882 Value* argument = root->appendNew<Value>(
2883 proc, Trunc, Origin(),
2884 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2885 root->appendNewControlValue(
2886 proc, Return, Origin(),
2887 root->appendNew<Value>(
2888 proc, BitOr, Origin(),
2892 CHECK(compileAndRun<int>(proc, a) == a);
2895 void testBitOrImms32(int a, int b)
2898 BasicBlock* root = proc.addBlock();
2899 root->appendNewControlValue(
2900 proc, Return, Origin(),
2901 root->appendNew<Value>(
2902 proc, BitOr, Origin(),
2903 root->appendNew<Const32Value>(proc, Origin(), a),
2904 root->appendNew<Const32Value>(proc, Origin(), b)));
2906 CHECK(compileAndRun<int>(proc) == (a | b));
2909 void testBitOrArgImm32(int a, int b)
2912 BasicBlock* root = proc.addBlock();
2913 root->appendNewControlValue(
2914 proc, Return, Origin(),
2915 root->appendNew<Value>(
2916 proc, BitOr, Origin(),
2917 root->appendNew<Value>(
2918 proc, Trunc, Origin(),
2919 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2920 root->appendNew<Const32Value>(proc, Origin(), b)));
2922 CHECK(compileAndRun<int>(proc, a) == (a | b));
2925 void testBitOrImmArg32(int a, int b)
2928 BasicBlock* root = proc.addBlock();
2929 root->appendNewControlValue(
2930 proc, Return, Origin(),
2931 root->appendNew<Value>(
2932 proc, BitOr, Origin(),
2933 root->appendNew<Const32Value>(proc, Origin(), a),
2934 root->appendNew<Value>(
2935 proc, Trunc, Origin(),
2936 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2938 CHECK(compileAndRun<int>(proc, b) == (a | b));
2941 void testBitOrBitOrArgImmImm32(int a, int b, int c)
2944 BasicBlock* root = proc.addBlock();
2945 Value* innerBitOr = root->appendNew<Value>(
2946 proc, BitOr, Origin(),
2947 root->appendNew<Value>(
2948 proc, Trunc, Origin(),
2949 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2950 root->appendNew<Const32Value>(proc, Origin(), b));
2951 root->appendNewControlValue(
2952 proc, Return, Origin(),
2953 root->appendNew<Value>(
2954 proc, BitOr, Origin(),
2956 root->appendNew<Const32Value>(proc, Origin(), c)));
2958 CHECK(compileAndRun<int>(proc, a) == ((a | b) | c));
2961 void testBitOrImmBitOrArgImm32(int a, int b, int c)
2964 BasicBlock* root = proc.addBlock();
2965 Value* innerBitOr = root->appendNew<Value>(
2966 proc, BitOr, Origin(),
2967 root->appendNew<Value>(
2968 proc, Trunc, Origin(),
2969 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2970 root->appendNew<Const32Value>(proc, Origin(), c));
2971 root->appendNewControlValue(
2972 proc, Return, Origin(),
2973 root->appendNew<Value>(
2974 proc, BitOr, Origin(),
2975 root->appendNew<Const32Value>(proc, Origin(), a),
2978 CHECK(compileAndRun<int>(proc, b) == (a | (b | c)));
2981 void testBitXorArgs(int64_t a, int64_t b)
2984 BasicBlock* root = proc.addBlock();
2985 root->appendNewControlValue(
2986 proc, Return, Origin(),
2987 root->appendNew<Value>(
2988 proc, BitXor, Origin(),
2989 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2990 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2992 CHECK(compileAndRun<int64_t>(proc, a, b) == (a ^ b));
2995 void testBitXorSameArg(int64_t a)
2998 BasicBlock* root = proc.addBlock();
2999 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3000 root->appendNewControlValue(
3001 proc, Return, Origin(),
3002 root->appendNew<Value>(
3003 proc, BitXor, Origin(),
3007 CHECK(!compileAndRun<int64_t>(proc, a));
3010 void testBitXorImms(int64_t a, int64_t b)
3013 BasicBlock* root = proc.addBlock();
3014 root->appendNewControlValue(
3015 proc, Return, Origin(),
3016 root->appendNew<Value>(
3017 proc, BitXor, Origin(),
3018 root->appendNew<Const64Value>(proc, Origin(), a),
3019 root->appendNew<Const64Value>(proc, Origin(), b)));
3021 CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
3024 void testBitXorArgImm(int64_t a, int64_t b)
3027 BasicBlock* root = proc.addBlock();
3028 root->appendNewControlValue(
3029 proc, Return, Origin(),
3030 root->appendNew<Value>(
3031 proc, BitXor, Origin(),
3032 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3033 root->appendNew<Const64Value>(proc, Origin(), b)));
3035 CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
3038 void testBitXorImmArg(int64_t a, int64_t b)
3041 BasicBlock* root = proc.addBlock();
3042 root->appendNewControlValue(
3043 proc, Return, Origin(),
3044 root->appendNew<Value>(
3045 proc, BitXor, Origin(),
3046 root->appendNew<Const64Value>(proc, Origin(), a),
3047 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
3049 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
3052 void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
3055 BasicBlock* root = proc.addBlock();
3056 Value* innerBitXor = root->appendNew<Value>(
3057 proc, BitXor, Origin(),
3058 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3059 root->appendNew<Const64Value>(proc, Origin(), b));
3060 root->appendNewControlValue(
3061 proc, Return, Origin(),
3062 root->appendNew<Value>(
3063 proc, BitXor, Origin(),
3065 root->appendNew<Const64Value>(proc, Origin(), c)));
3067 CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
3070 void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
3073 BasicBlock* root = proc.addBlock();
3074 Value* innerBitXor = root->appendNew<Value>(
3075 proc, BitXor, Origin(),
3076 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3077 root->appendNew<Const64Value>(proc, Origin(), c));
3078 root->appendNewControlValue(
3079 proc, Return, Origin(),
3080 root->appendNew<Value>(
3081 proc, BitXor, Origin(),
3082 root->appendNew<Const64Value>(proc, Origin(), a),
3085 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
3088 void testBitXorArgs32(int a, int b)
3091 BasicBlock* root = proc.addBlock();
3092 root->appendNewControlValue(
3093 proc, Return, Origin(),
3094 root->appendNew<Value>(
3095 proc, BitXor, Origin(),
3096 root->appendNew<Value>(
3097 proc, Trunc, Origin(),
3098 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3099 root->appendNew<Value>(
3100 proc, Trunc, Origin(),
3101 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3103 CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
3106 void testBitXorSameArg32(int a)
3109 BasicBlock* root = proc.addBlock();
3110 Value* argument = root->appendNew<Value>(
3111 proc, Trunc, Origin(),
3112 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3113 root->appendNewControlValue(
3114 proc, Return, Origin(),
3115 root->appendNew<Value>(
3116 proc, BitXor, Origin(),
3120 CHECK(!compileAndRun<int>(proc, a));
3123 void testBitXorImms32(int a, int b)
3126 BasicBlock* root = proc.addBlock();
3127 root->appendNewControlValue(
3128 proc, Return, Origin(),
3129 root->appendNew<Value>(
3130 proc, BitXor, Origin(),
3131 root->appendNew<Const32Value>(proc, Origin(), a),
3132 root->appendNew<Const32Value>(proc, Origin(), b)));
3134 CHECK(compileAndRun<int>(proc) == (a ^ b));
3137 void testBitXorArgImm32(int a, int b)
3140 BasicBlock* root = proc.addBlock();
3141 root->appendNewControlValue(
3142 proc, Return, Origin(),
3143 root->appendNew<Value>(
3144 proc, BitXor, Origin(),
3145 root->appendNew<Value>(
3146 proc, Trunc, Origin(),
3147 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3148 root->appendNew<Const32Value>(proc, Origin(), b)));
3150 CHECK(compileAndRun<int>(proc, a) == (a ^ b));
3153 void testBitXorImmArg32(int a, int b)
3156 BasicBlock* root = proc.addBlock();
3157 root->appendNewControlValue(
3158 proc, Return, Origin(),
3159 root->appendNew<Value>(
3160 proc, BitXor, Origin(),
3161 root->appendNew<Const32Value>(proc, Origin(), a),
3162 root->appendNew<Value>(
3163 proc, Trunc, Origin(),
3164 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
3166 CHECK(compileAndRun<int>(proc, b) == (a ^ b));
3169 void testBitXorBitXorArgImmImm32(int a, int b, int c)
3172 BasicBlock* root = proc.addBlock();
3173 Value* innerBitXor = root->appendNew<Value>(
3174 proc, BitXor, Origin(),
3175 root->appendNew<Value>(
3176 proc, Trunc, Origin(),
3177 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3178 root->appendNew<Const32Value>(proc, Origin(), b));
3179 root->appendNewControlValue(
3180 proc, Return, Origin(),
3181 root->appendNew<Value>(
3182 proc, BitXor, Origin(),
3184 root->appendNew<Const32Value>(proc, Origin(), c)));
3186 CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
3189 void testBitXorImmBitXorArgImm32(int a, int b, int c)
3192 BasicBlock* root = proc.addBlock();
3193 Value* innerBitXor = root->appendNew<Value>(
3194 proc, BitXor, Origin(),
3195 root->appendNew<Value>(
3196 proc, Trunc, Origin(),
3197 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3198 root->appendNew<Const32Value>(proc, Origin(), c));
3199 root->appendNewControlValue(
3200 proc, Return, Origin(),
3201 root->appendNew<Value>(
3202 proc, BitXor, Origin(),
3203 root->appendNew<Const32Value>(proc, Origin(), a),
3206 CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
3209 void testBitNotArg(int64_t a)
3212 BasicBlock* root = proc.addBlock();
3213 root->appendNewControlValue(
3214 proc, Return, Origin(),
3215 root->appendNew<Value>(
3216 proc, BitXor, Origin(),
3217 root->appendNew<Const64Value>(proc, Origin(), -1),
3218 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
3220 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
3223 void testBitNotImm(int64_t a)
3226 BasicBlock* root = proc.addBlock();
3227 root->appendNewControlValue(
3228 proc, Return, Origin(),
3229 root->appendNew<Value>(
3230 proc, BitXor, Origin(),
3231 root->appendNew<Const64Value>(proc, Origin(), -1),
3232 root->appendNew<Const64Value>(proc, Origin(), a)));
3234 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
3237 void testBitNotMem(int64_t a)
3240 BasicBlock* root = proc.addBlock();
3241 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3242 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
3243 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
3244 root->appendNew<Const64Value>(proc, Origin(), -1),
3246 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
3247 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3250 compileAndRun<int32_t>(proc, &input);
3251 CHECK(isIdentical(input, static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
3254 void testBitNotArg32(int32_t a)
3257 BasicBlock* root = proc.addBlock();
3258 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
3259 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3260 root->appendNewControlValue(
3261 proc, Return, Origin(),
3262 root->appendNew<Value>(proc, BitXor, Origin(),
3263 root->appendNew<Const32Value>(proc, Origin(), -1),
3265 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
3268 void testBitNotImm32(int32_t a)
3271 BasicBlock* root = proc.addBlock();
3272 root->appendNewControlValue(
3273 proc, Return, Origin(),
3274 root->appendNew<Value>(
3275 proc, BitXor, Origin(),
3276 root->appendNew<Const32Value>(proc, Origin(), -1),
3277 root->appendNew<Const32Value>(proc, Origin(), a)));
3279 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
3282 void testBitNotMem32(int32_t a)
3285 BasicBlock* root = proc.addBlock();
3286 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3287 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
3288 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
3289 root->appendNew<Const32Value>(proc, Origin(), -1),
3291 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
3292 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3295 compileAndRun<int32_t>(proc, &input);
3296 CHECK(isIdentical(input, static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
3299 void testBitNotOnBooleanAndBranch32(int64_t a, int64_t b)
3302 BasicBlock* root = proc.addBlock();
3303 BasicBlock* thenCase = proc.addBlock();
3304 BasicBlock* elseCase = proc.addBlock();
3306 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
3307 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3308 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
3309 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
3310 Value* argsAreEqual = root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2);
3311 Value* argsAreNotEqual = root->appendNew<Value>(proc, BitXor, Origin(),
3312 root->appendNew<Const32Value>(proc, Origin(), -1),
3315 root->appendNewControlValue(
3316 proc, Branch, Origin(),
3318 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
3320 thenCase->appendNewControlValue(
3321 proc, Return, Origin(),
3322 thenCase->appendNew<Const32Value>(proc, Origin(), 42));
3324 elseCase->appendNewControlValue(
3325 proc, Return, Origin(),
3326 elseCase->appendNew<Const32Value>(proc, Origin(), -42));
3328 int32_t expectedValue = (a != b) ? 42 : -42;
3329 CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
3332 void testShlArgs(int64_t a, int64_t b)
3335 BasicBlock* root = proc.addBlock();
3336 root->appendNewControlValue(
3337 proc, Return, Origin(),
3338 root->appendNew<Value>(
3339 proc, Shl, Origin(),
3340 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3341 root->appendNew<Value>(
3342 proc, Trunc, Origin(),
3343 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3345 CHECK(compileAndRun<int64_t>(proc, a, b) == (a << b));
3348 void testShlImms(int64_t a, int64_t b)
3351 BasicBlock* root = proc.addBlock();
3352 root->appendNewControlValue(
3353 proc, Return, Origin(),
3354 root->appendNew<Value>(
3355 proc, Shl, Origin(),
3356 root->appendNew<Const64Value>(proc, Origin(), a),
3357 root->appendNew<Const32Value>(proc, Origin(), b)));
3359 CHECK(compileAndRun<int64_t>(proc) == (a << b));
3362 void testShlArgImm(int64_t a, int64_t b)
3365 BasicBlock* root = proc.addBlock();
3366 root->appendNewControlValue(
3367 proc, Return, Origin(),
3368 root->appendNew<Value>(
3369 proc, Shl, Origin(),
3370 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3371 root->appendNew<Const32Value>(proc, Origin(), b)));
3373 CHECK(compileAndRun<int64_t>(proc, a) == (a << b));
3376 void testShlArg32(int32_t a)
3379 BasicBlock* root = proc.addBlock();
3380 Value* value = root->appendNew<Value>(
3381 proc, Trunc, Origin(),
3382 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3383 root->appendNewControlValue(
3384 proc, Return, Origin(),
3385 root->appendNew<Value>(proc, Shl, Origin(), value, value));
3387 CHECK(compileAndRun<int32_t>(proc, a) == (a << a));
3390 void testShlArgs32(int32_t a, int32_t b)
3393 BasicBlock* root = proc.addBlock();
3394 root->appendNewControlValue(
3395 proc, Return, Origin(),
3396 root->appendNew<Value>(
3397 proc, Shl, Origin(),
3398 root->appendNew<Value>(
3399 proc, Trunc, Origin(),
3400 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3401 root->appendNew<Value>(
3402 proc, Trunc, Origin(),
3403 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3405 CHECK(compileAndRun<int32_t>(proc, a, b) == (a << b));
3408 void testShlImms32(int32_t a, int32_t b)
3411 BasicBlock* root = proc.addBlock();
3412 root->appendNewControlValue(
3413 proc, Return, Origin(),
3414 root->appendNew<Value>(
3415 proc, Shl, Origin(),
3416 root->appendNew<Const32Value>(proc, Origin(), a),
3417 root->appendNew<Const32Value>(proc, Origin(), b)));
3419 CHECK(compileAndRun<int32_t>(proc) == (a << b));
3422 void testShlArgImm32(int32_t a, int32_t b)
3425 BasicBlock* root = proc.addBlock();
3426 root->appendNewControlValue(
3427 proc, Return, Origin(),
3428 root->appendNew<Value>(
3429 proc, Shl, Origin(),
3430 root->appendNew<Value>(
3431 proc, Trunc, Origin(),
3432 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3433 root->appendNew<Const32Value>(proc, Origin(), b)));
3435 CHECK(compileAndRun<int32_t>(proc, a) == (a << b));
3438 void testSShrArgs(int64_t a, int64_t b)
3441 BasicBlock* root = proc.addBlock();
3442 root->appendNewControlValue(
3443 proc, Return, Origin(),
3444 root->appendNew<Value>(
3445 proc, SShr, Origin(),
3446 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3447 root->appendNew<Value>(
3448 proc, Trunc, Origin(),
3449 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3451 CHECK(compileAndRun<int64_t>(proc, a, b) == (a >> b));
3454 void testSShrImms(int64_t a, int64_t b)
3457 BasicBlock* root = proc.addBlock();
3458 root->appendNewControlValue(
3459 proc, Return, Origin(),
3460 root->appendNew<Value>(
3461 proc, SShr, Origin(),
3462 root->appendNew<Const64Value>(proc, Origin(), a),
3463 root->appendNew<Const32Value>(proc, Origin(), b)));
3465 CHECK(compileAndRun<int64_t>(proc) == (a >> b));
3468 void testSShrArgImm(int64_t a, int64_t b)
3471 BasicBlock* root = proc.addBlock();
3472 root->appendNewControlValue(
3473 proc, Return, Origin(),
3474 root->appendNew<Value>(
3475 proc, SShr, Origin(),
3476 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3477 root->appendNew<Const32Value>(proc, Origin(), b)));