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 "B3ComputeDivisionMagic.h"
37 #include "B3Const32Value.h"
38 #include "B3ConstPtrValue.h"
39 #include "B3Effects.h"
40 #include "B3FenceValue.h"
41 #include "B3Generate.h"
42 #include "B3LowerToAir.h"
43 #include "B3MathExtras.h"
44 #include "B3MemoryValue.h"
45 #include "B3MoveConstants.h"
46 #include "B3Procedure.h"
47 #include "B3ReduceStrength.h"
48 #include "B3SlotBaseValue.h"
49 #include "B3StackSlot.h"
50 #include "B3StackmapGenerationParams.h"
51 #include "B3SwitchValue.h"
52 #include "B3UpsilonValue.h"
53 #include "B3UseCounts.h"
54 #include "B3Validate.h"
55 #include "B3ValueInlines.h"
56 #include "B3VariableValue.h"
57 #include "B3WasmAddressValue.h"
58 #include "B3WasmBoundsCheckValue.h"
59 #include "CCallHelpers.h"
62 #include "InitializeThreading.h"
63 #include "JSCInlines.h"
64 #include "LinkBuffer.h"
69 #include <wtf/ListDump.h>
71 #include <wtf/NumberOfCores.h>
72 #include <wtf/Threading.h>
74 // We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
75 static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
79 dataLog("Usage: testb3 [<filter>]\n");
80 if (hiddenTruthBecauseNoReturnIsStupid())
87 using namespace JSC::B3;
91 bool shouldBeVerbose()
93 return shouldDumpIR(B3Mode);
98 // Nothing fancy for now; we just use the existing WTF assertion machinery.
99 #define CHECK(x) do { \
103 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #x); \
107 #define CHECK_EQ(x, y) do { \
113 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, toCString(#x " == " #y, " (" #x " == ", __x, ", " #y " == ", __y, ")").data()); \
119 std::unique_ptr<Compilation> compile(Procedure& procedure, unsigned optLevel = 1)
121 return std::make_unique<Compilation>(*vm, procedure, optLevel);
124 template<typename T, typename... Arguments>
125 T invoke(MacroAssemblerCodePtr ptr, Arguments... arguments)
127 T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(ptr.executableAddress());
128 return function(arguments...);
131 template<typename T, typename... Arguments>
132 T invoke(const Compilation& code, Arguments... arguments)
134 return invoke<T>(code.code(), arguments...);
137 template<typename T, typename... Arguments>
138 T compileAndRun(Procedure& procedure, Arguments... arguments)
140 return invoke<T>(*compile(procedure), arguments...);
143 void lowerToAirForTesting(Procedure& proc)
145 proc.resetReachability();
147 if (shouldBeVerbose())
148 dataLog("B3 before lowering:\n", proc);
153 if (shouldBeVerbose())
154 dataLog("Air after lowering:\n", proc.code());
156 Air::validate(proc.code());
159 template<typename Func>
160 void checkDisassembly(Compilation& compilation, const Func& func, CString failText)
162 CString disassembly = compilation.disassembly();
163 if (func(disassembly.data()))
167 dataLog("Bad lowering! ", failText, "\n");
168 dataLog(disassembly);
172 void checkUsesInstruction(Compilation& compilation, const char* text)
176 [&] (const char* disassembly) -> bool {
177 return strstr(disassembly, text);
179 toCString("Expected to find ", text, " but didnt!"));
182 void checkDoesNotUseInstruction(Compilation& compilation, const char* text)
186 [&] (const char* disassembly) -> bool {
187 return !strstr(disassembly, text);
189 toCString("Did not expected to find ", text, " but it's there!"));
192 template<typename Type>
198 typedef Operand<int64_t> Int64Operand;
199 typedef Operand<int32_t> Int32Operand;
201 template<typename FloatType>
202 void populateWithInterestingValues(Vector<Operand<FloatType>>& operands)
204 operands.append({ "0.", static_cast<FloatType>(0.) });
205 operands.append({ "-0.", static_cast<FloatType>(-0.) });
206 operands.append({ "0.4", static_cast<FloatType>(0.5) });
207 operands.append({ "-0.4", static_cast<FloatType>(-0.5) });
208 operands.append({ "0.5", static_cast<FloatType>(0.5) });
209 operands.append({ "-0.5", static_cast<FloatType>(-0.5) });
210 operands.append({ "0.6", static_cast<FloatType>(0.5) });
211 operands.append({ "-0.6", static_cast<FloatType>(-0.5) });
212 operands.append({ "1.", static_cast<FloatType>(1.) });
213 operands.append({ "-1.", static_cast<FloatType>(-1.) });
214 operands.append({ "2.", static_cast<FloatType>(2.) });
215 operands.append({ "-2.", static_cast<FloatType>(-2.) });
216 operands.append({ "M_PI", static_cast<FloatType>(M_PI) });
217 operands.append({ "-M_PI", static_cast<FloatType>(-M_PI) });
218 operands.append({ "min", std::numeric_limits<FloatType>::min() });
219 operands.append({ "max", std::numeric_limits<FloatType>::max() });
220 operands.append({ "lowest", std::numeric_limits<FloatType>::lowest() });
221 operands.append({ "epsilon", std::numeric_limits<FloatType>::epsilon() });
222 operands.append({ "infiniti", std::numeric_limits<FloatType>::infinity() });
223 operands.append({ "-infiniti", - std::numeric_limits<FloatType>::infinity() });
224 operands.append({ "PNaN", static_cast<FloatType>(PNaN) });
227 template<typename FloatType>
228 Vector<Operand<FloatType>> floatingPointOperands()
230 Vector<Operand<FloatType>> operands;
231 populateWithInterestingValues(operands);
235 static Vector<Int64Operand> int64Operands()
237 Vector<Int64Operand> operands;
238 operands.append({ "0", 0 });
239 operands.append({ "1", 1 });
240 operands.append({ "-1", -1 });
241 operands.append({ "42", 42 });
242 operands.append({ "-42", -42 });
243 operands.append({ "int64-max", std::numeric_limits<int64_t>::max() });
244 operands.append({ "int64-min", std::numeric_limits<int64_t>::min() });
245 operands.append({ "int32-max", std::numeric_limits<int32_t>::max() });
246 operands.append({ "int32-min", std::numeric_limits<int32_t>::min() });
251 static Vector<Int32Operand> int32Operands()
253 Vector<Int32Operand> operands({
259 { "int32-max", std::numeric_limits<int32_t>::max() },
260 { "int32-min", std::numeric_limits<int32_t>::min() }
265 void add32(CCallHelpers& jit, GPRReg src1, GPRReg src2, GPRReg dest)
268 jit.add32(src1, dest);
270 jit.move(src1, dest);
271 jit.add32(src2, dest);
278 BasicBlock* root = proc.addBlock();
279 Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
280 root->appendNewControlValue(proc, Return, Origin(), const42);
282 CHECK(compileAndRun<int>(proc) == 42);
288 BasicBlock* root = proc.addBlock();
290 root->appendNewControlValue(
291 proc, Return, Origin(),
292 root->appendNew<MemoryValue>(
293 proc, Load, Int32, Origin(),
294 root->appendNew<ConstPtrValue>(proc, Origin(), &x)));
296 CHECK(compileAndRun<int>(proc) == 42);
299 void testLoadWithOffsetImpl(int32_t offset64, int32_t offset32)
303 BasicBlock* root = proc.addBlock();
305 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
306 root->appendNewControlValue(
307 proc, Return, Origin(),
308 root->appendNew<MemoryValue>(
309 proc, Load, Int64, Origin(),
313 char* address = reinterpret_cast<char*>(&x) - offset64;
314 CHECK(compileAndRun<int64_t>(proc, address) == -42);
318 BasicBlock* root = proc.addBlock();
320 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
321 root->appendNewControlValue(
322 proc, Return, Origin(),
323 root->appendNew<MemoryValue>(
324 proc, Load, Int32, Origin(),
328 char* address = reinterpret_cast<char*>(&x) - offset32;
329 CHECK(compileAndRun<int32_t>(proc, address) == -42);
333 void testLoadOffsetImm9Max()
335 testLoadWithOffsetImpl(255, 255);
338 void testLoadOffsetImm9MaxPlusOne()
340 testLoadWithOffsetImpl(256, 256);
343 void testLoadOffsetImm9MaxPlusTwo()
345 testLoadWithOffsetImpl(257, 257);
348 void testLoadOffsetImm9Min()
350 testLoadWithOffsetImpl(-256, -256);
353 void testLoadOffsetImm9MinMinusOne()
355 testLoadWithOffsetImpl(-257, -257);
358 void testLoadOffsetScaledUnsignedImm12Max()
360 testLoadWithOffsetImpl(32760, 16380);
363 void testLoadOffsetScaledUnsignedOverImm12Max()
365 testLoadWithOffsetImpl(32760, 32760);
366 testLoadWithOffsetImpl(32761, 16381);
367 testLoadWithOffsetImpl(32768, 16384);
370 void testArg(int argument)
373 BasicBlock* root = proc.addBlock();
374 root->appendNewControlValue(
375 proc, Return, Origin(),
376 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
378 CHECK(compileAndRun<int>(proc, argument) == argument);
381 void testReturnConst64(int64_t value)
384 BasicBlock* root = proc.addBlock();
385 root->appendNewControlValue(
386 proc, Return, Origin(),
387 root->appendNew<Const64Value>(proc, Origin(), value));
389 CHECK(compileAndRun<int64_t>(proc) == value);
392 void testReturnVoid()
395 BasicBlock* root = proc.addBlock();
396 root->appendNewControlValue(proc, Return, Origin());
397 compileAndRun<void>(proc);
400 void testAddArg(int a)
403 BasicBlock* root = proc.addBlock();
404 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
405 root->appendNewControlValue(
406 proc, Return, Origin(),
407 root->appendNew<Value>(proc, Add, Origin(), value, value));
409 CHECK(compileAndRun<int>(proc, a) == a + a);
412 void testAddArgs(int a, int b)
415 BasicBlock* root = proc.addBlock();
416 root->appendNewControlValue(
417 proc, Return, Origin(),
418 root->appendNew<Value>(
420 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
421 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
423 CHECK(compileAndRun<int>(proc, a, b) == a + b);
426 void testAddArgImm(int a, int b)
429 BasicBlock* root = proc.addBlock();
430 root->appendNewControlValue(
431 proc, Return, Origin(),
432 root->appendNew<Value>(
434 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
435 root->appendNew<Const64Value>(proc, Origin(), b)));
437 CHECK(compileAndRun<int>(proc, a) == a + b);
440 void testAddImmArg(int a, int b)
443 BasicBlock* root = proc.addBlock();
444 root->appendNewControlValue(
445 proc, Return, Origin(),
446 root->appendNew<Value>(
448 root->appendNew<Const64Value>(proc, Origin(), a),
449 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
451 CHECK(compileAndRun<int>(proc, b) == a + b);
454 void testAddArgMem(int64_t a, int64_t b)
457 BasicBlock* root = proc.addBlock();
458 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
459 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
460 Value* result = root->appendNew<Value>(proc, Add, Origin(),
461 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
463 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
464 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
466 int64_t inputOutput = b;
467 CHECK(!compileAndRun<int64_t>(proc, a, &inputOutput));
468 CHECK(inputOutput == a + b);
471 void testAddMemArg(int64_t a, int64_t b)
474 BasicBlock* root = proc.addBlock();
475 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
476 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
477 Value* result = root->appendNew<Value>(proc, Add, Origin(),
479 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
480 root->appendNewControlValue(proc, Return, Origin(), result);
482 CHECK(compileAndRun<int64_t>(proc, &a, b) == a + b);
485 void testAddImmMem(int64_t a, int64_t b)
488 BasicBlock* root = proc.addBlock();
489 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
490 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
491 Value* result = root->appendNew<Value>(proc, Add, Origin(),
492 root->appendNew<Const64Value>(proc, Origin(), a),
494 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
495 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
497 int64_t inputOutput = b;
498 CHECK(!compileAndRun<int>(proc, &inputOutput));
499 CHECK(inputOutput == a + b);
502 void testAddArg32(int a)
505 BasicBlock* root = proc.addBlock();
506 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
507 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
508 root->appendNewControlValue(
509 proc, Return, Origin(),
510 root->appendNew<Value>(proc, Add, Origin(), value, value));
512 CHECK(compileAndRun<int>(proc, a) == a + a);
515 void testAddArgs32(int a, int b)
518 BasicBlock* root = proc.addBlock();
519 root->appendNewControlValue(
520 proc, Return, Origin(),
521 root->appendNew<Value>(
523 root->appendNew<Value>(
524 proc, Trunc, Origin(),
525 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
526 root->appendNew<Value>(
527 proc, Trunc, Origin(),
528 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
530 CHECK(compileAndRun<int>(proc, a, b) == a + b);
533 void testAddArgMem32(int32_t a, int32_t b)
536 BasicBlock* root = proc.addBlock();
537 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
538 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
539 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
540 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
541 Value* result = root->appendNew<Value>(proc, Add, Origin(), argument, load);
542 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
543 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
545 int32_t inputOutput = b;
546 CHECK(!compileAndRun<int32_t>(proc, a, &inputOutput));
547 CHECK(inputOutput == a + b);
550 void testAddMemArg32(int32_t a, int32_t b)
553 BasicBlock* root = proc.addBlock();
554 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
555 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
556 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
557 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
558 Value* result = root->appendNew<Value>(proc, Add, Origin(), load, argument);
559 root->appendNewControlValue(proc, Return, Origin(), result);
561 CHECK(compileAndRun<int32_t>(proc, &a, b) == a + b);
564 void testAddImmMem32(int32_t a, int32_t b)
567 BasicBlock* root = proc.addBlock();
568 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
569 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
570 Value* result = root->appendNew<Value>(proc, Add, Origin(),
571 root->appendNew<Const32Value>(proc, Origin(), a),
573 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
574 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
576 int32_t inputOutput = b;
577 CHECK(!compileAndRun<int>(proc, &inputOutput));
578 CHECK(inputOutput == a + b);
581 void testAddArgZeroImmZDef()
584 BasicBlock* root = proc.addBlock();
585 Value* arg = root->appendNew<Value>(
586 proc, Trunc, Origin(),
587 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
588 Value* constZero = root->appendNew<Const32Value>(proc, Origin(), 0);
589 root->appendNewControlValue(
590 proc, Return, Origin(),
591 root->appendNew<Value>(
596 auto code = compile(proc, 0);
597 CHECK(invoke<int64_t>(*code, 0x0123456789abcdef) == 0x89abcdef);
600 void testAddLoadTwice()
602 auto test = [&] (unsigned optLevel) {
604 BasicBlock* root = proc.addBlock();
606 Value* load = root->appendNew<MemoryValue>(
607 proc, Load, Int32, Origin(),
608 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
609 root->appendNewControlValue(
610 proc, Return, Origin(),
611 root->appendNew<Value>(proc, Add, Origin(), load, load));
613 auto code = compile(proc, optLevel);
614 CHECK(invoke<int32_t>(*code) == 42 * 2);
621 void testAddArgDouble(double a)
624 BasicBlock* root = proc.addBlock();
625 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
626 root->appendNewControlValue(
627 proc, Return, Origin(),
628 root->appendNew<Value>(proc, Add, Origin(), value, value));
630 CHECK(isIdentical(compileAndRun<double>(proc, a), a + a));
633 void testAddArgsDouble(double a, double b)
636 BasicBlock* root = proc.addBlock();
637 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
638 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
639 root->appendNewControlValue(
640 proc, Return, Origin(),
641 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
643 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a + b));
646 void testAddArgImmDouble(double a, double b)
649 BasicBlock* root = proc.addBlock();
650 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
651 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
652 root->appendNewControlValue(
653 proc, Return, Origin(),
654 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
656 CHECK(isIdentical(compileAndRun<double>(proc, a), a + b));
659 void testAddImmArgDouble(double a, double b)
662 BasicBlock* root = proc.addBlock();
663 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
664 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
665 root->appendNewControlValue(
666 proc, Return, Origin(),
667 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
669 CHECK(isIdentical(compileAndRun<double>(proc, b), a + b));
672 void testAddImmsDouble(double a, double b)
675 BasicBlock* root = proc.addBlock();
676 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
677 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
678 root->appendNewControlValue(
679 proc, Return, Origin(),
680 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
682 CHECK(isIdentical(compileAndRun<double>(proc), a + b));
685 void testAddArgFloat(float a)
688 BasicBlock* root = proc.addBlock();
689 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
690 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
691 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
692 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, floatValue);
693 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
694 root->appendNewControlValue(proc, Return, Origin(), result32);
697 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
700 void testAddArgsFloat(float a, float b)
703 BasicBlock* root = proc.addBlock();
704 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
705 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
706 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
707 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
708 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
709 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
710 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue1, floatValue2);
711 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
712 root->appendNewControlValue(proc, Return, Origin(), result32);
714 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
717 void testAddFPRArgsFloat(float a, float b)
720 BasicBlock* root = proc.addBlock();
721 Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
722 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
723 Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
724 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1));
725 Value* result = root->appendNew<Value>(proc, Add, Origin(), argument1, argument2);
726 root->appendNewControlValue(proc, Return, Origin(), result);
728 CHECK(isIdentical(compileAndRun<float>(proc, a, b), a + b));
731 void testAddArgImmFloat(float a, float b)
734 BasicBlock* root = proc.addBlock();
735 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
736 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
737 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
738 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
739 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, constValue);
740 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
741 root->appendNewControlValue(proc, Return, Origin(), result32);
743 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + b)));
746 void testAddImmArgFloat(float a, float b)
749 BasicBlock* root = proc.addBlock();
750 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
751 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
752 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
753 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
754 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue, floatValue);
755 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
756 root->appendNewControlValue(proc, Return, Origin(), result32);
758 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
761 void testAddImmsFloat(float a, float b)
764 BasicBlock* root = proc.addBlock();
765 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
766 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
767 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue1, constValue2);
768 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
769 root->appendNewControlValue(proc, Return, Origin(), result32);
771 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a + b)));
774 void testAddArgFloatWithUselessDoubleConversion(float a)
777 BasicBlock* root = proc.addBlock();
778 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
779 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
780 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
781 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
782 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble, asDouble);
783 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
784 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
785 root->appendNewControlValue(proc, Return, Origin(), result32);
787 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
790 void testAddArgsFloatWithUselessDoubleConversion(float a, float b)
793 BasicBlock* root = proc.addBlock();
794 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
795 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
796 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
797 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
798 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
799 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
800 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
801 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
802 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
803 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
804 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
805 root->appendNewControlValue(proc, Return, Origin(), result32);
807 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
810 void testAddArgsFloatWithEffectfulDoubleConversion(float a, float b)
813 BasicBlock* root = proc.addBlock();
814 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
815 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
816 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
817 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
818 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
819 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
820 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
821 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
822 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
823 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
824 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
825 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
826 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
827 root->appendNewControlValue(proc, Return, Origin(), result32);
830 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a + b)));
831 CHECK(isIdentical(effect, static_cast<double>(a) + static_cast<double>(b)));
834 void testMulArg(int a)
837 BasicBlock* root = proc.addBlock();
838 Value* value = root->appendNew<Value>(
839 proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
840 root->appendNewControlValue(
841 proc, Return, Origin(),
842 root->appendNew<Value>(proc, Mul, Origin(), value, value));
844 CHECK(compileAndRun<int>(proc, a) == a * a);
847 void testMulArgStore(int a)
850 BasicBlock* root = proc.addBlock();
855 Value* value = root->appendNew<Value>(
856 proc, Trunc, Origin(),
857 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
858 Value* mul = root->appendNew<Value>(proc, Mul, Origin(), value, value);
860 root->appendNew<MemoryValue>(
861 proc, Store, Origin(), value,
862 root->appendNew<ConstPtrValue>(proc, Origin(), &valueSlot));
863 root->appendNew<MemoryValue>(
864 proc, Store, Origin(), mul,
865 root->appendNew<ConstPtrValue>(proc, Origin(), &mulSlot));
867 root->appendNewControlValue(
868 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
870 CHECK(!compileAndRun<int>(proc, a));
871 CHECK(mulSlot == a * a);
872 CHECK(valueSlot == a);
875 void testMulAddArg(int a)
878 BasicBlock* root = proc.addBlock();
879 Value* value = root->appendNew<Value>(
880 proc, Trunc, Origin(),
881 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
882 root->appendNewControlValue(
883 proc, Return, Origin(),
884 root->appendNew<Value>(
886 root->appendNew<Value>(proc, Mul, Origin(), value, value),
889 CHECK(compileAndRun<int>(proc, a) == a * a + a);
892 void testMulArgs(int a, int b)
895 BasicBlock* root = proc.addBlock();
896 root->appendNewControlValue(
897 proc, Return, Origin(),
898 root->appendNew<Value>(
900 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
901 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
903 CHECK(compileAndRun<int>(proc, a, b) == a * b);
906 void testMulArgImm(int64_t a, int64_t b)
909 BasicBlock* root = proc.addBlock();
910 root->appendNewControlValue(
911 proc, Return, Origin(),
912 root->appendNew<Value>(
914 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
915 root->appendNew<Const64Value>(proc, Origin(), b)));
917 CHECK(compileAndRun<int64_t>(proc, a) == a * b);
920 void testMulImmArg(int a, int b)
923 BasicBlock* root = proc.addBlock();
924 root->appendNewControlValue(
925 proc, Return, Origin(),
926 root->appendNew<Value>(
928 root->appendNew<Const64Value>(proc, Origin(), a),
929 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
931 CHECK(compileAndRun<int>(proc, b) == a * b);
934 void testMulArgs32(int a, int b)
937 BasicBlock* root = proc.addBlock();
938 root->appendNewControlValue(
939 proc, Return, Origin(),
940 root->appendNew<Value>(
942 root->appendNew<Value>(
943 proc, Trunc, Origin(),
944 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
945 root->appendNew<Value>(
946 proc, Trunc, Origin(),
947 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
949 CHECK(compileAndRun<int>(proc, a, b) == a * b);
952 void testMulLoadTwice()
954 auto test = [&] (unsigned optLevel) {
956 BasicBlock* root = proc.addBlock();
958 Value* load = root->appendNew<MemoryValue>(
959 proc, Load, Int32, Origin(),
960 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
961 root->appendNewControlValue(
962 proc, Return, Origin(),
963 root->appendNew<Value>(proc, Mul, Origin(), load, load));
965 auto code = compile(proc, optLevel);
966 CHECK(invoke<int32_t>(*code) == 42 * 42);
973 void testMulAddArgsLeft()
976 BasicBlock* root = proc.addBlock();
978 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
979 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
980 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
981 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
982 Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
983 root->appendNewControlValue(proc, Return, Origin(), added);
985 auto code = compile(proc);
987 auto testValues = int64Operands();
988 for (auto a : testValues) {
989 for (auto b : testValues) {
990 for (auto c : testValues) {
991 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
997 void testMulAddArgsRight()
1000 BasicBlock* root = proc.addBlock();
1002 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1003 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1004 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1005 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1006 Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
1007 root->appendNewControlValue(proc, Return, Origin(), added);
1009 auto code = compile(proc);
1011 auto testValues = int64Operands();
1012 for (auto a : testValues) {
1013 for (auto b : testValues) {
1014 for (auto c : testValues) {
1015 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
1021 void testMulAddArgsLeft32()
1024 BasicBlock* root = proc.addBlock();
1026 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1027 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1028 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1029 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1030 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1031 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1032 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1033 Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
1034 root->appendNewControlValue(proc, Return, Origin(), added);
1036 auto code = compile(proc);
1038 auto testValues = int32Operands();
1039 for (auto a : testValues) {
1040 for (auto b : testValues) {
1041 for (auto c : testValues) {
1042 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
1048 void testMulAddArgsRight32()
1051 BasicBlock* root = proc.addBlock();
1053 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1054 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1055 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1056 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1057 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1058 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1059 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1060 Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
1061 root->appendNewControlValue(proc, Return, Origin(), added);
1063 auto code = compile(proc);
1065 auto testValues = int32Operands();
1066 for (auto a : testValues) {
1067 for (auto b : testValues) {
1068 for (auto c : testValues) {
1069 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
1075 void testMulSubArgsLeft()
1078 BasicBlock* root = proc.addBlock();
1080 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1081 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1082 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1083 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1084 Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
1085 root->appendNewControlValue(proc, Return, Origin(), added);
1087 auto code = compile(proc);
1089 auto testValues = int64Operands();
1090 for (auto a : testValues) {
1091 for (auto b : testValues) {
1092 for (auto c : testValues) {
1093 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
1099 void testMulSubArgsRight()
1102 BasicBlock* root = proc.addBlock();
1104 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1105 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1106 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1107 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1108 Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
1109 root->appendNewControlValue(proc, Return, Origin(), added);
1111 auto code = compile(proc);
1113 auto testValues = int64Operands();
1114 for (auto a : testValues) {
1115 for (auto b : testValues) {
1116 for (auto c : testValues) {
1117 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
1123 void testMulSubArgsLeft32()
1126 BasicBlock* root = proc.addBlock();
1128 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1129 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1130 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1131 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1132 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1133 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1134 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1135 Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
1136 root->appendNewControlValue(proc, Return, Origin(), added);
1138 auto code = compile(proc);
1140 auto testValues = int32Operands();
1141 for (auto a : testValues) {
1142 for (auto b : testValues) {
1143 for (auto c : testValues) {
1144 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
1150 void testMulSubArgsRight32()
1153 BasicBlock* root = proc.addBlock();
1155 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1156 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1157 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1158 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1159 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1160 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1161 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1162 Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
1163 root->appendNewControlValue(proc, Return, Origin(), added);
1165 auto code = compile(proc);
1167 auto testValues = int32Operands();
1168 for (auto a : testValues) {
1169 for (auto b : testValues) {
1170 for (auto c : testValues) {
1171 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
1177 void testMulNegArgs()
1180 BasicBlock* root = proc.addBlock();
1182 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1183 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1184 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1185 Value* zero = root->appendNew<Const64Value>(proc, Origin(), 0);
1186 Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
1187 root->appendNewControlValue(proc, Return, Origin(), added);
1189 auto code = compile(proc);
1191 auto testValues = int64Operands();
1192 for (auto a : testValues) {
1193 for (auto b : testValues) {
1194 CHECK(invoke<int64_t>(*code, a.value, b.value) == -(a.value * b.value));
1199 void testMulNegArgs32()
1202 BasicBlock* root = proc.addBlock();
1204 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1205 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1206 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1207 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1208 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1209 Value* zero = root->appendNew<Const32Value>(proc, Origin(), 0);
1210 Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
1211 root->appendNewControlValue(proc, Return, Origin(), added);
1213 auto code = compile(proc);
1215 auto testValues = int32Operands();
1216 for (auto a : testValues) {
1217 for (auto b : testValues) {
1218 CHECK(invoke<int32_t>(*code, a.value, b.value) == -(a.value * b.value));
1223 void testMulArgDouble(double a)
1226 BasicBlock* root = proc.addBlock();
1227 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1228 root->appendNewControlValue(
1229 proc, Return, Origin(),
1230 root->appendNew<Value>(proc, Mul, Origin(), value, value));
1232 CHECK(isIdentical(compileAndRun<double>(proc, a), a * a));
1235 void testMulArgsDouble(double a, double b)
1238 BasicBlock* root = proc.addBlock();
1239 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1240 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1241 root->appendNewControlValue(
1242 proc, Return, Origin(),
1243 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1245 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a * b));
1248 void testMulArgImmDouble(double a, double b)
1251 BasicBlock* root = proc.addBlock();
1252 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1253 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1254 root->appendNewControlValue(
1255 proc, Return, Origin(),
1256 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1258 CHECK(isIdentical(compileAndRun<double>(proc, a), a * b));
1261 void testMulImmArgDouble(double a, double b)
1264 BasicBlock* root = proc.addBlock();
1265 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1266 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1267 root->appendNewControlValue(
1268 proc, Return, Origin(),
1269 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1271 CHECK(isIdentical(compileAndRun<double>(proc, b), a * b));
1274 void testMulImmsDouble(double a, double b)
1277 BasicBlock* root = proc.addBlock();
1278 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1279 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1280 root->appendNewControlValue(
1281 proc, Return, Origin(),
1282 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1284 CHECK(isIdentical(compileAndRun<double>(proc), a * b));
1287 void testMulArgFloat(float a)
1290 BasicBlock* root = proc.addBlock();
1291 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1292 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1293 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1294 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, floatValue);
1295 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1296 root->appendNewControlValue(proc, Return, Origin(), result32);
1299 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
1302 void testMulArgsFloat(float a, float b)
1305 BasicBlock* root = proc.addBlock();
1306 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1307 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1308 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1309 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1310 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1311 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1312 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue1, floatValue2);
1313 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1314 root->appendNewControlValue(proc, Return, Origin(), result32);
1316 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1319 void testMulArgImmFloat(float a, float b)
1322 BasicBlock* root = proc.addBlock();
1323 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1324 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1325 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1326 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1327 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, constValue);
1328 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1329 root->appendNewControlValue(proc, Return, Origin(), result32);
1331 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * b)));
1334 void testMulImmArgFloat(float a, float b)
1337 BasicBlock* root = proc.addBlock();
1338 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1339 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1340 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1341 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1342 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue, floatValue);
1343 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1344 root->appendNewControlValue(proc, Return, Origin(), result32);
1346 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1349 void testMulImmsFloat(float a, float b)
1352 BasicBlock* root = proc.addBlock();
1353 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1354 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1355 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue1, constValue2);
1356 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1357 root->appendNewControlValue(proc, Return, Origin(), result32);
1359 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a * b)));
1362 void testMulArgFloatWithUselessDoubleConversion(float a)
1365 BasicBlock* root = proc.addBlock();
1366 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1367 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1368 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1369 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1370 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble, asDouble);
1371 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1372 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1373 root->appendNewControlValue(proc, Return, Origin(), result32);
1375 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
1378 void testMulArgsFloatWithUselessDoubleConversion(float a, float b)
1381 BasicBlock* root = proc.addBlock();
1382 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1383 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1384 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1385 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1386 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1387 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1388 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1389 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1390 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
1391 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1392 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1393 root->appendNewControlValue(proc, Return, Origin(), result32);
1395 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1398 void testMulArgsFloatWithEffectfulDoubleConversion(float a, float b)
1401 BasicBlock* root = proc.addBlock();
1402 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1403 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1404 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1405 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1406 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1407 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1408 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1409 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1410 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
1411 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1412 Value* doubleMulress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1413 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleMulress);
1414 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1415 root->appendNewControlValue(proc, Return, Origin(), result32);
1418 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a * b)));
1419 CHECK(isIdentical(effect, static_cast<double>(a) * static_cast<double>(b)));
1422 void testDivArgDouble(double a)
1425 BasicBlock* root = proc.addBlock();
1426 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1427 root->appendNewControlValue(
1428 proc, Return, Origin(),
1429 root->appendNew<Value>(proc, Div, Origin(), value, value));
1431 CHECK(isIdentical(compileAndRun<double>(proc, a), a / a));
1434 void testDivArgsDouble(double a, double b)
1437 BasicBlock* root = proc.addBlock();
1438 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1439 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1440 root->appendNewControlValue(
1441 proc, Return, Origin(),
1442 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1444 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a / b));
1447 void testDivArgImmDouble(double a, double b)
1450 BasicBlock* root = proc.addBlock();
1451 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1452 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1453 root->appendNewControlValue(
1454 proc, Return, Origin(),
1455 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1457 CHECK(isIdentical(compileAndRun<double>(proc, a), a / b));
1460 void testDivImmArgDouble(double a, double b)
1463 BasicBlock* root = proc.addBlock();
1464 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1465 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1466 root->appendNewControlValue(
1467 proc, Return, Origin(),
1468 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1470 CHECK(isIdentical(compileAndRun<double>(proc, b), a / b));
1473 void testDivImmsDouble(double a, double b)
1476 BasicBlock* root = proc.addBlock();
1477 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1478 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1479 root->appendNewControlValue(
1480 proc, Return, Origin(),
1481 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1483 CHECK(isIdentical(compileAndRun<double>(proc), a / b));
1486 void testDivArgFloat(float a)
1489 BasicBlock* root = proc.addBlock();
1490 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1491 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1492 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1493 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, floatValue);
1494 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1495 root->appendNewControlValue(proc, Return, Origin(), result32);
1498 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1501 void testDivArgsFloat(float a, float b)
1504 BasicBlock* root = proc.addBlock();
1505 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1506 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1507 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1508 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1509 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1510 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1511 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue1, floatValue2);
1512 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1513 root->appendNewControlValue(proc, Return, Origin(), result32);
1515 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1518 void testDivArgImmFloat(float a, float b)
1521 BasicBlock* root = proc.addBlock();
1522 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1523 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1524 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1525 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1526 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, constValue);
1527 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1528 root->appendNewControlValue(proc, Return, Origin(), result32);
1530 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / b)));
1533 void testDivImmArgFloat(float a, float b)
1536 BasicBlock* root = proc.addBlock();
1537 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1538 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1539 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1540 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1541 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue, floatValue);
1542 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1543 root->appendNewControlValue(proc, Return, Origin(), result32);
1545 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1548 void testDivImmsFloat(float a, float b)
1551 BasicBlock* root = proc.addBlock();
1552 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1553 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1554 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue1, constValue2);
1555 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1556 root->appendNewControlValue(proc, Return, Origin(), result32);
1558 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a / b)));
1561 void testModArgDouble(double a)
1564 BasicBlock* root = proc.addBlock();
1565 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1566 root->appendNewControlValue(
1567 proc, Return, Origin(),
1568 root->appendNew<Value>(proc, Mod, Origin(), value, value));
1570 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, a)));
1573 void testModArgsDouble(double a, double b)
1576 BasicBlock* root = proc.addBlock();
1577 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1578 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1579 root->appendNewControlValue(
1580 proc, Return, Origin(),
1581 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1583 CHECK(isIdentical(compileAndRun<double>(proc, a, b), fmod(a, b)));
1586 void testModArgImmDouble(double a, double b)
1589 BasicBlock* root = proc.addBlock();
1590 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1591 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1592 root->appendNewControlValue(
1593 proc, Return, Origin(),
1594 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1596 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, b)));
1599 void testModImmArgDouble(double a, double b)
1602 BasicBlock* root = proc.addBlock();
1603 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1604 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1605 root->appendNewControlValue(
1606 proc, Return, Origin(),
1607 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1609 CHECK(isIdentical(compileAndRun<double>(proc, b), fmod(a, b)));
1612 void testModImmsDouble(double a, double b)
1615 BasicBlock* root = proc.addBlock();
1616 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1617 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1618 root->appendNewControlValue(
1619 proc, Return, Origin(),
1620 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1622 CHECK(isIdentical(compileAndRun<double>(proc), fmod(a, b)));
1625 void testModArgFloat(float a)
1628 BasicBlock* root = proc.addBlock();
1629 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1630 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1631 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1632 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, floatValue);
1633 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1634 root->appendNewControlValue(proc, Return, Origin(), result32);
1637 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, a)))));
1640 void testModArgsFloat(float a, float b)
1643 BasicBlock* root = proc.addBlock();
1644 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1645 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1646 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1647 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1648 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1649 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1650 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue1, floatValue2);
1651 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1652 root->appendNewControlValue(proc, Return, Origin(), result32);
1654 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)))));
1657 void testModArgImmFloat(float a, float b)
1660 BasicBlock* root = proc.addBlock();
1661 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1662 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1663 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1664 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1665 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, constValue);
1666 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1667 root->appendNewControlValue(proc, Return, Origin(), result32);
1669 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1672 void testModImmArgFloat(float a, float b)
1675 BasicBlock* root = proc.addBlock();
1676 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1677 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1678 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1679 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1680 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue, floatValue);
1681 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1682 root->appendNewControlValue(proc, Return, Origin(), result32);
1684 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1687 void testModImmsFloat(float a, float b)
1690 BasicBlock* root = proc.addBlock();
1691 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1692 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1693 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue1, constValue2);
1694 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1695 root->appendNewControlValue(proc, Return, Origin(), result32);
1697 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1700 void testDivArgFloatWithUselessDoubleConversion(float a)
1703 BasicBlock* root = proc.addBlock();
1704 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1705 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1706 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1707 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1708 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble, asDouble);
1709 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1710 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1711 root->appendNewControlValue(proc, Return, Origin(), result32);
1713 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1716 void testDivArgsFloatWithUselessDoubleConversion(float a, float b)
1719 BasicBlock* root = proc.addBlock();
1720 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1721 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1722 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1723 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1724 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1725 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1726 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1727 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1728 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1729 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1730 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1731 root->appendNewControlValue(proc, Return, Origin(), result32);
1733 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1736 void testDivArgsFloatWithEffectfulDoubleConversion(float a, float b)
1739 BasicBlock* root = proc.addBlock();
1740 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1741 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1742 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1743 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1744 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1745 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1746 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1747 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1748 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1749 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1750 Value* doubleDivress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1751 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleDivress);
1752 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1753 root->appendNewControlValue(proc, Return, Origin(), result32);
1756 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a / b)));
1757 CHECK(isIdentical(effect, static_cast<double>(a) / static_cast<double>(b)));
1760 void testUDivArgsInt32(uint32_t a, uint32_t b)
1762 // UDiv with denominator == 0 is invalid.
1767 BasicBlock* root = proc.addBlock();
1768 Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
1769 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1770 Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
1771 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1772 Value* result = root->appendNew<Value>(proc, UDiv, Origin(), argument1, argument2);
1773 root->appendNew<Value>(proc, Return, Origin(), result);
1775 CHECK_EQ(compileAndRun<uint32_t>(proc, a, b), a / b);
1778 void testUDivArgsInt64(uint64_t a, uint64_t b)
1780 // UDiv with denominator == 0 is invalid.
1785 BasicBlock* root = proc.addBlock();
1786 Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1787 Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1788 Value* result = root->appendNew<Value>(proc, UDiv, Origin(), argument1, argument2);
1789 root->appendNew<Value>(proc, Return, Origin(), result);
1791 CHECK_EQ(compileAndRun<uint64_t>(proc, a, b), a / b);
1794 void testUModArgsInt32(uint32_t a, uint32_t b)
1796 // UMod with denominator == 0 is invalid.
1801 BasicBlock* root = proc.addBlock();
1802 Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
1803 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1804 Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
1805 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1806 Value* result = root->appendNew<Value>(proc, UMod, Origin(), argument1, argument2);
1807 root->appendNew<Value>(proc, Return, Origin(), result);
1809 CHECK_EQ(compileAndRun<uint32_t>(proc, a, b), a % b);
1812 void testUModArgsInt64(uint64_t a, uint64_t b)
1814 // UMod with denominator == 0 is invalid.
1819 BasicBlock* root = proc.addBlock();
1820 Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1821 Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1822 Value* result = root->appendNew<Value>(proc, UMod, Origin(), argument1, argument2);
1823 root->appendNew<Value>(proc, Return, Origin(), result);
1825 CHECK_EQ(compileAndRun<uint64_t>(proc, a, b), a % b);
1828 void testSubArg(int a)
1831 BasicBlock* root = proc.addBlock();
1832 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1833 root->appendNewControlValue(
1834 proc, Return, Origin(),
1835 root->appendNew<Value>(proc, Sub, Origin(), value, value));
1837 CHECK(!compileAndRun<int>(proc, a));
1840 void testSubArgs(int a, int b)
1843 BasicBlock* root = proc.addBlock();
1844 root->appendNewControlValue(
1845 proc, Return, Origin(),
1846 root->appendNew<Value>(
1847 proc, Sub, Origin(),
1848 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1849 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
1851 CHECK(compileAndRun<int>(proc, a, b) == a - b);
1854 void testSubArgImm(int64_t a, int64_t b)
1857 BasicBlock* root = proc.addBlock();
1858 root->appendNewControlValue(
1859 proc, Return, Origin(),
1860 root->appendNew<Value>(
1861 proc, Sub, Origin(),
1862 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1863 root->appendNew<Const64Value>(proc, Origin(), b)));
1865 CHECK(compileAndRun<int64_t>(proc, a) == a - b);
1868 void testNegValueSubOne(int a)
1871 BasicBlock* root = proc.addBlock();
1872 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1873 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
1874 root->appendNew<Const64Value>(proc, Origin(), 0),
1876 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
1878 root->appendNew<Const64Value>(proc, Origin(), 1));
1879 root->appendNewControlValue(proc, Return, Origin(), negArgumentMinusOne);
1880 CHECK(compileAndRun<int>(proc, a) == -a - 1);
1883 void testSubImmArg(int a, int b)
1886 BasicBlock* root = proc.addBlock();
1887 root->appendNewControlValue(
1888 proc, Return, Origin(),
1889 root->appendNew<Value>(
1890 proc, Sub, Origin(),
1891 root->appendNew<Const64Value>(proc, Origin(), a),
1892 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1894 CHECK(compileAndRun<int>(proc, b) == a - b);
1897 void testSubArgMem(int64_t a, int64_t b)
1900 BasicBlock* root = proc.addBlock();
1901 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1902 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1903 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1904 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1906 root->appendNewControlValue(proc, Return, Origin(), result);
1908 CHECK(compileAndRun<int64_t>(proc, a, &b) == a - b);
1911 void testSubMemArg(int64_t a, int64_t b)
1914 BasicBlock* root = proc.addBlock();
1915 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1916 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1917 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1919 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1920 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1921 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1923 int64_t inputOutput = a;
1924 CHECK(!compileAndRun<int64_t>(proc, &inputOutput, b));
1925 CHECK(inputOutput == a - b);
1928 void testSubImmMem(int64_t a, int64_t b)
1931 BasicBlock* root = proc.addBlock();
1932 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1933 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1934 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1935 root->appendNew<Const64Value>(proc, Origin(), a),
1937 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1938 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1940 int64_t inputOutput = b;
1941 CHECK(!compileAndRun<int>(proc, &inputOutput));
1942 CHECK(inputOutput == a - b);
1945 void testSubMemImm(int64_t a, int64_t b)
1948 BasicBlock* root = proc.addBlock();
1949 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1950 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1951 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1953 root->appendNew<Const64Value>(proc, Origin(), b));
1954 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1955 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1957 int64_t inputOutput = a;
1958 CHECK(!compileAndRun<int>(proc, &inputOutput));
1959 CHECK(inputOutput == a - b);
1963 void testSubArgs32(int a, int b)
1966 BasicBlock* root = proc.addBlock();
1967 root->appendNewControlValue(
1968 proc, Return, Origin(),
1969 root->appendNew<Value>(
1970 proc, Sub, Origin(),
1971 root->appendNew<Value>(
1972 proc, Trunc, Origin(),
1973 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1974 root->appendNew<Value>(
1975 proc, Trunc, Origin(),
1976 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1978 CHECK(compileAndRun<int>(proc, a, b) == a - b);
1981 void testSubArgImm32(int a, int b)
1984 BasicBlock* root = proc.addBlock();
1985 root->appendNewControlValue(
1986 proc, Return, Origin(),
1987 root->appendNew<Value>(
1988 proc, Sub, Origin(),
1989 root->appendNew<Value>(
1990 proc, Trunc, Origin(),
1991 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1992 root->appendNew<Const32Value>(proc, Origin(), b)));
1994 CHECK(compileAndRun<int>(proc, a) == a - b);
1997 void testSubImmArg32(int a, int b)
2000 BasicBlock* root = proc.addBlock();
2001 root->appendNewControlValue(
2002 proc, Return, Origin(),
2003 root->appendNew<Value>(
2004 proc, Sub, Origin(),
2005 root->appendNew<Const32Value>(proc, Origin(), a),
2006 root->appendNew<Value>(
2007 proc, Trunc, Origin(),
2008 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2010 CHECK(compileAndRun<int>(proc, b) == a - b);
2013 void testSubMemArg32(int32_t a, int32_t b)
2016 BasicBlock* root = proc.addBlock();
2017 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2018 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2019 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2020 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2021 Value* result = root->appendNew<Value>(proc, Sub, Origin(), load, argument);
2022 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2023 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2025 int32_t inputOutput = a;
2026 CHECK(!compileAndRun<int32_t>(proc, &inputOutput, b));
2027 CHECK(inputOutput == a - b);
2030 void testSubArgMem32(int32_t a, int32_t b)
2033 BasicBlock* root = proc.addBlock();
2034 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2035 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2036 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2037 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2038 Value* result = root->appendNew<Value>(proc, Sub, Origin(), argument, load);
2039 root->appendNewControlValue(proc, Return, Origin(), result);
2041 CHECK(compileAndRun<int32_t>(proc, a, &b) == a - b);
2044 void testSubImmMem32(int32_t a, int32_t b)
2047 BasicBlock* root = proc.addBlock();
2048 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2049 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2050 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2051 root->appendNew<Const32Value>(proc, Origin(), a),
2053 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2054 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2056 int32_t inputOutput = b;
2057 CHECK(!compileAndRun<int>(proc, &inputOutput));
2058 CHECK(inputOutput == a - b);
2061 void testSubMemImm32(int32_t a, int32_t b)
2064 BasicBlock* root = proc.addBlock();
2065 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2066 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2067 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2069 root->appendNew<Const32Value>(proc, Origin(), b));
2070 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2071 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2073 int32_t inputOutput = a;
2074 CHECK(!compileAndRun<int>(proc, &inputOutput));
2075 CHECK(inputOutput == a - b);
2078 void testNegValueSubOne32(int a)
2081 BasicBlock* root = proc.addBlock();
2082 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2083 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2084 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
2085 root->appendNew<Const32Value>(proc, Origin(), 0),
2087 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
2089 root->appendNew<Const32Value>(proc, Origin(), 1));
2090 root->appendNewControlValue(proc, Return, Origin(), negArgumentMinusOne);
2091 CHECK(compileAndRun<int>(proc, a) == -a - 1);
2094 void testSubArgDouble(double a)
2097 BasicBlock* root = proc.addBlock();
2098 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2099 root->appendNewControlValue(
2100 proc, Return, Origin(),
2101 root->appendNew<Value>(proc, Sub, Origin(), value, value));
2103 CHECK(isIdentical(compileAndRun<double>(proc, a), a - a));
2106 void testSubArgsDouble(double a, double b)
2109 BasicBlock* root = proc.addBlock();
2110 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2111 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
2112 root->appendNewControlValue(
2113 proc, Return, Origin(),
2114 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2116 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a - b));
2119 void testSubArgImmDouble(double a, double b)
2122 BasicBlock* root = proc.addBlock();
2123 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2124 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2125 root->appendNewControlValue(
2126 proc, Return, Origin(),
2127 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2129 CHECK(isIdentical(compileAndRun<double>(proc, a), a - b));
2132 void testSubImmArgDouble(double a, double b)
2135 BasicBlock* root = proc.addBlock();
2136 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2137 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2138 root->appendNewControlValue(
2139 proc, Return, Origin(),
2140 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2142 CHECK(isIdentical(compileAndRun<double>(proc, b), a - b));
2145 void testSubImmsDouble(double a, double b)
2148 BasicBlock* root = proc.addBlock();
2149 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2150 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2151 root->appendNewControlValue(
2152 proc, Return, Origin(),
2153 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2155 CHECK(isIdentical(compileAndRun<double>(proc), a - b));
2158 void testSubArgFloat(float a)
2161 BasicBlock* root = proc.addBlock();
2162 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2163 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2164 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2165 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, floatValue);
2166 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2167 root->appendNewControlValue(proc, Return, Origin(), result32);
2170 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
2173 void testSubArgsFloat(float a, float b)
2176 BasicBlock* root = proc.addBlock();
2177 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2178 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2179 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2180 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2181 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2182 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2183 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue1, floatValue2);
2184 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2185 root->appendNewControlValue(proc, Return, Origin(), result32);
2187 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2190 void testSubArgImmFloat(float a, float b)
2193 BasicBlock* root = proc.addBlock();
2194 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2195 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2196 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2197 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2198 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, constValue);
2199 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2200 root->appendNewControlValue(proc, Return, Origin(), result32);
2202 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - b)));
2205 void testSubImmArgFloat(float a, float b)
2208 BasicBlock* root = proc.addBlock();
2209 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2210 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2211 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2212 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2213 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue, floatValue);
2214 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2215 root->appendNewControlValue(proc, Return, Origin(), result32);
2217 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2220 void testSubImmsFloat(float a, float b)
2223 BasicBlock* root = proc.addBlock();
2224 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2225 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2226 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue1, constValue2);
2227 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2228 root->appendNewControlValue(proc, Return, Origin(), result32);
2230 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a - b)));
2233 void testSubArgFloatWithUselessDoubleConversion(float a)
2236 BasicBlock* root = proc.addBlock();
2237 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
2238 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2239 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
2240 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2241 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble, asDouble);
2242 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2243 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2244 root->appendNewControlValue(proc, Return, Origin(), result32);
2246 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
2249 void testSubArgsFloatWithUselessDoubleConversion(float a, float b)
2252 BasicBlock* root = proc.addBlock();
2253 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2254 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2255 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2256 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2257 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2258 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2259 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
2260 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
2261 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
2262 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2263 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2264 root->appendNewControlValue(proc, Return, Origin(), result32);
2266 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2269 void testSubArgsFloatWithEffectfulDoubleConversion(float a, float b)
2272 BasicBlock* root = proc.addBlock();
2273 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2274 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2275 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2276 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2277 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2278 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2279 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
2280 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
2281 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
2282 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2283 Value* doubleSubress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2284 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleSubress);
2285 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2286 root->appendNewControlValue(proc, Return, Origin(), result32);
2289 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a - b)));
2290 CHECK(isIdentical(effect, static_cast<double>(a) - static_cast<double>(b)));
2293 void testTernarySubInstructionSelection(B3::Opcode valueModifier, Type valueType, Air::Opcode expectedOpcode)
2296 BasicBlock* root = proc.addBlock();
2298 Value* left = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2299 Value* right = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2301 if (valueModifier == Trunc) {
2302 left = root->appendNew<Value>(proc, valueModifier, valueType, Origin(), left);
2303 right = root->appendNew<Value>(proc, valueModifier, valueType, Origin(), right);
2306 root->appendNewControlValue(
2307 proc, Return, Origin(),
2308 root->appendNew<Value>(proc, Sub, Origin(), left, right));
2310 lowerToAirForTesting(proc);
2312 auto block = proc.code()[0];
2313 unsigned numberOfSubInstructions = 0;
2314 for (auto instruction : *block) {
2315 if (instruction.kind.opcode == expectedOpcode) {
2316 CHECK_EQ(instruction.args.size(), 3ul);
2317 CHECK_EQ(instruction.args[0].kind(), Air::Arg::Tmp);
2318 CHECK_EQ(instruction.args[1].kind(), Air::Arg::Tmp);
2319 CHECK_EQ(instruction.args[2].kind(), Air::Arg::Tmp);
2320 numberOfSubInstructions++;
2323 CHECK_EQ(numberOfSubInstructions, 1ul);
2326 void testNegDouble(double a)
2329 BasicBlock* root = proc.addBlock();
2330 root->appendNewControlValue(
2331 proc, Return, Origin(),
2332 root->appendNew<Value>(
2333 proc, Neg, Origin(),
2334 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
2336 CHECK(isIdentical(compileAndRun<double>(proc, a), -a));
2339 void testNegFloat(float a)
2342 BasicBlock* root = proc.addBlock();
2343 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2344 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2345 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2346 root->appendNewControlValue(
2347 proc, Return, Origin(),
2348 root->appendNew<Value>(proc, Neg, Origin(), floatValue));
2350 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), -a));
2353 void testNegFloatWithUselessDoubleConversion(float a)
2356 BasicBlock* root = proc.addBlock();
2357 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
2358 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2359 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
2360 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2361 Value* result = root->appendNew<Value>(proc, Neg, Origin(), asDouble);
2362 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2363 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2365 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), -a));
2368 void testBitAndArgs(int64_t a, int64_t b)
2371 BasicBlock* root = proc.addBlock();
2372 root->appendNewControlValue(
2373 proc, Return, Origin(),
2374 root->appendNew<Value>(
2375 proc, BitAnd, Origin(),
2376 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2377 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2379 CHECK(compileAndRun<int64_t>(proc, a, b) == (a & b));
2382 void testBitAndSameArg(int64_t a)
2385 BasicBlock* root = proc.addBlock();
2386 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2387 root->appendNewControlValue(
2388 proc, Return, Origin(),
2389 root->appendNew<Value>(
2390 proc, BitAnd, Origin(),
2394 CHECK(compileAndRun<int64_t>(proc, a) == a);
2397 void testBitAndImms(int64_t a, int64_t b)
2400 BasicBlock* root = proc.addBlock();
2401 root->appendNewControlValue(
2402 proc, Return, Origin(),
2403 root->appendNew<Value>(
2404 proc, BitAnd, Origin(),
2405 root->appendNew<Const64Value>(proc, Origin(), a),
2406 root->appendNew<Const64Value>(proc, Origin(), b)));
2408 CHECK(compileAndRun<int64_t>(proc) == (a & b));
2411 void testBitAndArgImm(int64_t a, int64_t b)
2414 BasicBlock* root = proc.addBlock();
2415 root->appendNewControlValue(
2416 proc, Return, Origin(),
2417 root->appendNew<Value>(
2418 proc, BitAnd, Origin(),
2419 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2420 root->appendNew<Const64Value>(proc, Origin(), b)));
2422 CHECK(compileAndRun<int64_t>(proc, a) == (a & b));
2425 void testBitAndImmArg(int64_t a, int64_t b)
2428 BasicBlock* root = proc.addBlock();
2429 root->appendNewControlValue(
2430 proc, Return, Origin(),
2431 root->appendNew<Value>(
2432 proc, BitAnd, Origin(),
2433 root->appendNew<Const64Value>(proc, Origin(), a),
2434 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2436 CHECK(compileAndRun<int64_t>(proc, b) == (a & b));
2439 void testBitAndBitAndArgImmImm(int64_t a, int64_t b, int64_t c)
2442 BasicBlock* root = proc.addBlock();
2443 Value* innerBitAnd = root->appendNew<Value>(
2444 proc, BitAnd, Origin(),
2445 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2446 root->appendNew<Const64Value>(proc, Origin(), b));
2447 root->appendNewControlValue(
2448 proc, Return, Origin(),
2449 root->appendNew<Value>(
2450 proc, BitAnd, Origin(),
2452 root->appendNew<Const64Value>(proc, Origin(), c)));
2454 CHECK(compileAndRun<int64_t>(proc, a) == ((a & b) & c));
2457 void testBitAndImmBitAndArgImm(int64_t a, int64_t b, int64_t c)
2460 BasicBlock* root = proc.addBlock();
2461 Value* innerBitAnd = root->appendNew<Value>(
2462 proc, BitAnd, Origin(),
2463 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2464 root->appendNew<Const64Value>(proc, Origin(), c));
2465 root->appendNewControlValue(
2466 proc, Return, Origin(),
2467 root->appendNew<Value>(
2468 proc, BitAnd, Origin(),
2469 root->appendNew<Const64Value>(proc, Origin(), a),
2472 CHECK(compileAndRun<int64_t>(proc, b) == (a & (b & c)));
2475 void testBitAndArgs32(int a, int b)
2478 BasicBlock* root = proc.addBlock();
2479 root->appendNewControlValue(
2480 proc, Return, Origin(),
2481 root->appendNew<Value>(
2482 proc, BitAnd, Origin(),
2483 root->appendNew<Value>(
2484 proc, Trunc, Origin(),
2485 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2486 root->appendNew<Value>(
2487 proc, Trunc, Origin(),
2488 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2490 CHECK(compileAndRun<int>(proc, a, b) == (a & b));
2493 void testBitAndSameArg32(int a)
2496 BasicBlock* root = proc.addBlock();
2497 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2498 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2499 root->appendNewControlValue(
2500 proc, Return, Origin(),
2501 root->appendNew<Value>(
2502 proc, BitAnd, Origin(),
2506 CHECK(compileAndRun<int>(proc, a) == a);
2509 void testBitAndImms32(int a, int b)
2512 BasicBlock* root = proc.addBlock();
2513 root->appendNewControlValue(
2514 proc, Return, Origin(),
2515 root->appendNew<Value>(
2516 proc, BitAnd, Origin(),
2517 root->appendNew<Const32Value>(proc, Origin(), a),
2518 root->appendNew<Const32Value>(proc, Origin(), b)));
2520 CHECK(compileAndRun<int>(proc) == (a & b));
2523 void testBitAndArgImm32(int a, int b)
2526 BasicBlock* root = proc.addBlock();
2527 root->appendNewControlValue(
2528 proc, Return, Origin(),
2529 root->appendNew<Value>(
2530 proc, BitAnd, Origin(),
2531 root->appendNew<Value>(
2532 proc, Trunc, Origin(),
2533 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2534 root->appendNew<Const32Value>(proc, Origin(), b)));
2536 CHECK(compileAndRun<int>(proc, a) == (a & b));
2539 void testBitAndImmArg32(int a, int b)
2542 BasicBlock* root = proc.addBlock();
2543 root->appendNewControlValue(
2544 proc, Return, Origin(),
2545 root->appendNew<Value>(
2546 proc, BitAnd, Origin(),
2547 root->appendNew<Const32Value>(proc, Origin(), a),
2548 root->appendNew<Value>(
2549 proc, Trunc, Origin(),
2550 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2552 CHECK(compileAndRun<int>(proc, b) == (a & b));
2555 void testBitAndBitAndArgImmImm32(int a, int b, int c)
2558 BasicBlock* root = proc.addBlock();
2559 Value* innerBitAnd = root->appendNew<Value>(
2560 proc, BitAnd, Origin(),
2561 root->appendNew<Value>(
2562 proc, Trunc, Origin(),
2563 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2564 root->appendNew<Const32Value>(proc, Origin(), b));
2565 root->appendNewControlValue(
2566 proc, Return, Origin(),
2567 root->appendNew<Value>(
2568 proc, BitAnd, Origin(),
2570 root->appendNew<Const32Value>(proc, Origin(), c)));
2572 CHECK(compileAndRun<int>(proc, a) == ((a & b) & c));
2575 void testBitAndImmBitAndArgImm32(int a, int b, int c)
2578 BasicBlock* root = proc.addBlock();
2579 Value* innerBitAnd = root->appendNew<Value>(
2580 proc, BitAnd, Origin(),
2581 root->appendNew<Value>(
2582 proc, Trunc, Origin(),
2583 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2584 root->appendNew<Const32Value>(proc, Origin(), c));
2585 root->appendNewControlValue(
2586 proc, Return, Origin(),
2587 root->appendNew<Value>(
2588 proc, BitAnd, Origin(),
2589 root->appendNew<Const32Value>(proc, Origin(), a),
2592 CHECK(compileAndRun<int>(proc, b) == (a & (b & c)));
2595 void testBitAndWithMaskReturnsBooleans(int64_t a, int64_t b)
2598 BasicBlock* root = proc.addBlock();
2599 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2600 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2601 Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg0, arg1);
2602 Value* maskedEqual = root->appendNew<Value>(proc, BitAnd, Origin(),
2603 root->appendNew<Const32Value>(proc, Origin(), 0x5),
2605 Value* inverted = root->appendNew<Value>(proc, BitXor, Origin(),
2606 root->appendNew<Const32Value>(proc, Origin(), 0x1),
2608 Value* select = root->appendNew<Value>(proc, Select, Origin(), inverted,
2609 root->appendNew<Const64Value>(proc, Origin(), 42),
2610 root->appendNew<Const64Value>(proc, Origin(), -5));
2612 root->appendNewControlValue(proc, Return, Origin(), select);
2614 int64_t expected = (a == b) ? -5 : 42;
2615 CHECK(compileAndRun<int64_t>(proc, a, b) == expected);
2618 double bitAndDouble(double a, double b)
2620 return bitwise_cast<double>(bitwise_cast<uint64_t>(a) & bitwise_cast<uint64_t>(b));
2623 void testBitAndArgDouble(double a)
2626 BasicBlock* root = proc.addBlock();
2627 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2628 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2629 root->appendNewControlValue(proc, Return, Origin(), result);
2631 CHECK(isIdentical(compileAndRun<double>(proc, a), bitAndDouble(a, a)));
2634 void testBitAndArgsDouble(double a, double b)
2637 BasicBlock* root = proc.addBlock();
2638 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2639 Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
2640 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2641 root->appendNewControlValue(proc, Return, Origin(), result);
2643 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2646 void testBitAndArgImmDouble(double a, double b)
2649 BasicBlock* root = proc.addBlock();
2650 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2651 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2652 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2653 root->appendNewControlValue(proc, Return, Origin(), result);
2655 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2658 void testBitAndImmsDouble(double a, double b)
2661 BasicBlock* root = proc.addBlock();
2662 Value* argumentA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2663 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2664 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2665 root->appendNewControlValue(proc, Return, Origin(), result);
2667 CHECK(isIdentical(compileAndRun<double>(proc), bitAndDouble(a, b)));
2670 float bitAndFloat(float a, float b)
2672 return bitwise_cast<float>(bitwise_cast<uint32_t>(a) & bitwise_cast<uint32_t>(b));
2675 void testBitAndArgFloat(float a)
2678 BasicBlock* root = proc.addBlock();
2679 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2680 root->appendNew<Value>(proc, Trunc, Origin(),
2681 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2682 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2683 root->appendNewControlValue(proc, Return, Origin(), result);
2685 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), bitAndFloat(a, a)));
2688 void testBitAndArgsFloat(float a, float b)
2691 BasicBlock* root = proc.addBlock();
2692 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2693 root->appendNew<Value>(proc, Trunc, Origin(),
2694 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2695 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2696 root->appendNew<Value>(proc, Trunc, Origin(),
2697 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2698 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2699 root->appendNewControlValue(proc, Return, Origin(), result);
2701 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2704 void testBitAndArgImmFloat(float a, float b)
2707 BasicBlock* root = proc.addBlock();
2708 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2709 root->appendNew<Value>(proc, Trunc, Origin(),
2710 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2711 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2712 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2713 root->appendNewControlValue(proc, Return, Origin(), result);
2715 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2718 void testBitAndImmsFloat(float a, float b)
2721 BasicBlock* root = proc.addBlock();
2722 Value* argumentA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2723 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2724 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2725 root->appendNewControlValue(proc, Return, Origin(), result);
2727 CHECK(isIdentical(compileAndRun<float>(proc), bitAndFloat(a, b)));
2730 void testBitAndArgsFloatWithUselessDoubleConversion(float a, float b)
2733 BasicBlock* root = proc.addBlock();
2734 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2735 root->appendNew<Value>(proc, Trunc, Origin(),
2736 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2737 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2738 root->appendNew<Value>(proc, Trunc, Origin(),
2739 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2740 Value* argumentAasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentA);
2741 Value* argumentBasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentB);
2742 Value* doubleResult = root->appendNew<Value>(proc, BitAnd, Origin(), argumentAasDouble, argumentBasDouble);
2743 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleResult);
2744 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2748 float expected = static_cast<float>(bitAndDouble(doubleA, doubleB));
2749 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), expected));
2752 void testBitOrArgs(int64_t a, int64_t b)
2755 BasicBlock* root = proc.addBlock();
2756 root->appendNewControlValue(
2757 proc, Return, Origin(),
2758 root->appendNew<Value>(
2759 proc, BitOr, Origin(),
2760 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2761 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2763 CHECK(compileAndRun<int64_t>(proc, a, b) == (a | b));
2766 void testBitOrSameArg(int64_t a)
2769 BasicBlock* root = proc.addBlock();
2770 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2771 root->appendNewControlValue(
2772 proc, Return, Origin(),
2773 root->appendNew<Value>(
2774 proc, BitOr, Origin(),
2778 CHECK(compileAndRun<int64_t>(proc, a) == a);
2781 void testBitOrImms(int64_t a, int64_t b)
2784 BasicBlock* root = proc.addBlock();
2785 root->appendNewControlValue(
2786 proc, Return, Origin(),
2787 root->appendNew<Value>(
2788 proc, BitOr, Origin(),
2789 root->appendNew<Const64Value>(proc, Origin(), a),
2790 root->appendNew<Const64Value>(proc, Origin(), b)));
2792 CHECK(compileAndRun<int64_t>(proc) == (a | b));
2795 void testBitOrArgImm(int64_t a, int64_t b)
2798 BasicBlock* root = proc.addBlock();
2799 root->appendNewControlValue(
2800 proc, Return, Origin(),
2801 root->appendNew<Value>(
2802 proc, BitOr, Origin(),
2803 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2804 root->appendNew<Const64Value>(proc, Origin(), b)));
2806 CHECK(compileAndRun<int64_t>(proc, a) == (a | b));
2809 void testBitOrImmArg(int64_t a, int64_t b)
2812 BasicBlock* root = proc.addBlock();
2813 root->appendNewControlValue(
2814 proc, Return, Origin(),
2815 root->appendNew<Value>(
2816 proc, BitOr, Origin(),
2817 root->appendNew<Const64Value>(proc, Origin(), a),
2818 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2820 CHECK(compileAndRun<int64_t>(proc, b) == (a | b));
2823 void testBitOrBitOrArgImmImm(int64_t a, int64_t b, int64_t c)
2826 BasicBlock* root = proc.addBlock();
2827 Value* innerBitOr = root->appendNew<Value>(
2828 proc, BitOr, Origin(),
2829 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2830 root->appendNew<Const64Value>(proc, Origin(), b));
2831 root->appendNewControlValue(
2832 proc, Return, Origin(),
2833 root->appendNew<Value>(
2834 proc, BitOr, Origin(),
2836 root->appendNew<Const64Value>(proc, Origin(), c)));
2838 CHECK(compileAndRun<int64_t>(proc, a) == ((a | b) | c));
2841 void testBitOrImmBitOrArgImm(int64_t a, int64_t b, int64_t c)
2844 BasicBlock* root = proc.addBlock();
2845 Value* innerBitOr = root->appendNew<Value>(
2846 proc, BitOr, Origin(),
2847 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2848 root->appendNew<Const64Value>(proc, Origin(), c));
2849 root->appendNewControlValue(
2850 proc, Return, Origin(),
2851 root->appendNew<Value>(
2852 proc, BitOr, Origin(),
2853 root->appendNew<Const64Value>(proc, Origin(), a),
2856 CHECK(compileAndRun<int64_t>(proc, b) == (a | (b | c)));
2859 void testBitOrArgs32(int a, int b)
2862 BasicBlock* root = proc.addBlock();
2863 root->appendNewControlValue(
2864 proc, Return, Origin(),
2865 root->appendNew<Value>(
2866 proc, BitOr, Origin(),
2867 root->appendNew<Value>(
2868 proc, Trunc, Origin(),
2869 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2870 root->appendNew<Value>(
2871 proc, Trunc, Origin(),
2872 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2874 CHECK(compileAndRun<int>(proc, a, b) == (a | b));
2877 void testBitOrSameArg32(int a)
2880 BasicBlock* root = proc.addBlock();
2881 Value* argument = root->appendNew<Value>(
2882 proc, Trunc, Origin(),
2883 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2884 root->appendNewControlValue(
2885 proc, Return, Origin(),
2886 root->appendNew<Value>(
2887 proc, BitOr, Origin(),
2891 CHECK(compileAndRun<int>(proc, a) == a);
2894 void testBitOrImms32(int a, int b)
2897 BasicBlock* root = proc.addBlock();
2898 root->appendNewControlValue(
2899 proc, Return, Origin(),
2900 root->appendNew<Value>(
2901 proc, BitOr, Origin(),
2902 root->appendNew<Const32Value>(proc, Origin(), a),
2903 root->appendNew<Const32Value>(proc, Origin(), b)));
2905 CHECK(compileAndRun<int>(proc) == (a | b));
2908 void testBitOrArgImm32(int a, int b)
2911 BasicBlock* root = proc.addBlock();
2912 root->appendNewControlValue(
2913 proc, Return, Origin(),
2914 root->appendNew<Value>(
2915 proc, BitOr, Origin(),
2916 root->appendNew<Value>(
2917 proc, Trunc, Origin(),
2918 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2919 root->appendNew<Const32Value>(proc, Origin(), b)));
2921 CHECK(compileAndRun<int>(proc, a) == (a | b));
2924 void testBitOrImmArg32(int a, int b)
2927 BasicBlock* root = proc.addBlock();
2928 root->appendNewControlValue(
2929 proc, Return, Origin(),
2930 root->appendNew<Value>(
2931 proc, BitOr, Origin(),
2932 root->appendNew<Const32Value>(proc, Origin(), a),
2933 root->appendNew<Value>(
2934 proc, Trunc, Origin(),
2935 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2937 CHECK(compileAndRun<int>(proc, b) == (a | b));
2940 void testBitOrBitOrArgImmImm32(int a, int b, int c)
2943 BasicBlock* root = proc.addBlock();
2944 Value* innerBitOr = root->appendNew<Value>(
2945 proc, BitOr, Origin(),
2946 root->appendNew<Value>(
2947 proc, Trunc, Origin(),
2948 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2949 root->appendNew<Const32Value>(proc, Origin(), b));
2950 root->appendNewControlValue(
2951 proc, Return, Origin(),
2952 root->appendNew<Value>(
2953 proc, BitOr, Origin(),
2955 root->appendNew<Const32Value>(proc, Origin(), c)));
2957 CHECK(compileAndRun<int>(proc, a) == ((a | b) | c));
2960 void testBitOrImmBitOrArgImm32(int a, int b, int c)
2963 BasicBlock* root = proc.addBlock();
2964 Value* innerBitOr = root->appendNew<Value>(
2965 proc, BitOr, Origin(),
2966 root->appendNew<Value>(
2967 proc, Trunc, Origin(),
2968 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2969 root->appendNew<Const32Value>(proc, Origin(), c));
2970 root->appendNewControlValue(
2971 proc, Return, Origin(),
2972 root->appendNew<Value>(
2973 proc, BitOr, Origin(),
2974 root->appendNew<Const32Value>(proc, Origin(), a),
2977 CHECK(compileAndRun<int>(proc, b) == (a | (b | c)));
2980 void testBitXorArgs(int64_t a, int64_t b)
2983 BasicBlock* root = proc.addBlock();
2984 root->appendNewControlValue(
2985 proc, Return, Origin(),
2986 root->appendNew<Value>(
2987 proc, BitXor, Origin(),
2988 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2989 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2991 CHECK(compileAndRun<int64_t>(proc, a, b) == (a ^ b));
2994 void testBitXorSameArg(int64_t a)
2997 BasicBlock* root = proc.addBlock();
2998 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2999 root->appendNewControlValue(
3000 proc, Return, Origin(),
3001 root->appendNew<Value>(
3002 proc, BitXor, Origin(),
3006 CHECK(!compileAndRun<int64_t>(proc, a));
3009 void testBitXorImms(int64_t a, int64_t b)
3012 BasicBlock* root = proc.addBlock();
3013 root->appendNewControlValue(
3014 proc, Return, Origin(),
3015 root->appendNew<Value>(
3016 proc, BitXor, Origin(),
3017 root->appendNew<Const64Value>(proc, Origin(), a),
3018 root->appendNew<Const64Value>(proc, Origin(), b)));
3020 CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
3023 void testBitXorArgImm(int64_t a, int64_t b)
3026 BasicBlock* root = proc.addBlock();
3027 root->appendNewControlValue(
3028 proc, Return, Origin(),
3029 root->appendNew<Value>(
3030 proc, BitXor, Origin(),
3031 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3032 root->appendNew<Const64Value>(proc, Origin(), b)));
3034 CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
3037 void testBitXorImmArg(int64_t a, int64_t b)
3040 BasicBlock* root = proc.addBlock();
3041 root->appendNewControlValue(
3042 proc, Return, Origin(),
3043 root->appendNew<Value>(
3044 proc, BitXor, Origin(),
3045 root->appendNew<Const64Value>(proc, Origin(), a),
3046 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
3048 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
3051 void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
3054 BasicBlock* root = proc.addBlock();
3055 Value* innerBitXor = root->appendNew<Value>(
3056 proc, BitXor, Origin(),
3057 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3058 root->appendNew<Const64Value>(proc, Origin(), b));
3059 root->appendNewControlValue(
3060 proc, Return, Origin(),
3061 root->appendNew<Value>(
3062 proc, BitXor, Origin(),
3064 root->appendNew<Const64Value>(proc, Origin(), c)));
3066 CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
3069 void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
3072 BasicBlock* root = proc.addBlock();
3073 Value* innerBitXor = root->appendNew<Value>(
3074 proc, BitXor, Origin(),
3075 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3076 root->appendNew<Const64Value>(proc, Origin(), c));
3077 root->appendNewControlValue(
3078 proc, Return, Origin(),
3079 root->appendNew<Value>(
3080 proc, BitXor, Origin(),
3081 root->appendNew<Const64Value>(proc, Origin(), a),
3084 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
3087 void testBitXorArgs32(int a, int b)
3090 BasicBlock* root = proc.addBlock();
3091 root->appendNewControlValue(
3092 proc, Return, Origin(),
3093 root->appendNew<Value>(
3094 proc, BitXor, Origin(),
3095 root->appendNew<Value>(
3096 proc, Trunc, Origin(),
3097 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3098 root->appendNew<Value>(
3099 proc, Trunc, Origin(),
3100 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3102 CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
3105 void testBitXorSameArg32(int a)
3108 BasicBlock* root = proc.addBlock();
3109 Value* argument = root->appendNew<Value>(
3110 proc, Trunc, Origin(),
3111 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3112 root->appendNewControlValue(
3113 proc, Return, Origin(),
3114 root->appendNew<Value>(
3115 proc, BitXor, Origin(),
3119 CHECK(!compileAndRun<int>(proc, a));
3122 void testBitXorImms32(int a, int b)
3125 BasicBlock* root = proc.addBlock();
3126 root->appendNewControlValue(
3127 proc, Return, Origin(),
3128 root->appendNew<Value>(
3129 proc, BitXor, Origin(),
3130 root->appendNew<Const32Value>(proc, Origin(), a),
3131 root->appendNew<Const32Value>(proc, Origin(), b)));
3133 CHECK(compileAndRun<int>(proc) == (a ^ b));
3136 void testBitXorArgImm32(int a, int b)
3139 BasicBlock* root = proc.addBlock();
3140 root->appendNewControlValue(
3141 proc, Return, Origin(),
3142 root->appendNew<Value>(
3143 proc, BitXor, Origin(),
3144 root->appendNew<Value>(
3145 proc, Trunc, Origin(),
3146 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3147 root->appendNew<Const32Value>(proc, Origin(), b)));
3149 CHECK(compileAndRun<int>(proc, a) == (a ^ b));
3152 void testBitXorImmArg32(int a, int b)
3155 BasicBlock* root = proc.addBlock();
3156 root->appendNewControlValue(
3157 proc, Return, Origin(),
3158 root->appendNew<Value>(
3159 proc, BitXor, Origin(),
3160 root->appendNew<Const32Value>(proc, Origin(), a),
3161 root->appendNew<Value>(
3162 proc, Trunc, Origin(),
3163 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
3165 CHECK(compileAndRun<int>(proc, b) == (a ^ b));
3168 void testBitXorBitXorArgImmImm32(int a, int b, int c)
3171 BasicBlock* root = proc.addBlock();
3172 Value* innerBitXor = root->appendNew<Value>(
3173 proc, BitXor, Origin(),
3174 root->appendNew<Value>(
3175 proc, Trunc, Origin(),
3176 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3177 root->appendNew<Const32Value>(proc, Origin(), b));
3178 root->appendNewControlValue(
3179 proc, Return, Origin(),
3180 root->appendNew<Value>(
3181 proc, BitXor, Origin(),
3183 root->appendNew<Const32Value>(proc, Origin(), c)));
3185 CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
3188 void testBitXorImmBitXorArgImm32(int a, int b, int c)
3191 BasicBlock* root = proc.addBlock();
3192 Value* innerBitXor = root->appendNew<Value>(
3193 proc, BitXor, Origin(),
3194 root->appendNew<Value>(
3195 proc, Trunc, Origin(),
3196 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3197 root->appendNew<Const32Value>(proc, Origin(), c));
3198 root->appendNewControlValue(
3199 proc, Return, Origin(),
3200 root->appendNew<Value>(
3201 proc, BitXor, Origin(),
3202 root->appendNew<Const32Value>(proc, Origin(), a),
3205 CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
3208 void testBitNotArg(int64_t a)
3211 BasicBlock* root = proc.addBlock();
3212 root->appendNewControlValue(
3213 proc, Return, Origin(),
3214 root->appendNew<Value>(
3215 proc, BitXor, Origin(),
3216 root->appendNew<Const64Value>(proc, Origin(), -1),
3217 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
3219 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
3222 void testBitNotImm(int64_t a)
3225 BasicBlock* root = proc.addBlock();
3226 root->appendNewControlValue(
3227 proc, Return, Origin(),
3228 root->appendNew<Value>(
3229 proc, BitXor, Origin(),
3230 root->appendNew<Const64Value>(proc, Origin(), -1),
3231 root->appendNew<Const64Value>(proc, Origin(), a)));
3233 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
3236 void testBitNotMem(int64_t a)
3239 BasicBlock* root = proc.addBlock();
3240 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3241 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
3242 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
3243 root->appendNew<Const64Value>(proc, Origin(), -1),
3245 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
3246 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3249 compileAndRun<int32_t>(proc, &input);
3250 CHECK(isIdentical(input, static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
3253 void testBitNotArg32(int32_t a)
3256 BasicBlock* root = proc.addBlock();
3257 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
3258 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3259 root->appendNewControlValue(
3260 proc, Return, Origin(),
3261 root->appendNew<Value>(proc, BitXor, Origin(),
3262 root->appendNew<Const32Value>(proc, Origin(), -1),
3264 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
3267 void testBitNotImm32(int32_t a)
3270 BasicBlock* root = proc.addBlock();
3271 root->appendNewControlValue(
3272 proc, Return, Origin(),
3273 root->appendNew<Value>(
3274 proc, BitXor, Origin(),
3275 root->appendNew<Const32Value>(proc, Origin(), -1),
3276 root->appendNew<Const32Value>(proc, Origin(), a)));
3278 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
3281 void testBitNotMem32(int32_t a)
3284 BasicBlock* root = proc.addBlock();
3285 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3286 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
3287 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
3288 root->appendNew<Const32Value>(proc, Origin(), -1),
3290 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
3291 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3294 compileAndRun<int32_t>(proc, &input);
3295 CHECK(isIdentical(input, static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
3298 void testBitNotOnBooleanAndBranch32(int64_t a, int64_t b)
3301 BasicBlock* root = proc.addBlock();
3302 BasicBlock* thenCase = proc.addBlock();
3303 BasicBlock* elseCase = proc.addBlock();
3305 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
3306 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3307 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
3308 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
3309 Value* argsAreEqual = root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2);
3310 Value* argsAreNotEqual = root->appendNew<Value>(proc, BitXor, Origin(),
3311 root->appendNew<Const32Value>(proc, Origin(), -1),
3314 root->appendNewControlValue(
3315 proc, Branch, Origin(),
3317 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
3319 thenCase->appendNewControlValue(
3320 proc, Return, Origin(),
3321 thenCase->appendNew<Const32Value>(proc, Origin(), 42));
3323 elseCase->appendNewControlValue(
3324 proc, Return, Origin(),
3325 elseCase->appendNew<Const32Value>(proc, Origin(), -42));
3327 int32_t expectedValue = (a != b) ? 42 : -42;
3328 CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
3331 void testShlArgs(int64_t a, int64_t b)
3334 BasicBlock* root = proc.addBlock();
3335 root->appendNewControlValue(
3336 proc, Return, Origin(),
3337 root->appendNew<Value>(
3338 proc, Shl, Origin(),
3339 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3340 root->appendNew<Value>(
3341 proc, Trunc, Origin(),
3342 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3344 CHECK(compileAndRun<int64_t>(proc, a, b) == (a << b));
3347 void testShlImms(int64_t a, int64_t b)
3350 BasicBlock* root = proc.addBlock();
3351 root->appendNewControlValue(
3352 proc, Return, Origin(),
3353 root->appendNew<Value>(
3354 proc, Shl, Origin(),
3355 root->appendNew<Const64Value>(proc, Origin(), a),
3356 root->appendNew<Const32Value>(proc, Origin(), b)));
3358 CHECK(compileAndRun<int64_t>(proc) == (a << b));
3361 void testShlArgImm(int64_t a, int64_t b)
3364 BasicBlock* root = proc.addBlock();
3365 root->appendNewControlValue(
3366 proc, Return, Origin(),
3367 root->appendNew<Value>(
3368 proc, Shl, Origin(),
3369 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3370 root->appendNew<Const32Value>(proc, Origin(), b)));
3372 CHECK(compileAndRun<int64_t>(proc, a) == (a << b));
3375 void testShlArg32(int32_t a)
3378 BasicBlock* root = proc.addBlock();
3379 Value* value = root->appendNew<Value>(
3380 proc, Trunc, Origin(),
3381 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3382 root->appendNewControlValue(
3383 proc, Return, Origin(),
3384 root->appendNew<Value>(proc, Shl, Origin(), value, value));
3386 CHECK(compileAndRun<int32_t>(proc, a) == (a << a));
3389 void testShlArgs32(int32_t a, int32_t b)
3392 BasicBlock* root = proc.addBlock();
3393 root->appendNewControlValue(
3394 proc, Return, Origin(),
3395 root->appendNew<Value>(
3396 proc, Shl, Origin(),
3397 root->appendNew<Value>(
3398 proc, Trunc, Origin(),
3399 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3400 root->appendNew<Value>(
3401 proc, Trunc, Origin(),
3402 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3404 CHECK(compileAndRun<int32_t>(proc, a, b) == (a << b));
3407 void testShlImms32(int32_t a, int32_t b)
3410 BasicBlock* root = proc.addBlock();
3411 root->appendNewControlValue(
3412 proc, Return, Origin(),
3413 root->appendNew<Value>(
3414 proc, Shl, Origin(),
3415 root->appendNew<Const32Value>(proc, Origin(), a),
3416 root->appendNew<Const32Value>(proc, Origin(), b)));
3418 CHECK(compileAndRun<int32_t>(proc) == (a << b));
3421 void testShlArgImm32(int32_t a, int32_t b)
3424 BasicBlock* root = proc.addBlock();
3425 root->appendNewControlValue(
3426 proc, Return, Origin(),
3427 root->appendNew<Value>(
3428 proc, Shl, Origin(),
3429 root->appendNew<Value>(
3430 proc, Trunc, Origin(),
3431 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3432 root->appendNew<Const32Value>(proc, Origin(), b)));
3434 CHECK(compileAndRun<int32_t>(proc, a) == (a << b));
3437 void testSShrArgs(int64_t a, int64_t b)
3440 BasicBlock* root = proc.addBlock();
3441 root->appendNewControlValue(
3442 proc, Return, Origin(),
3443 root->appendNew<Value>(
3444 proc, SShr, Origin(),
3445 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3446 root->appendNew<Value>(
3447 proc, Trunc, Origin(),
3448 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3450 CHECK(compileAndRun<int64_t>(proc, a, b) == (a >> b));
3453 void testSShrImms(int64_t a, int64_t b)
3456 BasicBlock* root = proc.addBlock();
3457 root->appendNewControlValue(
3458 proc, Return, Origin(),
3459 root->appendNew<Value>(
3460 proc, SShr, Origin(),
3461 root->appendNew<Const64Value>(proc, Origin(), a),
3462 root->appendNew<Const32Value>(proc, Origin(), b)));
3464 CHECK(compileAndRun<int64_t>(proc) == (a >> b));
3467 void testSShrArgImm(int64_t a, int64_t b)
3470 BasicBlock* root = proc.addBlock();
3471 root->appendNewControlValue(
3472 proc, Return, Origin(),
3473 root->appendNew<Value>(
3474 proc, SShr, Origin(),
3475 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3476 root->appendNew<Const32Value>(proc, Origin(), b)));
3478 CHECK(compileAndRun<int64_t>(proc, a) == (a >> b));
3481 void testSShrArg32(int32_t a)
3484 BasicBlock* root = proc.addBlock();
3485 Value* value = root->appendNew<Value>(
3486 proc, Trunc, Origin(),
3487 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3488 root->appendNewControlValue(
3489 proc, Return, Origin(),
3490 root->appendNew<Value>(proc, SShr, Origin(), value, value));
3492 CHECK(compileAndRun<int32_t>(proc, a) == (a >> (a & 31)));
3495 void testSShrArgs32(int32_t a, int32_t b)
3498 BasicBlock* root = proc.addBlock();
3499 root->appendNewControlValue(
3500 proc, Return, Origin(),
3501 root->appendNew<Value>(
3502 proc, SShr, Origin(),
3503 root->appendNew<Value>(
3504 proc, Trunc, Origin(),
3505 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3506 root->appendNew<Value>(
3507 proc, Trunc, Origin(),
3508 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3510 CHECK(compileAndRun<int32_t>(proc, a, b) == (a >> b));
3513 void testSShrImms32(int32_t a, int32_t b)
3516 BasicBlock* root = proc.addBlock();
3517 root->appendNewControlValue(
3518 proc, Return, Origin(),
3519 root->appendNew<Value>(
3520 proc, SShr, Origin(),
3521 root->appendNew<Const32Value>(proc, Origin(), a),
3522 root->appendNew<Const32Value>(proc, Origin(), b)));
3524 CHECK(compileAndRun<int32_t>(proc) == (a >> b));
3527 void testSShrArgImm32(int32_t a, int32_t b)
3530 BasicBlock* root = proc.addBlock();
3531 root->appendNewControlValue(
3532 proc, Return, Origin(),
3533 root->appendNew<Value>(
3534 proc, SShr, Origin(),
3535 root->appendNew<Value>(
3536 proc, Trunc, Origin(),
3537 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3538 root->appendNew<Const32Value>(proc, Origin(), b)));
3540 CHECK(compileAndRun<int32_t>(proc, a) == (a >> b));
3543 void testZShrArgs(uint64_t a, uint64_t b)
3546 BasicBlock* root = proc.addBlock();
3547 root->appendNewControlValue(
3548 proc, Return, Origin(),
3549 root->appendNew<Value>(
3550 proc, ZShr, Origin(),
3551 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3552 root->appendNew<Value>(
3553 proc, Trunc, Origin(),
3554 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3556 CHECK(compileAndRun<uint64_t>(proc, a, b) == (a >> b));
3559 void testZShrImms(uint64_t a, uint64_t b)
3562 BasicBlock* root = proc.addBlock();
3563 root->appendNewControlValue(
3564 proc, Return, Origin(),
3565 root->appendNew<Value>(
3566 proc, ZShr, Origin(),
3567 root->appendNew<Const64Value>(proc, Origin(), a),
3568 root->appendNew<Const32Value>(proc, Origin(), b)));
3570 CHECK(compileAndRun<uint64_t>(proc) == (a >> b));
3573 void testZShrArgImm(uint64_t a, uint64_t b)
3576 BasicBlock* root = proc.addBlock();
3577 root->appendNewControlValue(
3578 proc, Return, Origin(),
3579 root->appendNew<Value>(
3580 proc, ZShr, Origin(),
3581 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3582 root->appendNew<Const32Value>(proc, Origin(), b)));
3584 CHECK(compileAndRun<uint64_t>(proc, a) == (a >> b));
3587 void testZShrArg32(uint32_t a)
3590 BasicBlock* root = proc.addBlock();
3591 Value* value = root->appendNew<Value>(
3592 proc, Trunc, Origin(),
3593 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3594 root->appendNewControlValue(
3595 proc, Return, Origin(),
3596 root->appendNew<Value>(proc, ZShr, Origin(), value, value));
3598 CHECK(compileAndRun<uint32_t>(proc, a) == (a >> (a & 31)));
3601 void testZShrArgs32(uint32_t a, uint32_t b)
3604 BasicBlock* root = proc.addBlock();
3605 root->appendNewControlValue(
3606 proc, Return, Origin(),
3607 root->appendNew<Value>(
3608 proc, ZShr, Origin(),
3609 root->appendNew<Value>(
3610 proc, Trunc, Origin(),
3611 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3612 root->appendNew<Value>(
3613 proc, Trunc, Origin(),
3614 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3616 CHECK(compileAndRun<uint32_t>(proc, a, b) == (a >> b));
3619 void testZShrImms32(uint32_t a, uint32_t b)
3622 BasicBlock* root = proc.addBlock();
3623 root->appendNewControlValue(
3624 proc, Return, Origin(),
3625 root->appendNew<Value>(
3626 proc, ZShr, Origin(),
3627 root->appendNew<Const32Value>(proc, Origin(), a),
3628 root->appendNew<Const32Value>(proc, Origin(), b)));
3630 CHECK(compileAndRun<uint32_t>(proc) == (a >> b));
3633 void testZShrArgImm32(uint32_t a, uint32_t b)
3636 BasicBlock* root = proc.addBlock();
3637 root->appendNewControlValue(
3638 proc, Return, Origin(),
3639 root->appendNew<Value>(
3640 proc, ZShr, Origin(),
3641 root->appendNew<Value>(
3642 proc, Trunc, Origin(),
3643 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3644 root->appendNew<Const32Value>(proc, Origin(), b)));
3646 CHECK(compileAndRun<uint32_t>(proc, a) == (a >> b));
3649 template<typename IntegerType>
3650 static unsigned countLeadingZero(IntegerType value)
3652 unsigned bitCount = sizeof(IntegerType) * 8;
3656 unsigned counter = 0;
3657 while (!(static_cast<uint64_t>(value) & (1l << (bitCount - 1)))) {
3664 void testClzArg64(int64_t a)
3667 BasicBlock* root = proc.addBlock();
3668 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3669 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
3670 root->appendNewControlValue(proc, Return, Origin(), clzValue);
3671 CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
3674 void testClzMem64(int64_t a)
3677 BasicBlock* root = proc.addBlock();
3678 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3679 MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
3680 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
3681 root->appendNewControlValue(proc, Return, Origin(), clzValue);
3682 CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
3685 void testClzArg32(int32_t a)
3688 BasicBlock* root = proc.addBlock();
3689 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
3690 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3691 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
3692 root->appendNewControlValue(proc, Return, Origin(), clzValue);
3693 CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
3696 void testClzMem32(int32_t a)
3699 BasicBlock* root = proc.addBlock();
3700 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3701 MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
3702 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
3703 root->appendNewControlValue(proc, Return, Origin(), clzValue);
3704 CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
3707 void testAbsArg(double a)
3710 BasicBlock* root = proc.addBlock();
3711 root->appendNewControlValue(
3712 proc, Return, Origin(),
3713 root->appendNew<Value>(
3714 proc, Abs, Origin(),
3715 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
3717 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
3720 void testAbsImm(double a)
3723 BasicBlock* root = proc.addBlock();
3724 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
3725 root->appendNewControlValue(
3726 proc, Return, Origin(),
3727 root->appendNew<Value>(proc, Abs, Origin(), argument));
3729 CHECK(isIdentical(compileAndRun<double>(proc), fabs(a)));
3732 void testAbsMem(double a)
3735 BasicBlock* root = proc.addBlock();
3736 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3737 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3738 root->appendNewControlValue(
3739 proc, Return, Origin(),
3740 root->appendNew<Value>(proc, Abs, Origin(), loadDouble));
3742 CHECK(isIdentical(compileAndRun<double>(proc, &a), fabs(a)));
3745 void testAbsAbsArg(double a)
3748 BasicBlock* root = proc.addBlock();
3749 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(),
3750 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
3751 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
3752 root->appendNewControlValue(proc, Return, Origin(), secondAbs);
3754 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
3757 void testAbsBitwiseCastArg(double a)
3760 BasicBlock* root = proc.addBlock();
3761 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3762 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
3763 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
3764 root->appendNewControlValue(proc, Return, Origin(), absValue);
3766 CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int64_t>(a)), fabs(a)));
3769 void testBitwiseCastAbsBitwiseCastArg(double a)
3772 BasicBlock* root = proc.addBlock();
3773 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3774 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
3775 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
3776 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
3778 root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
3780 int64_t expectedResult = bitwise_cast<int64_t>(fabs(a));
3781 CHECK(isIdentical(compileAndRun<int64_t>(proc, bitwise_cast<int64_t>(a)), expectedResult));
3784 void testAbsArg(float a)
3787 BasicBlock* root = proc.addBlock();
3788 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3789 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3790 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3791 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
3792 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3793 root->appendNewControlValue(proc, Return, Origin(), result32);
3795 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3798 void testAbsImm(float a)
3801 BasicBlock* root = proc.addBlock();
3802 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
3803 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
3804 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3805 root->appendNewControlValue(proc, Return, Origin(), result32);
3807 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3810 void testAbsMem(float a)
3813 BasicBlock* root = proc.addBlock();
3814 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3815 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
3816 Value* result = root->appendNew<Value>(proc, Abs, Origin(), loadFloat);
3817 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3818 root->appendNewControlValue(proc, Return, Origin(), result32);
3820 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3823 void testAbsAbsArg(float a)
3826 BasicBlock* root = proc.addBlock();
3827 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3828 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3829 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3830 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(), argument);
3831 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
3832 root->appendNewControlValue(proc, Return, Origin(), secondAbs);
3834 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
3837 void testAbsBitwiseCastArg(float a)
3840 BasicBlock* root = proc.addBlock();
3841 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
3842 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3843 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
3844 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
3845 root->appendNewControlValue(proc, Return, Origin(), absValue);
3847 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
3850 void testBitwiseCastAbsBitwiseCastArg(float a)
3853 BasicBlock* root = proc.addBlock();
3854 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
3855 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3856 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
3857 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
3858 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
3860 root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
3862 int32_t expectedResult = bitwise_cast<int32_t>(static_cast<float>(fabs(a)));
3863 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), expectedResult));
3866 void testAbsArgWithUselessDoubleConversion(float a)
3869 BasicBlock* root = proc.addBlock();
3870 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3871 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3872 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3873 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3874 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
3875 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3876 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3877 root->appendNewControlValue(proc, Return, Origin(), result32);
3879 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3882 void testAbsArgWithEffectfulDoubleConversion(float a)
3885 BasicBlock* root = proc.addBlock();
3886 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3887 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3888 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3889 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3890 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
3891 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3892 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3893 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3894 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
3895 root->appendNewControlValue(proc, Return, Origin(), result32);
3898 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
3899 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3900 CHECK(isIdentical(effect, static_cast<double>(fabs(a))));
3903 void testCeilArg(double a)
3906 BasicBlock* root = proc.addBlock();
3907 root->appendNewControlValue(
3908 proc, Return, Origin(),
3909 root->appendNew<Value>(
3910 proc, Ceil, Origin(),
3911 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
3913 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
3916 void testCeilImm(double a)
3919 BasicBlock* root = proc.addBlock();
3920 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
3921 root->appendNewControlValue(
3922 proc, Return, Origin(),
3923 root->appendNew<Value>(proc, Ceil, Origin(), argument));
3925 CHECK(isIdentical(compileAndRun<double>(proc), ceil(a)));
3928 void testCeilMem(double a)
3931 BasicBlock* root = proc.addBlock();
3932 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3933 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3934 root->appendNewControlValue(
3935 proc, Return, Origin(),
3936 root->appendNew<Value>(proc, Ceil, Origin(), loadDouble));
3938 CHECK(isIdentical(compileAndRun<double>(proc, &a), ceil(a)));
3941 void testCeilCeilArg(double a)
3944 BasicBlock* root = proc.addBlock();
3945 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
3946 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
3947 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
3948 root->appendNewControlValue(proc, Return, Origin(), secondCeil);
3950 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
3953 void testFloorCeilArg(double a)
3956 BasicBlock* root = proc.addBlock();
3957 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
3958 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
3959 Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
3960 root->appendNewControlValue(proc, Return, Origin(), wrappingFloor);
3962 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
3965 void testCeilIToD64(int64_t a)
3968 BasicBlock* root = proc.addBlock();
3969 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3970 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
3972 root->appendNewControlValue(
3973 proc, Return, Origin(),
3974 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
3976 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
3979 void testCeilIToD32(int64_t a)
3982 BasicBlock* root = proc.addBlock();
3983 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
3984 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3985 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
3987 root->appendNewControlValue(
3988 proc, Return, Origin(),
3989 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
3991 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
3994 void testCeilArg(float a)
3997 BasicBlock* root = proc.addBlock();
3998 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3999 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
4000 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
4001 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
4002 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
4003 root->appendNewControlValue(proc, Return, Origin(), result32);
4005 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
4008 void testCeilImm(float a)
4011 BasicBlock* root = proc.addBlock();
4012 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
4013 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
4014 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
4015 root->appendNewControlValue(proc, Return, Origin(), result32);
4017 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
4020 void testCeilMem(float a)
4023 BasicBlock* root = proc.addBlock();
4024 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
4025 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
4026 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), loadFloat);
4027 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
4028 root->appendNewControlValue(proc, Return, Origin(), result32);
4030 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(ceilf(a))));
4033 void testCeilCeilArg(float a)
4036 BasicBlock* root = proc.addBlock();
4037 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
4038 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
4039 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
4040 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
4041 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
4042 root->appendNewControlValue(proc, Return, Origin(), secondCeil);
4044 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
4047 void testFloorCeilArg(float a)
4050 BasicBlock* root = proc.addBlock();
4051 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
4052 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
4053 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
4054 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
4055 Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
4056 root->appendNewControlValue(proc, Return, Origin(), wrappingFloor);
4058 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
4061 void testCeilArgWithUselessDoubleConversion(float a)
4064 BasicBlock* root = proc.addBlock();
4065 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
4066 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
4067 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
4068 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
4069 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
4070 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
4071 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
4072 root->appendNewControlValue(proc, Return, Origin(), result32);
4074 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
4077 void testCeilArgWithEffectfulDoubleConversion(float a)
4080 BasicBlock* root = proc.addBlock();
4081 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
4082 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));