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 "CCallHelpers.h"
60 #include "InitializeThreading.h"
61 #include "JSCInlines.h"
62 #include "LinkBuffer.h"
67 #include <wtf/ListDump.h>
69 #include <wtf/NumberOfCores.h>
70 #include <wtf/Threading.h>
72 // We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
73 static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
77 dataLog("Usage: testb3 [<filter>]\n");
78 if (hiddenTruthBecauseNoReturnIsStupid())
85 using namespace JSC::B3;
89 bool shouldBeVerbose()
91 return shouldDumpIR(B3Mode);
96 // Nothing fancy for now; we just use the existing WTF assertion machinery.
97 #define CHECK(x) do { \
101 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #x); \
105 #define CHECK_EQ(x, y) do { \
111 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, toCString(#x " == " #y, " (" #x " == ", __x, ", " #y " == ", __y, ")").data()); \
117 std::unique_ptr<Compilation> compile(Procedure& procedure, unsigned optLevel = 1)
119 return std::make_unique<Compilation>(*vm, procedure, optLevel);
122 template<typename T, typename... Arguments>
123 T invoke(MacroAssemblerCodePtr ptr, Arguments... arguments)
125 T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(ptr.executableAddress());
126 return function(arguments...);
129 template<typename T, typename... Arguments>
130 T invoke(const Compilation& code, Arguments... arguments)
132 return invoke<T>(code.code(), arguments...);
135 template<typename T, typename... Arguments>
136 T compileAndRun(Procedure& procedure, Arguments... arguments)
138 return invoke<T>(*compile(procedure), arguments...);
141 void lowerToAirForTesting(Procedure& proc)
143 proc.resetReachability();
145 if (shouldBeVerbose())
146 dataLog("B3 before lowering:\n", proc);
151 if (shouldBeVerbose())
152 dataLog("Air after lowering:\n", proc.code());
154 Air::validate(proc.code());
157 void checkUsesInstruction(Compilation& compilation, const char* text)
159 CString disassembly = compilation.disassembly();
160 if (strstr(disassembly.data(), text))
164 dataLog("Bad lowering! Expected to find ", text, " but didn't:\n");
165 dataLog(disassembly);
169 void checkDoesNotUseInstruction(Compilation& compilation, const char* text)
171 CString disassembly = compilation.disassembly();
172 if (!strstr(disassembly.data(), text))
176 dataLog("Bad lowering! Did not expected to find ", text, " but it's there:\n");
177 dataLog(disassembly);
181 template<typename Type>
187 typedef Operand<int64_t> Int64Operand;
188 typedef Operand<int32_t> Int32Operand;
190 template<typename FloatType>
191 void populateWithInterestingValues(Vector<Operand<FloatType>>& operands)
193 operands.append({ "0.", static_cast<FloatType>(0.) });
194 operands.append({ "-0.", static_cast<FloatType>(-0.) });
195 operands.append({ "0.4", static_cast<FloatType>(0.5) });
196 operands.append({ "-0.4", static_cast<FloatType>(-0.5) });
197 operands.append({ "0.5", static_cast<FloatType>(0.5) });
198 operands.append({ "-0.5", static_cast<FloatType>(-0.5) });
199 operands.append({ "0.6", static_cast<FloatType>(0.5) });
200 operands.append({ "-0.6", static_cast<FloatType>(-0.5) });
201 operands.append({ "1.", static_cast<FloatType>(1.) });
202 operands.append({ "-1.", static_cast<FloatType>(-1.) });
203 operands.append({ "2.", static_cast<FloatType>(2.) });
204 operands.append({ "-2.", static_cast<FloatType>(-2.) });
205 operands.append({ "M_PI", static_cast<FloatType>(M_PI) });
206 operands.append({ "-M_PI", static_cast<FloatType>(-M_PI) });
207 operands.append({ "min", std::numeric_limits<FloatType>::min() });
208 operands.append({ "max", std::numeric_limits<FloatType>::max() });
209 operands.append({ "lowest", std::numeric_limits<FloatType>::lowest() });
210 operands.append({ "epsilon", std::numeric_limits<FloatType>::epsilon() });
211 operands.append({ "infiniti", std::numeric_limits<FloatType>::infinity() });
212 operands.append({ "-infiniti", - std::numeric_limits<FloatType>::infinity() });
213 operands.append({ "PNaN", static_cast<FloatType>(PNaN) });
216 template<typename FloatType>
217 Vector<Operand<FloatType>> floatingPointOperands()
219 Vector<Operand<FloatType>> operands;
220 populateWithInterestingValues(operands);
224 static Vector<Int64Operand> int64Operands()
226 Vector<Int64Operand> operands;
227 operands.append({ "0", 0 });
228 operands.append({ "1", 1 });
229 operands.append({ "-1", -1 });
230 operands.append({ "42", 42 });
231 operands.append({ "-42", -42 });
232 operands.append({ "int64-max", std::numeric_limits<int64_t>::max() });
233 operands.append({ "int64-min", std::numeric_limits<int64_t>::min() });
234 operands.append({ "int32-max", std::numeric_limits<int32_t>::max() });
235 operands.append({ "int32-min", std::numeric_limits<int32_t>::min() });
240 static Vector<Int32Operand> int32Operands()
242 Vector<Int32Operand> operands({
248 { "int32-max", std::numeric_limits<int32_t>::max() },
249 { "int32-min", std::numeric_limits<int32_t>::min() }
254 void add32(CCallHelpers& jit, GPRReg src1, GPRReg src2, GPRReg dest)
257 jit.add32(src1, dest);
259 jit.move(src1, dest);
260 jit.add32(src2, dest);
267 BasicBlock* root = proc.addBlock();
268 Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
269 root->appendNewControlValue(proc, Return, Origin(), const42);
271 CHECK(compileAndRun<int>(proc) == 42);
277 BasicBlock* root = proc.addBlock();
279 root->appendNewControlValue(
280 proc, Return, Origin(),
281 root->appendNew<MemoryValue>(
282 proc, Load, Int32, Origin(),
283 root->appendNew<ConstPtrValue>(proc, Origin(), &x)));
285 CHECK(compileAndRun<int>(proc) == 42);
288 void testLoadWithOffsetImpl(int32_t offset64, int32_t offset32)
292 BasicBlock* root = proc.addBlock();
294 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
295 root->appendNewControlValue(
296 proc, Return, Origin(),
297 root->appendNew<MemoryValue>(
298 proc, Load, Int64, Origin(),
302 char* address = reinterpret_cast<char*>(&x) - offset64;
303 CHECK(compileAndRun<int64_t>(proc, address) == -42);
307 BasicBlock* root = proc.addBlock();
309 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
310 root->appendNewControlValue(
311 proc, Return, Origin(),
312 root->appendNew<MemoryValue>(
313 proc, Load, Int32, Origin(),
317 char* address = reinterpret_cast<char*>(&x) - offset32;
318 CHECK(compileAndRun<int32_t>(proc, address) == -42);
322 void testLoadOffsetImm9Max()
324 testLoadWithOffsetImpl(255, 255);
327 void testLoadOffsetImm9MaxPlusOne()
329 testLoadWithOffsetImpl(256, 256);
332 void testLoadOffsetImm9MaxPlusTwo()
334 testLoadWithOffsetImpl(257, 257);
337 void testLoadOffsetImm9Min()
339 testLoadWithOffsetImpl(-256, -256);
342 void testLoadOffsetImm9MinMinusOne()
344 testLoadWithOffsetImpl(-257, -257);
347 void testLoadOffsetScaledUnsignedImm12Max()
349 testLoadWithOffsetImpl(32760, 16380);
352 void testLoadOffsetScaledUnsignedOverImm12Max()
354 testLoadWithOffsetImpl(32760, 32760);
355 testLoadWithOffsetImpl(32761, 16381);
356 testLoadWithOffsetImpl(32768, 16384);
359 void testArg(int argument)
362 BasicBlock* root = proc.addBlock();
363 root->appendNewControlValue(
364 proc, Return, Origin(),
365 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
367 CHECK(compileAndRun<int>(proc, argument) == argument);
370 void testReturnConst64(int64_t value)
373 BasicBlock* root = proc.addBlock();
374 root->appendNewControlValue(
375 proc, Return, Origin(),
376 root->appendNew<Const64Value>(proc, Origin(), value));
378 CHECK(compileAndRun<int64_t>(proc) == value);
381 void testReturnVoid()
384 BasicBlock* root = proc.addBlock();
385 root->appendNewControlValue(proc, Return, Origin());
386 compileAndRun<void>(proc);
389 void testAddArg(int a)
392 BasicBlock* root = proc.addBlock();
393 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
394 root->appendNewControlValue(
395 proc, Return, Origin(),
396 root->appendNew<Value>(proc, Add, Origin(), value, value));
398 CHECK(compileAndRun<int>(proc, a) == a + a);
401 void testAddArgs(int a, int b)
404 BasicBlock* root = proc.addBlock();
405 root->appendNewControlValue(
406 proc, Return, Origin(),
407 root->appendNew<Value>(
409 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
410 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
412 CHECK(compileAndRun<int>(proc, a, b) == a + b);
415 void testAddArgImm(int a, int b)
418 BasicBlock* root = proc.addBlock();
419 root->appendNewControlValue(
420 proc, Return, Origin(),
421 root->appendNew<Value>(
423 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
424 root->appendNew<Const64Value>(proc, Origin(), b)));
426 CHECK(compileAndRun<int>(proc, a) == a + b);
429 void testAddImmArg(int a, int b)
432 BasicBlock* root = proc.addBlock();
433 root->appendNewControlValue(
434 proc, Return, Origin(),
435 root->appendNew<Value>(
437 root->appendNew<Const64Value>(proc, Origin(), a),
438 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
440 CHECK(compileAndRun<int>(proc, b) == a + b);
443 void testAddArgMem(int64_t a, int64_t b)
446 BasicBlock* root = proc.addBlock();
447 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
448 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
449 Value* result = root->appendNew<Value>(proc, Add, Origin(),
450 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
452 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
453 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
455 int64_t inputOutput = b;
456 CHECK(!compileAndRun<int64_t>(proc, a, &inputOutput));
457 CHECK(inputOutput == a + b);
460 void testAddMemArg(int64_t a, int64_t b)
463 BasicBlock* root = proc.addBlock();
464 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
465 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
466 Value* result = root->appendNew<Value>(proc, Add, Origin(),
468 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
469 root->appendNewControlValue(proc, Return, Origin(), result);
471 CHECK(compileAndRun<int64_t>(proc, &a, b) == a + b);
474 void testAddImmMem(int64_t a, int64_t b)
477 BasicBlock* root = proc.addBlock();
478 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
479 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
480 Value* result = root->appendNew<Value>(proc, Add, Origin(),
481 root->appendNew<Const64Value>(proc, Origin(), a),
483 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
484 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
486 int64_t inputOutput = b;
487 CHECK(!compileAndRun<int>(proc, &inputOutput));
488 CHECK(inputOutput == a + b);
491 void testAddArg32(int a)
494 BasicBlock* root = proc.addBlock();
495 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
496 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
497 root->appendNewControlValue(
498 proc, Return, Origin(),
499 root->appendNew<Value>(proc, Add, Origin(), value, value));
501 CHECK(compileAndRun<int>(proc, a) == a + a);
504 void testAddArgs32(int a, int b)
507 BasicBlock* root = proc.addBlock();
508 root->appendNewControlValue(
509 proc, Return, Origin(),
510 root->appendNew<Value>(
512 root->appendNew<Value>(
513 proc, Trunc, Origin(),
514 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
515 root->appendNew<Value>(
516 proc, Trunc, Origin(),
517 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
519 CHECK(compileAndRun<int>(proc, a, b) == a + b);
522 void testAddArgMem32(int32_t a, int32_t b)
525 BasicBlock* root = proc.addBlock();
526 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
527 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
528 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
529 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
530 Value* result = root->appendNew<Value>(proc, Add, Origin(), argument, load);
531 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
532 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
534 int32_t inputOutput = b;
535 CHECK(!compileAndRun<int32_t>(proc, a, &inputOutput));
536 CHECK(inputOutput == a + b);
539 void testAddMemArg32(int32_t a, int32_t b)
542 BasicBlock* root = proc.addBlock();
543 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
544 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
545 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
546 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
547 Value* result = root->appendNew<Value>(proc, Add, Origin(), load, argument);
548 root->appendNewControlValue(proc, Return, Origin(), result);
550 CHECK(compileAndRun<int32_t>(proc, &a, b) == a + b);
553 void testAddImmMem32(int32_t a, int32_t b)
556 BasicBlock* root = proc.addBlock();
557 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
558 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
559 Value* result = root->appendNew<Value>(proc, Add, Origin(),
560 root->appendNew<Const32Value>(proc, Origin(), a),
562 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
563 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
565 int32_t inputOutput = b;
566 CHECK(!compileAndRun<int>(proc, &inputOutput));
567 CHECK(inputOutput == a + b);
570 void testAddArgZeroImmZDef()
573 BasicBlock* root = proc.addBlock();
574 Value* arg = root->appendNew<Value>(
575 proc, Trunc, Origin(),
576 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
577 Value* constZero = root->appendNew<Const32Value>(proc, Origin(), 0);
578 root->appendNewControlValue(
579 proc, Return, Origin(),
580 root->appendNew<Value>(
585 auto code = compile(proc, 0);
586 CHECK(invoke<int64_t>(*code, 0x0123456789abcdef) == 0x89abcdef);
589 void testAddLoadTwice()
591 auto test = [&] (unsigned optLevel) {
593 BasicBlock* root = proc.addBlock();
595 Value* load = root->appendNew<MemoryValue>(
596 proc, Load, Int32, Origin(),
597 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
598 root->appendNewControlValue(
599 proc, Return, Origin(),
600 root->appendNew<Value>(proc, Add, Origin(), load, load));
602 auto code = compile(proc, optLevel);
603 CHECK(invoke<int32_t>(*code) == 42 * 2);
610 void testAddArgDouble(double a)
613 BasicBlock* root = proc.addBlock();
614 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
615 root->appendNewControlValue(
616 proc, Return, Origin(),
617 root->appendNew<Value>(proc, Add, Origin(), value, value));
619 CHECK(isIdentical(compileAndRun<double>(proc, a), a + a));
622 void testAddArgsDouble(double a, double b)
625 BasicBlock* root = proc.addBlock();
626 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
627 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
628 root->appendNewControlValue(
629 proc, Return, Origin(),
630 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
632 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a + b));
635 void testAddArgImmDouble(double a, double b)
638 BasicBlock* root = proc.addBlock();
639 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
640 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
641 root->appendNewControlValue(
642 proc, Return, Origin(),
643 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
645 CHECK(isIdentical(compileAndRun<double>(proc, a), a + b));
648 void testAddImmArgDouble(double a, double b)
651 BasicBlock* root = proc.addBlock();
652 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
653 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
654 root->appendNewControlValue(
655 proc, Return, Origin(),
656 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
658 CHECK(isIdentical(compileAndRun<double>(proc, b), a + b));
661 void testAddImmsDouble(double a, double b)
664 BasicBlock* root = proc.addBlock();
665 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
666 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
667 root->appendNewControlValue(
668 proc, Return, Origin(),
669 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
671 CHECK(isIdentical(compileAndRun<double>(proc), a + b));
674 void testAddArgFloat(float a)
677 BasicBlock* root = proc.addBlock();
678 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
679 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
680 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
681 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, floatValue);
682 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
683 root->appendNewControlValue(proc, Return, Origin(), result32);
686 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
689 void testAddArgsFloat(float a, float b)
692 BasicBlock* root = proc.addBlock();
693 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
694 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
695 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
696 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
697 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
698 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
699 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue1, floatValue2);
700 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
701 root->appendNewControlValue(proc, Return, Origin(), result32);
703 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
706 void testAddArgImmFloat(float a, float b)
709 BasicBlock* root = proc.addBlock();
710 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
711 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
712 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
713 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
714 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, constValue);
715 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
716 root->appendNewControlValue(proc, Return, Origin(), result32);
718 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + b)));
721 void testAddImmArgFloat(float a, float b)
724 BasicBlock* root = proc.addBlock();
725 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
726 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
727 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
728 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
729 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue, floatValue);
730 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
731 root->appendNewControlValue(proc, Return, Origin(), result32);
733 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
736 void testAddImmsFloat(float a, float b)
739 BasicBlock* root = proc.addBlock();
740 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
741 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
742 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue1, constValue2);
743 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
744 root->appendNewControlValue(proc, Return, Origin(), result32);
746 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a + b)));
749 void testAddArgFloatWithUselessDoubleConversion(float a)
752 BasicBlock* root = proc.addBlock();
753 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
754 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
755 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
756 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
757 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble, asDouble);
758 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
759 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
760 root->appendNewControlValue(proc, Return, Origin(), result32);
762 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
765 void testAddArgsFloatWithUselessDoubleConversion(float a, float b)
768 BasicBlock* root = proc.addBlock();
769 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
770 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
771 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
772 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
773 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
774 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
775 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
776 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
777 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
778 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
779 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
780 root->appendNewControlValue(proc, Return, Origin(), result32);
782 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
785 void testAddArgsFloatWithEffectfulDoubleConversion(float a, float b)
788 BasicBlock* root = proc.addBlock();
789 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
790 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
791 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
792 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
793 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
794 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
795 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
796 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
797 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
798 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
799 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
800 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
801 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
802 root->appendNewControlValue(proc, Return, Origin(), result32);
805 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a + b)));
806 CHECK(isIdentical(effect, static_cast<double>(a) + static_cast<double>(b)));
809 void testMulArg(int a)
812 BasicBlock* root = proc.addBlock();
813 Value* value = root->appendNew<Value>(
814 proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
815 root->appendNewControlValue(
816 proc, Return, Origin(),
817 root->appendNew<Value>(proc, Mul, Origin(), value, value));
819 CHECK(compileAndRun<int>(proc, a) == a * a);
822 void testMulArgStore(int a)
825 BasicBlock* root = proc.addBlock();
830 Value* value = root->appendNew<Value>(
831 proc, Trunc, Origin(),
832 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
833 Value* mul = root->appendNew<Value>(proc, Mul, Origin(), value, value);
835 root->appendNew<MemoryValue>(
836 proc, Store, Origin(), value,
837 root->appendNew<ConstPtrValue>(proc, Origin(), &valueSlot));
838 root->appendNew<MemoryValue>(
839 proc, Store, Origin(), mul,
840 root->appendNew<ConstPtrValue>(proc, Origin(), &mulSlot));
842 root->appendNewControlValue(
843 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
845 CHECK(!compileAndRun<int>(proc, a));
846 CHECK(mulSlot == a * a);
847 CHECK(valueSlot == a);
850 void testMulAddArg(int a)
853 BasicBlock* root = proc.addBlock();
854 Value* value = root->appendNew<Value>(
855 proc, Trunc, Origin(),
856 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
857 root->appendNewControlValue(
858 proc, Return, Origin(),
859 root->appendNew<Value>(
861 root->appendNew<Value>(proc, Mul, Origin(), value, value),
864 CHECK(compileAndRun<int>(proc, a) == a * a + a);
867 void testMulArgs(int a, int b)
870 BasicBlock* root = proc.addBlock();
871 root->appendNewControlValue(
872 proc, Return, Origin(),
873 root->appendNew<Value>(
875 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
876 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
878 CHECK(compileAndRun<int>(proc, a, b) == a * b);
881 void testMulArgImm(int64_t a, int64_t b)
884 BasicBlock* root = proc.addBlock();
885 root->appendNewControlValue(
886 proc, Return, Origin(),
887 root->appendNew<Value>(
889 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
890 root->appendNew<Const64Value>(proc, Origin(), b)));
892 CHECK(compileAndRun<int64_t>(proc, a) == a * b);
895 void testMulImmArg(int a, int b)
898 BasicBlock* root = proc.addBlock();
899 root->appendNewControlValue(
900 proc, Return, Origin(),
901 root->appendNew<Value>(
903 root->appendNew<Const64Value>(proc, Origin(), a),
904 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
906 CHECK(compileAndRun<int>(proc, b) == a * b);
909 void testMulArgs32(int a, int b)
912 BasicBlock* root = proc.addBlock();
913 root->appendNewControlValue(
914 proc, Return, Origin(),
915 root->appendNew<Value>(
917 root->appendNew<Value>(
918 proc, Trunc, Origin(),
919 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
920 root->appendNew<Value>(
921 proc, Trunc, Origin(),
922 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
924 CHECK(compileAndRun<int>(proc, a, b) == a * b);
927 void testMulLoadTwice()
929 auto test = [&] (unsigned optLevel) {
931 BasicBlock* root = proc.addBlock();
933 Value* load = root->appendNew<MemoryValue>(
934 proc, Load, Int32, Origin(),
935 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
936 root->appendNewControlValue(
937 proc, Return, Origin(),
938 root->appendNew<Value>(proc, Mul, Origin(), load, load));
940 auto code = compile(proc, optLevel);
941 CHECK(invoke<int32_t>(*code) == 42 * 42);
948 void testMulAddArgsLeft()
951 BasicBlock* root = proc.addBlock();
953 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
954 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
955 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
956 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
957 Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
958 root->appendNewControlValue(proc, Return, Origin(), added);
960 auto code = compile(proc);
962 auto testValues = int64Operands();
963 for (auto a : testValues) {
964 for (auto b : testValues) {
965 for (auto c : testValues) {
966 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
972 void testMulAddArgsRight()
975 BasicBlock* root = proc.addBlock();
977 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
978 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
979 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
980 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
981 Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
982 root->appendNewControlValue(proc, Return, Origin(), added);
984 auto code = compile(proc);
986 auto testValues = int64Operands();
987 for (auto a : testValues) {
988 for (auto b : testValues) {
989 for (auto c : testValues) {
990 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
996 void testMulAddArgsLeft32()
999 BasicBlock* root = proc.addBlock();
1001 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1002 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1003 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1004 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1005 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1006 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1007 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1008 Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
1009 root->appendNewControlValue(proc, Return, Origin(), added);
1011 auto code = compile(proc);
1013 auto testValues = int32Operands();
1014 for (auto a : testValues) {
1015 for (auto b : testValues) {
1016 for (auto c : testValues) {
1017 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
1023 void testMulAddArgsRight32()
1026 BasicBlock* root = proc.addBlock();
1028 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1029 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1030 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1031 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1032 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1033 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1034 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1035 Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
1036 root->appendNewControlValue(proc, Return, Origin(), added);
1038 auto code = compile(proc);
1040 auto testValues = int32Operands();
1041 for (auto a : testValues) {
1042 for (auto b : testValues) {
1043 for (auto c : testValues) {
1044 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
1050 void testMulSubArgsLeft()
1053 BasicBlock* root = proc.addBlock();
1055 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1056 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1057 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1058 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1059 Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
1060 root->appendNewControlValue(proc, Return, Origin(), added);
1062 auto code = compile(proc);
1064 auto testValues = int64Operands();
1065 for (auto a : testValues) {
1066 for (auto b : testValues) {
1067 for (auto c : testValues) {
1068 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
1074 void testMulSubArgsRight()
1077 BasicBlock* root = proc.addBlock();
1079 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1080 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1081 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1082 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1083 Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
1084 root->appendNewControlValue(proc, Return, Origin(), added);
1086 auto code = compile(proc);
1088 auto testValues = int64Operands();
1089 for (auto a : testValues) {
1090 for (auto b : testValues) {
1091 for (auto c : testValues) {
1092 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
1098 void testMulSubArgsLeft32()
1101 BasicBlock* root = proc.addBlock();
1103 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1104 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1105 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1106 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1107 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1108 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1109 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1110 Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
1111 root->appendNewControlValue(proc, Return, Origin(), added);
1113 auto code = compile(proc);
1115 auto testValues = int32Operands();
1116 for (auto a : testValues) {
1117 for (auto b : testValues) {
1118 for (auto c : testValues) {
1119 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
1125 void testMulSubArgsRight32()
1128 BasicBlock* root = proc.addBlock();
1130 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1131 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1132 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1133 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1134 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1135 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1136 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1137 Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
1138 root->appendNewControlValue(proc, Return, Origin(), added);
1140 auto code = compile(proc);
1142 auto testValues = int32Operands();
1143 for (auto a : testValues) {
1144 for (auto b : testValues) {
1145 for (auto c : testValues) {
1146 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
1152 void testMulNegArgs()
1155 BasicBlock* root = proc.addBlock();
1157 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1158 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1159 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1160 Value* zero = root->appendNew<Const64Value>(proc, Origin(), 0);
1161 Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
1162 root->appendNewControlValue(proc, Return, Origin(), added);
1164 auto code = compile(proc);
1166 auto testValues = int64Operands();
1167 for (auto a : testValues) {
1168 for (auto b : testValues) {
1169 CHECK(invoke<int64_t>(*code, a.value, b.value) == -(a.value * b.value));
1174 void testMulNegArgs32()
1177 BasicBlock* root = proc.addBlock();
1179 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1180 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1181 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1182 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1183 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1184 Value* zero = root->appendNew<Const32Value>(proc, Origin(), 0);
1185 Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
1186 root->appendNewControlValue(proc, Return, Origin(), added);
1188 auto code = compile(proc);
1190 auto testValues = int32Operands();
1191 for (auto a : testValues) {
1192 for (auto b : testValues) {
1193 CHECK(invoke<int32_t>(*code, a.value, b.value) == -(a.value * b.value));
1198 void testMulArgDouble(double a)
1201 BasicBlock* root = proc.addBlock();
1202 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1203 root->appendNewControlValue(
1204 proc, Return, Origin(),
1205 root->appendNew<Value>(proc, Mul, Origin(), value, value));
1207 CHECK(isIdentical(compileAndRun<double>(proc, a), a * a));
1210 void testMulArgsDouble(double a, double b)
1213 BasicBlock* root = proc.addBlock();
1214 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1215 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1216 root->appendNewControlValue(
1217 proc, Return, Origin(),
1218 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1220 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a * b));
1223 void testMulArgImmDouble(double a, double b)
1226 BasicBlock* root = proc.addBlock();
1227 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1228 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1229 root->appendNewControlValue(
1230 proc, Return, Origin(),
1231 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1233 CHECK(isIdentical(compileAndRun<double>(proc, a), a * b));
1236 void testMulImmArgDouble(double a, double b)
1239 BasicBlock* root = proc.addBlock();
1240 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1241 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1242 root->appendNewControlValue(
1243 proc, Return, Origin(),
1244 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1246 CHECK(isIdentical(compileAndRun<double>(proc, b), a * b));
1249 void testMulImmsDouble(double a, double b)
1252 BasicBlock* root = proc.addBlock();
1253 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1254 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1255 root->appendNewControlValue(
1256 proc, Return, Origin(),
1257 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1259 CHECK(isIdentical(compileAndRun<double>(proc), a * b));
1262 void testMulArgFloat(float a)
1265 BasicBlock* root = proc.addBlock();
1266 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1267 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1268 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1269 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, floatValue);
1270 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1271 root->appendNewControlValue(proc, Return, Origin(), result32);
1274 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
1277 void testMulArgsFloat(float a, float b)
1280 BasicBlock* root = proc.addBlock();
1281 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1282 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1283 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1284 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1285 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1286 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1287 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue1, floatValue2);
1288 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1289 root->appendNewControlValue(proc, Return, Origin(), result32);
1291 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1294 void testMulArgImmFloat(float a, float b)
1297 BasicBlock* root = proc.addBlock();
1298 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1299 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1300 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1301 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1302 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, constValue);
1303 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1304 root->appendNewControlValue(proc, Return, Origin(), result32);
1306 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * b)));
1309 void testMulImmArgFloat(float a, float b)
1312 BasicBlock* root = proc.addBlock();
1313 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1314 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1315 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1316 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1317 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue, floatValue);
1318 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1319 root->appendNewControlValue(proc, Return, Origin(), result32);
1321 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1324 void testMulImmsFloat(float a, float b)
1327 BasicBlock* root = proc.addBlock();
1328 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1329 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1330 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue1, constValue2);
1331 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1332 root->appendNewControlValue(proc, Return, Origin(), result32);
1334 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a * b)));
1337 void testMulArgFloatWithUselessDoubleConversion(float a)
1340 BasicBlock* root = proc.addBlock();
1341 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1342 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1343 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1344 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1345 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble, asDouble);
1346 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1347 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1348 root->appendNewControlValue(proc, Return, Origin(), result32);
1350 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
1353 void testMulArgsFloatWithUselessDoubleConversion(float a, float b)
1356 BasicBlock* root = proc.addBlock();
1357 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1358 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1359 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1360 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1361 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1362 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1363 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1364 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1365 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
1366 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1367 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1368 root->appendNewControlValue(proc, Return, Origin(), result32);
1370 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1373 void testMulArgsFloatWithEffectfulDoubleConversion(float a, float b)
1376 BasicBlock* root = proc.addBlock();
1377 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1378 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1379 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1380 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1381 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1382 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1383 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1384 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1385 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
1386 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1387 Value* doubleMulress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1388 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleMulress);
1389 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1390 root->appendNewControlValue(proc, Return, Origin(), result32);
1393 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a * b)));
1394 CHECK(isIdentical(effect, static_cast<double>(a) * static_cast<double>(b)));
1397 void testDivArgDouble(double a)
1400 BasicBlock* root = proc.addBlock();
1401 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1402 root->appendNewControlValue(
1403 proc, Return, Origin(),
1404 root->appendNew<Value>(proc, Div, Origin(), value, value));
1406 CHECK(isIdentical(compileAndRun<double>(proc, a), a / a));
1409 void testDivArgsDouble(double a, double b)
1412 BasicBlock* root = proc.addBlock();
1413 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1414 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1415 root->appendNewControlValue(
1416 proc, Return, Origin(),
1417 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1419 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a / b));
1422 void testDivArgImmDouble(double a, double b)
1425 BasicBlock* root = proc.addBlock();
1426 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1427 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1428 root->appendNewControlValue(
1429 proc, Return, Origin(),
1430 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1432 CHECK(isIdentical(compileAndRun<double>(proc, a), a / b));
1435 void testDivImmArgDouble(double a, double b)
1438 BasicBlock* root = proc.addBlock();
1439 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1440 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1441 root->appendNewControlValue(
1442 proc, Return, Origin(),
1443 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1445 CHECK(isIdentical(compileAndRun<double>(proc, b), a / b));
1448 void testDivImmsDouble(double a, double b)
1451 BasicBlock* root = proc.addBlock();
1452 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1453 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1454 root->appendNewControlValue(
1455 proc, Return, Origin(),
1456 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1458 CHECK(isIdentical(compileAndRun<double>(proc), a / b));
1461 void testDivArgFloat(float a)
1464 BasicBlock* root = proc.addBlock();
1465 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1466 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1467 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1468 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, floatValue);
1469 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1470 root->appendNewControlValue(proc, Return, Origin(), result32);
1473 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1476 void testDivArgsFloat(float a, float b)
1479 BasicBlock* root = proc.addBlock();
1480 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1481 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1482 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1483 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1484 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1485 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1486 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue1, floatValue2);
1487 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1488 root->appendNewControlValue(proc, Return, Origin(), result32);
1490 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1493 void testDivArgImmFloat(float a, float b)
1496 BasicBlock* root = proc.addBlock();
1497 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1498 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1499 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1500 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1501 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, constValue);
1502 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1503 root->appendNewControlValue(proc, Return, Origin(), result32);
1505 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / b)));
1508 void testDivImmArgFloat(float a, float b)
1511 BasicBlock* root = proc.addBlock();
1512 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1513 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1514 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1515 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1516 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue, floatValue);
1517 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1518 root->appendNewControlValue(proc, Return, Origin(), result32);
1520 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1523 void testDivImmsFloat(float a, float b)
1526 BasicBlock* root = proc.addBlock();
1527 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1528 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1529 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue1, constValue2);
1530 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1531 root->appendNewControlValue(proc, Return, Origin(), result32);
1533 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a / b)));
1536 void testModArgDouble(double a)
1539 BasicBlock* root = proc.addBlock();
1540 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1541 root->appendNewControlValue(
1542 proc, Return, Origin(),
1543 root->appendNew<Value>(proc, Mod, Origin(), value, value));
1545 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, a)));
1548 void testModArgsDouble(double a, double b)
1551 BasicBlock* root = proc.addBlock();
1552 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1553 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1554 root->appendNewControlValue(
1555 proc, Return, Origin(),
1556 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1558 CHECK(isIdentical(compileAndRun<double>(proc, a, b), fmod(a, b)));
1561 void testModArgImmDouble(double a, double b)
1564 BasicBlock* root = proc.addBlock();
1565 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1566 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1567 root->appendNewControlValue(
1568 proc, Return, Origin(),
1569 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1571 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, b)));
1574 void testModImmArgDouble(double a, double b)
1577 BasicBlock* root = proc.addBlock();
1578 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1579 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1580 root->appendNewControlValue(
1581 proc, Return, Origin(),
1582 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1584 CHECK(isIdentical(compileAndRun<double>(proc, b), fmod(a, b)));
1587 void testModImmsDouble(double a, double b)
1590 BasicBlock* root = proc.addBlock();
1591 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1592 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1593 root->appendNewControlValue(
1594 proc, Return, Origin(),
1595 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1597 CHECK(isIdentical(compileAndRun<double>(proc), fmod(a, b)));
1600 void testModArgFloat(float a)
1603 BasicBlock* root = proc.addBlock();
1604 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1605 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1606 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1607 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, floatValue);
1608 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1609 root->appendNewControlValue(proc, Return, Origin(), result32);
1612 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, a)))));
1615 void testModArgsFloat(float a, float b)
1618 BasicBlock* root = proc.addBlock();
1619 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1620 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1621 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1622 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1623 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1624 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1625 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue1, floatValue2);
1626 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1627 root->appendNewControlValue(proc, Return, Origin(), result32);
1629 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)))));
1632 void testModArgImmFloat(float a, float b)
1635 BasicBlock* root = proc.addBlock();
1636 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1637 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1638 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1639 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1640 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, constValue);
1641 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1642 root->appendNewControlValue(proc, Return, Origin(), result32);
1644 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1647 void testModImmArgFloat(float a, float b)
1650 BasicBlock* root = proc.addBlock();
1651 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1652 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1653 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1654 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1655 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue, floatValue);
1656 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1657 root->appendNewControlValue(proc, Return, Origin(), result32);
1659 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1662 void testModImmsFloat(float a, float b)
1665 BasicBlock* root = proc.addBlock();
1666 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1667 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1668 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue1, constValue2);
1669 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1670 root->appendNewControlValue(proc, Return, Origin(), result32);
1672 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1675 void testDivArgFloatWithUselessDoubleConversion(float a)
1678 BasicBlock* root = proc.addBlock();
1679 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1680 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1681 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1682 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1683 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble, asDouble);
1684 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1685 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1686 root->appendNewControlValue(proc, Return, Origin(), result32);
1688 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1691 void testDivArgsFloatWithUselessDoubleConversion(float a, float b)
1694 BasicBlock* root = proc.addBlock();
1695 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1696 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1697 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1698 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1699 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1700 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1701 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1702 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1703 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1704 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1705 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1706 root->appendNewControlValue(proc, Return, Origin(), result32);
1708 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1711 void testDivArgsFloatWithEffectfulDoubleConversion(float a, float b)
1714 BasicBlock* root = proc.addBlock();
1715 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1716 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1717 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1718 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1719 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1720 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1721 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1722 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1723 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1724 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1725 Value* doubleDivress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1726 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleDivress);
1727 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1728 root->appendNewControlValue(proc, Return, Origin(), result32);
1731 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a / b)));
1732 CHECK(isIdentical(effect, static_cast<double>(a) / static_cast<double>(b)));
1735 void testSubArg(int a)
1738 BasicBlock* root = proc.addBlock();
1739 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1740 root->appendNewControlValue(
1741 proc, Return, Origin(),
1742 root->appendNew<Value>(proc, Sub, Origin(), value, value));
1744 CHECK(!compileAndRun<int>(proc, a));
1747 void testSubArgs(int a, int b)
1750 BasicBlock* root = proc.addBlock();
1751 root->appendNewControlValue(
1752 proc, Return, Origin(),
1753 root->appendNew<Value>(
1754 proc, Sub, Origin(),
1755 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1756 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
1758 CHECK(compileAndRun<int>(proc, a, b) == a - b);
1761 void testSubArgImm(int64_t a, int64_t b)
1764 BasicBlock* root = proc.addBlock();
1765 root->appendNewControlValue(
1766 proc, Return, Origin(),
1767 root->appendNew<Value>(
1768 proc, Sub, Origin(),
1769 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1770 root->appendNew<Const64Value>(proc, Origin(), b)));
1772 CHECK(compileAndRun<int64_t>(proc, a) == a - b);
1775 void testNegValueSubOne(int a)
1778 BasicBlock* root = proc.addBlock();
1779 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1780 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
1781 root->appendNew<Const64Value>(proc, Origin(), 0),
1783 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
1785 root->appendNew<Const64Value>(proc, Origin(), 1));
1786 root->appendNewControlValue(proc, Return, Origin(), negArgumentMinusOne);
1787 CHECK(compileAndRun<int>(proc, a) == -a - 1);
1790 void testSubImmArg(int a, int b)
1793 BasicBlock* root = proc.addBlock();
1794 root->appendNewControlValue(
1795 proc, Return, Origin(),
1796 root->appendNew<Value>(
1797 proc, Sub, Origin(),
1798 root->appendNew<Const64Value>(proc, Origin(), a),
1799 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1801 CHECK(compileAndRun<int>(proc, b) == a - b);
1804 void testSubArgMem(int64_t a, int64_t b)
1807 BasicBlock* root = proc.addBlock();
1808 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1809 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1810 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1811 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1813 root->appendNewControlValue(proc, Return, Origin(), result);
1815 CHECK(compileAndRun<int64_t>(proc, a, &b) == a - b);
1818 void testSubMemArg(int64_t a, int64_t b)
1821 BasicBlock* root = proc.addBlock();
1822 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1823 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1824 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1826 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1827 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1828 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1830 int64_t inputOutput = a;
1831 CHECK(!compileAndRun<int64_t>(proc, &inputOutput, b));
1832 CHECK(inputOutput == a - b);
1835 void testSubImmMem(int64_t a, int64_t b)
1838 BasicBlock* root = proc.addBlock();
1839 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1840 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1841 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1842 root->appendNew<Const64Value>(proc, Origin(), a),
1844 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1845 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1847 int64_t inputOutput = b;
1848 CHECK(!compileAndRun<int>(proc, &inputOutput));
1849 CHECK(inputOutput == a - b);
1852 void testSubMemImm(int64_t a, int64_t b)
1855 BasicBlock* root = proc.addBlock();
1856 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1857 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1858 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1860 root->appendNew<Const64Value>(proc, Origin(), b));
1861 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1862 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1864 int64_t inputOutput = a;
1865 CHECK(!compileAndRun<int>(proc, &inputOutput));
1866 CHECK(inputOutput == a - b);
1870 void testSubArgs32(int a, int b)
1873 BasicBlock* root = proc.addBlock();
1874 root->appendNewControlValue(
1875 proc, Return, Origin(),
1876 root->appendNew<Value>(
1877 proc, Sub, Origin(),
1878 root->appendNew<Value>(
1879 proc, Trunc, Origin(),
1880 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1881 root->appendNew<Value>(
1882 proc, Trunc, Origin(),
1883 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1885 CHECK(compileAndRun<int>(proc, a, b) == a - b);
1888 void testSubArgImm32(int a, int b)
1891 BasicBlock* root = proc.addBlock();
1892 root->appendNewControlValue(
1893 proc, Return, Origin(),
1894 root->appendNew<Value>(
1895 proc, Sub, Origin(),
1896 root->appendNew<Value>(
1897 proc, Trunc, Origin(),
1898 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1899 root->appendNew<Const32Value>(proc, Origin(), b)));
1901 CHECK(compileAndRun<int>(proc, a) == a - b);
1904 void testSubImmArg32(int a, int b)
1907 BasicBlock* root = proc.addBlock();
1908 root->appendNewControlValue(
1909 proc, Return, Origin(),
1910 root->appendNew<Value>(
1911 proc, Sub, Origin(),
1912 root->appendNew<Const32Value>(proc, Origin(), a),
1913 root->appendNew<Value>(
1914 proc, Trunc, Origin(),
1915 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
1917 CHECK(compileAndRun<int>(proc, b) == a - b);
1920 void testSubMemArg32(int32_t a, int32_t b)
1923 BasicBlock* root = proc.addBlock();
1924 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1925 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1926 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1927 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1928 Value* result = root->appendNew<Value>(proc, Sub, Origin(), load, argument);
1929 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1930 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1932 int32_t inputOutput = a;
1933 CHECK(!compileAndRun<int32_t>(proc, &inputOutput, b));
1934 CHECK(inputOutput == a - b);
1937 void testSubArgMem32(int32_t a, int32_t b)
1940 BasicBlock* root = proc.addBlock();
1941 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1942 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1943 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1944 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1945 Value* result = root->appendNew<Value>(proc, Sub, Origin(), argument, load);
1946 root->appendNewControlValue(proc, Return, Origin(), result);
1948 CHECK(compileAndRun<int32_t>(proc, a, &b) == a - b);
1951 void testSubImmMem32(int32_t a, int32_t b)
1954 BasicBlock* root = proc.addBlock();
1955 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1956 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1957 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1958 root->appendNew<Const32Value>(proc, Origin(), a),
1960 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1961 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1963 int32_t inputOutput = b;
1964 CHECK(!compileAndRun<int>(proc, &inputOutput));
1965 CHECK(inputOutput == a - b);
1968 void testSubMemImm32(int32_t a, int32_t b)
1971 BasicBlock* root = proc.addBlock();
1972 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1973 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1974 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1976 root->appendNew<Const32Value>(proc, Origin(), b));
1977 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1978 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1980 int32_t inputOutput = a;
1981 CHECK(!compileAndRun<int>(proc, &inputOutput));
1982 CHECK(inputOutput == a - b);
1985 void testNegValueSubOne32(int a)
1988 BasicBlock* root = proc.addBlock();
1989 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1990 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1991 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
1992 root->appendNew<Const32Value>(proc, Origin(), 0),
1994 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
1996 root->appendNew<Const32Value>(proc, Origin(), 1));
1997 root->appendNewControlValue(proc, Return, Origin(), negArgumentMinusOne);
1998 CHECK(compileAndRun<int>(proc, a) == -a - 1);
2001 void testSubArgDouble(double a)
2004 BasicBlock* root = proc.addBlock();
2005 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2006 root->appendNewControlValue(
2007 proc, Return, Origin(),
2008 root->appendNew<Value>(proc, Sub, Origin(), value, value));
2010 CHECK(isIdentical(compileAndRun<double>(proc, a), a - a));
2013 void testSubArgsDouble(double a, double b)
2016 BasicBlock* root = proc.addBlock();
2017 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2018 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
2019 root->appendNewControlValue(
2020 proc, Return, Origin(),
2021 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2023 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a - b));
2026 void testSubArgImmDouble(double a, double b)
2029 BasicBlock* root = proc.addBlock();
2030 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2031 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2032 root->appendNewControlValue(
2033 proc, Return, Origin(),
2034 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2036 CHECK(isIdentical(compileAndRun<double>(proc, a), a - b));
2039 void testSubImmArgDouble(double a, double b)
2042 BasicBlock* root = proc.addBlock();
2043 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2044 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2045 root->appendNewControlValue(
2046 proc, Return, Origin(),
2047 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2049 CHECK(isIdentical(compileAndRun<double>(proc, b), a - b));
2052 void testSubImmsDouble(double a, double b)
2055 BasicBlock* root = proc.addBlock();
2056 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2057 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2058 root->appendNewControlValue(
2059 proc, Return, Origin(),
2060 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2062 CHECK(isIdentical(compileAndRun<double>(proc), a - b));
2065 void testSubArgFloat(float a)
2068 BasicBlock* root = proc.addBlock();
2069 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2070 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2071 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2072 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, floatValue);
2073 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2074 root->appendNewControlValue(proc, Return, Origin(), result32);
2077 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
2080 void testSubArgsFloat(float a, float b)
2083 BasicBlock* root = proc.addBlock();
2084 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2085 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2086 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2087 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2088 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2089 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2090 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue1, floatValue2);
2091 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2092 root->appendNewControlValue(proc, Return, Origin(), result32);
2094 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2097 void testSubArgImmFloat(float a, float b)
2100 BasicBlock* root = proc.addBlock();
2101 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2102 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2103 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2104 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2105 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, constValue);
2106 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2107 root->appendNewControlValue(proc, Return, Origin(), result32);
2109 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - b)));
2112 void testSubImmArgFloat(float a, float b)
2115 BasicBlock* root = proc.addBlock();
2116 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2117 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2118 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2119 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2120 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue, floatValue);
2121 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2122 root->appendNewControlValue(proc, Return, Origin(), result32);
2124 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2127 void testSubImmsFloat(float a, float b)
2130 BasicBlock* root = proc.addBlock();
2131 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2132 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2133 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue1, constValue2);
2134 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2135 root->appendNewControlValue(proc, Return, Origin(), result32);
2137 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a - b)));
2140 void testSubArgFloatWithUselessDoubleConversion(float a)
2143 BasicBlock* root = proc.addBlock();
2144 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
2145 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2146 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
2147 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2148 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble, asDouble);
2149 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2150 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2151 root->appendNewControlValue(proc, Return, Origin(), result32);
2153 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
2156 void testSubArgsFloatWithUselessDoubleConversion(float a, float b)
2159 BasicBlock* root = proc.addBlock();
2160 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2161 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2162 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2163 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2164 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2165 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2166 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
2167 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
2168 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
2169 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2170 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2171 root->appendNewControlValue(proc, Return, Origin(), result32);
2173 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2176 void testSubArgsFloatWithEffectfulDoubleConversion(float a, float b)
2179 BasicBlock* root = proc.addBlock();
2180 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2181 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2182 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2183 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2184 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2185 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2186 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
2187 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
2188 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
2189 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2190 Value* doubleSubress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2191 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleSubress);
2192 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2193 root->appendNewControlValue(proc, Return, Origin(), result32);
2196 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a - b)));
2197 CHECK(isIdentical(effect, static_cast<double>(a) - static_cast<double>(b)));
2200 void testTernarySubInstructionSelection(B3::Opcode valueModifier, Type valueType, Air::Opcode expectedOpcode)
2203 BasicBlock* root = proc.addBlock();
2205 Value* left = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2206 Value* right = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2208 if (valueModifier == Trunc) {
2209 left = root->appendNew<Value>(proc, valueModifier, valueType, Origin(), left);
2210 right = root->appendNew<Value>(proc, valueModifier, valueType, Origin(), right);
2213 root->appendNewControlValue(
2214 proc, Return, Origin(),
2215 root->appendNew<Value>(proc, Sub, Origin(), left, right));
2217 lowerToAirForTesting(proc);
2219 auto block = proc.code()[0];
2220 unsigned numberOfSubInstructions = 0;
2221 for (auto instruction : *block) {
2222 if (instruction.kind.opcode == expectedOpcode) {
2223 CHECK_EQ(instruction.args.size(), 3ul);
2224 CHECK_EQ(instruction.args[0].kind(), Air::Arg::Tmp);
2225 CHECK_EQ(instruction.args[1].kind(), Air::Arg::Tmp);
2226 CHECK_EQ(instruction.args[2].kind(), Air::Arg::Tmp);
2227 numberOfSubInstructions++;
2230 CHECK_EQ(numberOfSubInstructions, 1ul);
2233 void testNegDouble(double a)
2236 BasicBlock* root = proc.addBlock();
2237 root->appendNewControlValue(
2238 proc, Return, Origin(),
2239 root->appendNew<Value>(
2240 proc, Neg, Origin(),
2241 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
2243 CHECK(isIdentical(compileAndRun<double>(proc, a), -a));
2246 void testNegFloat(float a)
2249 BasicBlock* root = proc.addBlock();
2250 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2251 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2252 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2253 root->appendNewControlValue(
2254 proc, Return, Origin(),
2255 root->appendNew<Value>(proc, Neg, Origin(), floatValue));
2257 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), -a));
2260 void testNegFloatWithUselessDoubleConversion(float a)
2263 BasicBlock* root = proc.addBlock();
2264 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
2265 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2266 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
2267 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2268 Value* result = root->appendNew<Value>(proc, Neg, Origin(), asDouble);
2269 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2270 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2272 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), -a));
2275 void testBitAndArgs(int64_t a, int64_t b)
2278 BasicBlock* root = proc.addBlock();
2279 root->appendNewControlValue(
2280 proc, Return, Origin(),
2281 root->appendNew<Value>(
2282 proc, BitAnd, Origin(),
2283 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2284 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2286 CHECK(compileAndRun<int64_t>(proc, a, b) == (a & b));
2289 void testBitAndSameArg(int64_t a)
2292 BasicBlock* root = proc.addBlock();
2293 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2294 root->appendNewControlValue(
2295 proc, Return, Origin(),
2296 root->appendNew<Value>(
2297 proc, BitAnd, Origin(),
2301 CHECK(compileAndRun<int64_t>(proc, a) == a);
2304 void testBitAndImms(int64_t a, int64_t b)
2307 BasicBlock* root = proc.addBlock();
2308 root->appendNewControlValue(
2309 proc, Return, Origin(),
2310 root->appendNew<Value>(
2311 proc, BitAnd, Origin(),
2312 root->appendNew<Const64Value>(proc, Origin(), a),
2313 root->appendNew<Const64Value>(proc, Origin(), b)));
2315 CHECK(compileAndRun<int64_t>(proc) == (a & b));
2318 void testBitAndArgImm(int64_t a, int64_t b)
2321 BasicBlock* root = proc.addBlock();
2322 root->appendNewControlValue(
2323 proc, Return, Origin(),
2324 root->appendNew<Value>(
2325 proc, BitAnd, Origin(),
2326 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2327 root->appendNew<Const64Value>(proc, Origin(), b)));
2329 CHECK(compileAndRun<int64_t>(proc, a) == (a & b));
2332 void testBitAndImmArg(int64_t a, int64_t b)
2335 BasicBlock* root = proc.addBlock();
2336 root->appendNewControlValue(
2337 proc, Return, Origin(),
2338 root->appendNew<Value>(
2339 proc, BitAnd, Origin(),
2340 root->appendNew<Const64Value>(proc, Origin(), a),
2341 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2343 CHECK(compileAndRun<int64_t>(proc, b) == (a & b));
2346 void testBitAndBitAndArgImmImm(int64_t a, int64_t b, int64_t c)
2349 BasicBlock* root = proc.addBlock();
2350 Value* innerBitAnd = root->appendNew<Value>(
2351 proc, BitAnd, Origin(),
2352 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2353 root->appendNew<Const64Value>(proc, Origin(), b));
2354 root->appendNewControlValue(
2355 proc, Return, Origin(),
2356 root->appendNew<Value>(
2357 proc, BitAnd, Origin(),
2359 root->appendNew<Const64Value>(proc, Origin(), c)));
2361 CHECK(compileAndRun<int64_t>(proc, a) == ((a & b) & c));
2364 void testBitAndImmBitAndArgImm(int64_t a, int64_t b, int64_t c)
2367 BasicBlock* root = proc.addBlock();
2368 Value* innerBitAnd = root->appendNew<Value>(
2369 proc, BitAnd, Origin(),
2370 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2371 root->appendNew<Const64Value>(proc, Origin(), c));
2372 root->appendNewControlValue(
2373 proc, Return, Origin(),
2374 root->appendNew<Value>(
2375 proc, BitAnd, Origin(),
2376 root->appendNew<Const64Value>(proc, Origin(), a),
2379 CHECK(compileAndRun<int64_t>(proc, b) == (a & (b & c)));
2382 void testBitAndArgs32(int a, int b)
2385 BasicBlock* root = proc.addBlock();
2386 root->appendNewControlValue(
2387 proc, Return, Origin(),
2388 root->appendNew<Value>(
2389 proc, BitAnd, Origin(),
2390 root->appendNew<Value>(
2391 proc, Trunc, Origin(),
2392 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2393 root->appendNew<Value>(
2394 proc, Trunc, Origin(),
2395 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2397 CHECK(compileAndRun<int>(proc, a, b) == (a & b));
2400 void testBitAndSameArg32(int a)
2403 BasicBlock* root = proc.addBlock();
2404 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2405 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2406 root->appendNewControlValue(
2407 proc, Return, Origin(),
2408 root->appendNew<Value>(
2409 proc, BitAnd, Origin(),
2413 CHECK(compileAndRun<int>(proc, a) == a);
2416 void testBitAndImms32(int a, int b)
2419 BasicBlock* root = proc.addBlock();
2420 root->appendNewControlValue(
2421 proc, Return, Origin(),
2422 root->appendNew<Value>(
2423 proc, BitAnd, Origin(),
2424 root->appendNew<Const32Value>(proc, Origin(), a),
2425 root->appendNew<Const32Value>(proc, Origin(), b)));
2427 CHECK(compileAndRun<int>(proc) == (a & b));
2430 void testBitAndArgImm32(int a, int b)
2433 BasicBlock* root = proc.addBlock();
2434 root->appendNewControlValue(
2435 proc, Return, Origin(),
2436 root->appendNew<Value>(
2437 proc, BitAnd, Origin(),
2438 root->appendNew<Value>(
2439 proc, Trunc, Origin(),
2440 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2441 root->appendNew<Const32Value>(proc, Origin(), b)));
2443 CHECK(compileAndRun<int>(proc, a) == (a & b));
2446 void testBitAndImmArg32(int a, int b)
2449 BasicBlock* root = proc.addBlock();
2450 root->appendNewControlValue(
2451 proc, Return, Origin(),
2452 root->appendNew<Value>(
2453 proc, BitAnd, Origin(),
2454 root->appendNew<Const32Value>(proc, Origin(), a),
2455 root->appendNew<Value>(
2456 proc, Trunc, Origin(),
2457 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2459 CHECK(compileAndRun<int>(proc, b) == (a & b));
2462 void testBitAndBitAndArgImmImm32(int a, int b, int c)
2465 BasicBlock* root = proc.addBlock();
2466 Value* innerBitAnd = root->appendNew<Value>(
2467 proc, BitAnd, Origin(),
2468 root->appendNew<Value>(
2469 proc, Trunc, Origin(),
2470 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2471 root->appendNew<Const32Value>(proc, Origin(), b));
2472 root->appendNewControlValue(
2473 proc, Return, Origin(),
2474 root->appendNew<Value>(
2475 proc, BitAnd, Origin(),
2477 root->appendNew<Const32Value>(proc, Origin(), c)));
2479 CHECK(compileAndRun<int>(proc, a) == ((a & b) & c));
2482 void testBitAndImmBitAndArgImm32(int a, int b, int c)
2485 BasicBlock* root = proc.addBlock();
2486 Value* innerBitAnd = root->appendNew<Value>(
2487 proc, BitAnd, Origin(),
2488 root->appendNew<Value>(
2489 proc, Trunc, Origin(),
2490 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2491 root->appendNew<Const32Value>(proc, Origin(), c));
2492 root->appendNewControlValue(
2493 proc, Return, Origin(),
2494 root->appendNew<Value>(
2495 proc, BitAnd, Origin(),
2496 root->appendNew<Const32Value>(proc, Origin(), a),
2499 CHECK(compileAndRun<int>(proc, b) == (a & (b & c)));
2502 void testBitAndWithMaskReturnsBooleans(int64_t a, int64_t b)
2505 BasicBlock* root = proc.addBlock();
2506 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2507 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2508 Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg0, arg1);
2509 Value* maskedEqual = root->appendNew<Value>(proc, BitAnd, Origin(),
2510 root->appendNew<Const32Value>(proc, Origin(), 0x5),
2512 Value* inverted = root->appendNew<Value>(proc, BitXor, Origin(),
2513 root->appendNew<Const32Value>(proc, Origin(), 0x1),
2515 Value* select = root->appendNew<Value>(proc, Select, Origin(), inverted,
2516 root->appendNew<Const64Value>(proc, Origin(), 42),
2517 root->appendNew<Const64Value>(proc, Origin(), -5));
2519 root->appendNewControlValue(proc, Return, Origin(), select);
2521 int64_t expected = (a == b) ? -5 : 42;
2522 CHECK(compileAndRun<int64_t>(proc, a, b) == expected);
2525 double bitAndDouble(double a, double b)
2527 return bitwise_cast<double>(bitwise_cast<uint64_t>(a) & bitwise_cast<uint64_t>(b));
2530 void testBitAndArgDouble(double a)
2533 BasicBlock* root = proc.addBlock();
2534 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2535 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2536 root->appendNewControlValue(proc, Return, Origin(), result);
2538 CHECK(isIdentical(compileAndRun<double>(proc, a), bitAndDouble(a, a)));
2541 void testBitAndArgsDouble(double a, double b)
2544 BasicBlock* root = proc.addBlock();
2545 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2546 Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
2547 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2548 root->appendNewControlValue(proc, Return, Origin(), result);
2550 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2553 void testBitAndArgImmDouble(double a, double b)
2556 BasicBlock* root = proc.addBlock();
2557 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2558 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2559 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2560 root->appendNewControlValue(proc, Return, Origin(), result);
2562 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2565 void testBitAndImmsDouble(double a, double b)
2568 BasicBlock* root = proc.addBlock();
2569 Value* argumentA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2570 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2571 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2572 root->appendNewControlValue(proc, Return, Origin(), result);
2574 CHECK(isIdentical(compileAndRun<double>(proc), bitAndDouble(a, b)));
2577 float bitAndFloat(float a, float b)
2579 return bitwise_cast<float>(bitwise_cast<uint32_t>(a) & bitwise_cast<uint32_t>(b));
2582 void testBitAndArgFloat(float a)
2585 BasicBlock* root = proc.addBlock();
2586 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2587 root->appendNew<Value>(proc, Trunc, Origin(),
2588 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2589 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2590 root->appendNewControlValue(proc, Return, Origin(), result);
2592 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), bitAndFloat(a, a)));
2595 void testBitAndArgsFloat(float a, float b)
2598 BasicBlock* root = proc.addBlock();
2599 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2600 root->appendNew<Value>(proc, Trunc, Origin(),
2601 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2602 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2603 root->appendNew<Value>(proc, Trunc, Origin(),
2604 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2605 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2606 root->appendNewControlValue(proc, Return, Origin(), result);
2608 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2611 void testBitAndArgImmFloat(float a, float b)
2614 BasicBlock* root = proc.addBlock();
2615 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2616 root->appendNew<Value>(proc, Trunc, Origin(),
2617 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2618 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2619 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2620 root->appendNewControlValue(proc, Return, Origin(), result);
2622 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2625 void testBitAndImmsFloat(float a, float b)
2628 BasicBlock* root = proc.addBlock();
2629 Value* argumentA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2630 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2631 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2632 root->appendNewControlValue(proc, Return, Origin(), result);
2634 CHECK(isIdentical(compileAndRun<float>(proc), bitAndFloat(a, b)));
2637 void testBitAndArgsFloatWithUselessDoubleConversion(float a, float b)
2640 BasicBlock* root = proc.addBlock();
2641 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2642 root->appendNew<Value>(proc, Trunc, Origin(),
2643 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2644 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2645 root->appendNew<Value>(proc, Trunc, Origin(),
2646 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2647 Value* argumentAasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentA);
2648 Value* argumentBasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentB);
2649 Value* doubleResult = root->appendNew<Value>(proc, BitAnd, Origin(), argumentAasDouble, argumentBasDouble);
2650 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleResult);
2651 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2655 float expected = static_cast<float>(bitAndDouble(doubleA, doubleB));
2656 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), expected));
2659 void testBitOrArgs(int64_t a, int64_t b)
2662 BasicBlock* root = proc.addBlock();
2663 root->appendNewControlValue(
2664 proc, Return, Origin(),
2665 root->appendNew<Value>(
2666 proc, BitOr, Origin(),
2667 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2668 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2670 CHECK(compileAndRun<int64_t>(proc, a, b) == (a | b));
2673 void testBitOrSameArg(int64_t a)
2676 BasicBlock* root = proc.addBlock();
2677 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2678 root->appendNewControlValue(
2679 proc, Return, Origin(),
2680 root->appendNew<Value>(
2681 proc, BitOr, Origin(),
2685 CHECK(compileAndRun<int64_t>(proc, a) == a);
2688 void testBitOrImms(int64_t a, int64_t b)
2691 BasicBlock* root = proc.addBlock();
2692 root->appendNewControlValue(
2693 proc, Return, Origin(),
2694 root->appendNew<Value>(
2695 proc, BitOr, Origin(),
2696 root->appendNew<Const64Value>(proc, Origin(), a),
2697 root->appendNew<Const64Value>(proc, Origin(), b)));
2699 CHECK(compileAndRun<int64_t>(proc) == (a | b));
2702 void testBitOrArgImm(int64_t a, int64_t b)
2705 BasicBlock* root = proc.addBlock();
2706 root->appendNewControlValue(
2707 proc, Return, Origin(),
2708 root->appendNew<Value>(
2709 proc, BitOr, Origin(),
2710 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2711 root->appendNew<Const64Value>(proc, Origin(), b)));
2713 CHECK(compileAndRun<int64_t>(proc, a) == (a | b));
2716 void testBitOrImmArg(int64_t a, int64_t b)
2719 BasicBlock* root = proc.addBlock();
2720 root->appendNewControlValue(
2721 proc, Return, Origin(),
2722 root->appendNew<Value>(
2723 proc, BitOr, Origin(),
2724 root->appendNew<Const64Value>(proc, Origin(), a),
2725 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2727 CHECK(compileAndRun<int64_t>(proc, b) == (a | b));
2730 void testBitOrBitOrArgImmImm(int64_t a, int64_t b, int64_t c)
2733 BasicBlock* root = proc.addBlock();
2734 Value* innerBitOr = root->appendNew<Value>(
2735 proc, BitOr, Origin(),
2736 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2737 root->appendNew<Const64Value>(proc, Origin(), b));
2738 root->appendNewControlValue(
2739 proc, Return, Origin(),
2740 root->appendNew<Value>(
2741 proc, BitOr, Origin(),
2743 root->appendNew<Const64Value>(proc, Origin(), c)));
2745 CHECK(compileAndRun<int64_t>(proc, a) == ((a | b) | c));
2748 void testBitOrImmBitOrArgImm(int64_t a, int64_t b, int64_t c)
2751 BasicBlock* root = proc.addBlock();
2752 Value* innerBitOr = root->appendNew<Value>(
2753 proc, BitOr, Origin(),
2754 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2755 root->appendNew<Const64Value>(proc, Origin(), c));
2756 root->appendNewControlValue(
2757 proc, Return, Origin(),
2758 root->appendNew<Value>(
2759 proc, BitOr, Origin(),
2760 root->appendNew<Const64Value>(proc, Origin(), a),
2763 CHECK(compileAndRun<int64_t>(proc, b) == (a | (b | c)));
2766 void testBitOrArgs32(int a, int b)
2769 BasicBlock* root = proc.addBlock();
2770 root->appendNewControlValue(
2771 proc, Return, Origin(),
2772 root->appendNew<Value>(
2773 proc, BitOr, Origin(),
2774 root->appendNew<Value>(
2775 proc, Trunc, Origin(),
2776 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2777 root->appendNew<Value>(
2778 proc, Trunc, Origin(),
2779 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2781 CHECK(compileAndRun<int>(proc, a, b) == (a | b));
2784 void testBitOrSameArg32(int a)
2787 BasicBlock* root = proc.addBlock();
2788 Value* argument = root->appendNew<Value>(
2789 proc, Trunc, Origin(),
2790 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2791 root->appendNewControlValue(
2792 proc, Return, Origin(),
2793 root->appendNew<Value>(
2794 proc, BitOr, Origin(),
2798 CHECK(compileAndRun<int>(proc, a) == a);
2801 void testBitOrImms32(int a, int b)
2804 BasicBlock* root = proc.addBlock();
2805 root->appendNewControlValue(
2806 proc, Return, Origin(),
2807 root->appendNew<Value>(
2808 proc, BitOr, Origin(),
2809 root->appendNew<Const32Value>(proc, Origin(), a),
2810 root->appendNew<Const32Value>(proc, Origin(), b)));
2812 CHECK(compileAndRun<int>(proc) == (a | b));
2815 void testBitOrArgImm32(int a, int b)
2818 BasicBlock* root = proc.addBlock();
2819 root->appendNewControlValue(
2820 proc, Return, Origin(),
2821 root->appendNew<Value>(
2822 proc, BitOr, Origin(),
2823 root->appendNew<Value>(
2824 proc, Trunc, Origin(),
2825 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2826 root->appendNew<Const32Value>(proc, Origin(), b)));
2828 CHECK(compileAndRun<int>(proc, a) == (a | b));
2831 void testBitOrImmArg32(int a, int b)
2834 BasicBlock* root = proc.addBlock();
2835 root->appendNewControlValue(
2836 proc, Return, Origin(),
2837 root->appendNew<Value>(
2838 proc, BitOr, Origin(),
2839 root->appendNew<Const32Value>(proc, Origin(), a),
2840 root->appendNew<Value>(
2841 proc, Trunc, Origin(),
2842 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2844 CHECK(compileAndRun<int>(proc, b) == (a | b));
2847 void testBitOrBitOrArgImmImm32(int a, int b, int c)
2850 BasicBlock* root = proc.addBlock();
2851 Value* innerBitOr = root->appendNew<Value>(
2852 proc, BitOr, Origin(),
2853 root->appendNew<Value>(
2854 proc, Trunc, Origin(),
2855 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2856 root->appendNew<Const32Value>(proc, Origin(), b));
2857 root->appendNewControlValue(
2858 proc, Return, Origin(),
2859 root->appendNew<Value>(
2860 proc, BitOr, Origin(),
2862 root->appendNew<Const32Value>(proc, Origin(), c)));
2864 CHECK(compileAndRun<int>(proc, a) == ((a | b) | c));
2867 void testBitOrImmBitOrArgImm32(int a, int b, int c)
2870 BasicBlock* root = proc.addBlock();
2871 Value* innerBitOr = root->appendNew<Value>(
2872 proc, BitOr, Origin(),
2873 root->appendNew<Value>(
2874 proc, Trunc, Origin(),
2875 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2876 root->appendNew<Const32Value>(proc, Origin(), c));
2877 root->appendNewControlValue(
2878 proc, Return, Origin(),
2879 root->appendNew<Value>(
2880 proc, BitOr, Origin(),
2881 root->appendNew<Const32Value>(proc, Origin(), a),
2884 CHECK(compileAndRun<int>(proc, b) == (a | (b | c)));
2887 void testBitXorArgs(int64_t a, int64_t b)
2890 BasicBlock* root = proc.addBlock();
2891 root->appendNewControlValue(
2892 proc, Return, Origin(),
2893 root->appendNew<Value>(
2894 proc, BitXor, Origin(),
2895 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2896 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2898 CHECK(compileAndRun<int64_t>(proc, a, b) == (a ^ b));
2901 void testBitXorSameArg(int64_t a)
2904 BasicBlock* root = proc.addBlock();
2905 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2906 root->appendNewControlValue(
2907 proc, Return, Origin(),
2908 root->appendNew<Value>(
2909 proc, BitXor, Origin(),
2913 CHECK(!compileAndRun<int64_t>(proc, a));
2916 void testBitXorImms(int64_t a, int64_t b)
2919 BasicBlock* root = proc.addBlock();
2920 root->appendNewControlValue(
2921 proc, Return, Origin(),
2922 root->appendNew<Value>(
2923 proc, BitXor, Origin(),
2924 root->appendNew<Const64Value>(proc, Origin(), a),
2925 root->appendNew<Const64Value>(proc, Origin(), b)));
2927 CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
2930 void testBitXorArgImm(int64_t a, int64_t b)
2933 BasicBlock* root = proc.addBlock();
2934 root->appendNewControlValue(
2935 proc, Return, Origin(),
2936 root->appendNew<Value>(
2937 proc, BitXor, Origin(),
2938 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2939 root->appendNew<Const64Value>(proc, Origin(), b)));
2941 CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
2944 void testBitXorImmArg(int64_t a, int64_t b)
2947 BasicBlock* root = proc.addBlock();
2948 root->appendNewControlValue(
2949 proc, Return, Origin(),
2950 root->appendNew<Value>(
2951 proc, BitXor, Origin(),
2952 root->appendNew<Const64Value>(proc, Origin(), a),
2953 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2955 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
2958 void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
2961 BasicBlock* root = proc.addBlock();
2962 Value* innerBitXor = root->appendNew<Value>(
2963 proc, BitXor, Origin(),
2964 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2965 root->appendNew<Const64Value>(proc, Origin(), b));
2966 root->appendNewControlValue(
2967 proc, Return, Origin(),
2968 root->appendNew<Value>(
2969 proc, BitXor, Origin(),
2971 root->appendNew<Const64Value>(proc, Origin(), c)));
2973 CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
2976 void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
2979 BasicBlock* root = proc.addBlock();
2980 Value* innerBitXor = root->appendNew<Value>(
2981 proc, BitXor, Origin(),
2982 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2983 root->appendNew<Const64Value>(proc, Origin(), c));
2984 root->appendNewControlValue(
2985 proc, Return, Origin(),
2986 root->appendNew<Value>(
2987 proc, BitXor, Origin(),
2988 root->appendNew<Const64Value>(proc, Origin(), a),
2991 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
2994 void testBitXorArgs32(int a, int b)
2997 BasicBlock* root = proc.addBlock();
2998 root->appendNewControlValue(
2999 proc, Return, Origin(),
3000 root->appendNew<Value>(
3001 proc, BitXor, Origin(),
3002 root->appendNew<Value>(
3003 proc, Trunc, Origin(),
3004 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3005 root->appendNew<Value>(
3006 proc, Trunc, Origin(),
3007 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3009 CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
3012 void testBitXorSameArg32(int a)
3015 BasicBlock* root = proc.addBlock();
3016 Value* argument = root->appendNew<Value>(
3017 proc, Trunc, Origin(),
3018 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3019 root->appendNewControlValue(
3020 proc, Return, Origin(),
3021 root->appendNew<Value>(
3022 proc, BitXor, Origin(),
3026 CHECK(!compileAndRun<int>(proc, a));
3029 void testBitXorImms32(int a, int b)
3032 BasicBlock* root = proc.addBlock();
3033 root->appendNewControlValue(
3034 proc, Return, Origin(),
3035 root->appendNew<Value>(
3036 proc, BitXor, Origin(),
3037 root->appendNew<Const32Value>(proc, Origin(), a),
3038 root->appendNew<Const32Value>(proc, Origin(), b)));
3040 CHECK(compileAndRun<int>(proc) == (a ^ b));
3043 void testBitXorArgImm32(int a, int b)
3046 BasicBlock* root = proc.addBlock();
3047 root->appendNewControlValue(
3048 proc, Return, Origin(),
3049 root->appendNew<Value>(
3050 proc, BitXor, Origin(),
3051 root->appendNew<Value>(
3052 proc, Trunc, Origin(),
3053 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3054 root->appendNew<Const32Value>(proc, Origin(), b)));
3056 CHECK(compileAndRun<int>(proc, a) == (a ^ b));
3059 void testBitXorImmArg32(int a, int b)
3062 BasicBlock* root = proc.addBlock();
3063 root->appendNewControlValue(
3064 proc, Return, Origin(),
3065 root->appendNew<Value>(
3066 proc, BitXor, Origin(),
3067 root->appendNew<Const32Value>(proc, Origin(), a),
3068 root->appendNew<Value>(
3069 proc, Trunc, Origin(),
3070 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
3072 CHECK(compileAndRun<int>(proc, b) == (a ^ b));
3075 void testBitXorBitXorArgImmImm32(int a, int b, int c)
3078 BasicBlock* root = proc.addBlock();
3079 Value* innerBitXor = root->appendNew<Value>(
3080 proc, BitXor, Origin(),
3081 root->appendNew<Value>(
3082 proc, Trunc, Origin(),
3083 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3084 root->appendNew<Const32Value>(proc, Origin(), b));
3085 root->appendNewControlValue(
3086 proc, Return, Origin(),
3087 root->appendNew<Value>(
3088 proc, BitXor, Origin(),
3090 root->appendNew<Const32Value>(proc, Origin(), c)));
3092 CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
3095 void testBitXorImmBitXorArgImm32(int a, int b, int c)
3098 BasicBlock* root = proc.addBlock();
3099 Value* innerBitXor = root->appendNew<Value>(
3100 proc, BitXor, Origin(),
3101 root->appendNew<Value>(
3102 proc, Trunc, Origin(),
3103 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3104 root->appendNew<Const32Value>(proc, Origin(), c));
3105 root->appendNewControlValue(
3106 proc, Return, Origin(),
3107 root->appendNew<Value>(
3108 proc, BitXor, Origin(),
3109 root->appendNew<Const32Value>(proc, Origin(), a),
3112 CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
3115 void testBitNotArg(int64_t a)
3118 BasicBlock* root = proc.addBlock();
3119 root->appendNewControlValue(
3120 proc, Return, Origin(),
3121 root->appendNew<Value>(
3122 proc, BitXor, Origin(),
3123 root->appendNew<Const64Value>(proc, Origin(), -1),
3124 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
3126 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
3129 void testBitNotImm(int64_t a)
3132 BasicBlock* root = proc.addBlock();
3133 root->appendNewControlValue(
3134 proc, Return, Origin(),
3135 root->appendNew<Value>(
3136 proc, BitXor, Origin(),
3137 root->appendNew<Const64Value>(proc, Origin(), -1),
3138 root->appendNew<Const64Value>(proc, Origin(), a)));
3140 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
3143 void testBitNotMem(int64_t a)
3146 BasicBlock* root = proc.addBlock();
3147 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3148 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
3149 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
3150 root->appendNew<Const64Value>(proc, Origin(), -1),
3152 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
3153 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3156 compileAndRun<int32_t>(proc, &input);
3157 CHECK(isIdentical(input, static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
3160 void testBitNotArg32(int32_t a)
3163 BasicBlock* root = proc.addBlock();
3164 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
3165 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3166 root->appendNewControlValue(
3167 proc, Return, Origin(),
3168 root->appendNew<Value>(proc, BitXor, Origin(),
3169 root->appendNew<Const32Value>(proc, Origin(), -1),
3171 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
3174 void testBitNotImm32(int32_t a)
3177 BasicBlock* root = proc.addBlock();
3178 root->appendNewControlValue(
3179 proc, Return, Origin(),
3180 root->appendNew<Value>(
3181 proc, BitXor, Origin(),
3182 root->appendNew<Const32Value>(proc, Origin(), -1),
3183 root->appendNew<Const32Value>(proc, Origin(), a)));
3185 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
3188 void testBitNotMem32(int32_t a)
3191 BasicBlock* root = proc.addBlock();
3192 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3193 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
3194 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
3195 root->appendNew<Const32Value>(proc, Origin(), -1),
3197 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
3198 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3201 compileAndRun<int32_t>(proc, &input);
3202 CHECK(isIdentical(input, static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
3205 void testBitNotOnBooleanAndBranch32(int64_t a, int64_t b)
3208 BasicBlock* root = proc.addBlock();
3209 BasicBlock* thenCase = proc.addBlock();
3210 BasicBlock* elseCase = proc.addBlock();
3212 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
3213 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3214 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
3215 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
3216 Value* argsAreEqual = root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2);
3217 Value* argsAreNotEqual = root->appendNew<Value>(proc, BitXor, Origin(),
3218 root->appendNew<Const32Value>(proc, Origin(), -1),
3221 root->appendNewControlValue(
3222 proc, Branch, Origin(),
3224 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
3226 thenCase->appendNewControlValue(
3227 proc, Return, Origin(),
3228 thenCase->appendNew<Const32Value>(proc, Origin(), 42));
3230 elseCase->appendNewControlValue(
3231 proc, Return, Origin(),
3232 elseCase->appendNew<Const32Value>(proc, Origin(), -42));
3234 int32_t expectedValue = (a != b) ? 42 : -42;
3235 CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
3238 void testShlArgs(int64_t a, int64_t b)
3241 BasicBlock* root = proc.addBlock();
3242 root->appendNewControlValue(
3243 proc, Return, Origin(),
3244 root->appendNew<Value>(
3245 proc, Shl, Origin(),
3246 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3247 root->appendNew<Value>(
3248 proc, Trunc, Origin(),
3249 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3251 CHECK(compileAndRun<int64_t>(proc, a, b) == (a << b));
3254 void testShlImms(int64_t a, int64_t b)
3257 BasicBlock* root = proc.addBlock();
3258 root->appendNewControlValue(
3259 proc, Return, Origin(),
3260 root->appendNew<Value>(
3261 proc, Shl, Origin(),
3262 root->appendNew<Const64Value>(proc, Origin(), a),
3263 root->appendNew<Const32Value>(proc, Origin(), b)));
3265 CHECK(compileAndRun<int64_t>(proc) == (a << b));
3268 void testShlArgImm(int64_t a, int64_t b)
3271 BasicBlock* root = proc.addBlock();
3272 root->appendNewControlValue(
3273 proc, Return, Origin(),
3274 root->appendNew<Value>(
3275 proc, Shl, Origin(),
3276 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3277 root->appendNew<Const32Value>(proc, Origin(), b)));
3279 CHECK(compileAndRun<int64_t>(proc, a) == (a << b));
3282 void testShlArg32(int32_t a)
3285 BasicBlock* root = proc.addBlock();
3286 Value* value = root->appendNew<Value>(
3287 proc, Trunc, Origin(),
3288 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3289 root->appendNewControlValue(
3290 proc, Return, Origin(),
3291 root->appendNew<Value>(proc, Shl, Origin(), value, value));
3293 CHECK(compileAndRun<int32_t>(proc, a) == (a << a));
3296 void testShlArgs32(int32_t a, int32_t b)
3299 BasicBlock* root = proc.addBlock();
3300 root->appendNewControlValue(
3301 proc, Return, Origin(),
3302 root->appendNew<Value>(
3303 proc, Shl, Origin(),
3304 root->appendNew<Value>(
3305 proc, Trunc, Origin(),
3306 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3307 root->appendNew<Value>(
3308 proc, Trunc, Origin(),
3309 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3311 CHECK(compileAndRun<int32_t>(proc, a, b) == (a << b));
3314 void testShlImms32(int32_t a, int32_t b)
3317 BasicBlock* root = proc.addBlock();
3318 root->appendNewControlValue(
3319 proc, Return, Origin(),
3320 root->appendNew<Value>(
3321 proc, Shl, Origin(),
3322 root->appendNew<Const32Value>(proc, Origin(), a),
3323 root->appendNew<Const32Value>(proc, Origin(), b)));
3325 CHECK(compileAndRun<int32_t>(proc) == (a << b));
3328 void testShlArgImm32(int32_t a, int32_t b)
3331 BasicBlock* root = proc.addBlock();
3332 root->appendNewControlValue(
3333 proc, Return, Origin(),
3334 root->appendNew<Value>(
3335 proc, Shl, Origin(),
3336 root->appendNew<Value>(
3337 proc, Trunc, Origin(),
3338 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3339 root->appendNew<Const32Value>(proc, Origin(), b)));
3341 CHECK(compileAndRun<int32_t>(proc, a) == (a << b));
3344 void testSShrArgs(int64_t a, int64_t b)
3347 BasicBlock* root = proc.addBlock();
3348 root->appendNewControlValue(
3349 proc, Return, Origin(),
3350 root->appendNew<Value>(
3351 proc, SShr, Origin(),
3352 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3353 root->appendNew<Value>(
3354 proc, Trunc, Origin(),
3355 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3357 CHECK(compileAndRun<int64_t>(proc, a, b) == (a >> b));
3360 void testSShrImms(int64_t a, int64_t b)
3363 BasicBlock* root = proc.addBlock();
3364 root->appendNewControlValue(
3365 proc, Return, Origin(),
3366 root->appendNew<Value>(
3367 proc, SShr, Origin(),
3368 root->appendNew<Const64Value>(proc, Origin(), a),
3369 root->appendNew<Const32Value>(proc, Origin(), b)));
3371 CHECK(compileAndRun<int64_t>(proc) == (a >> b));
3374 void testSShrArgImm(int64_t a, int64_t b)
3377 BasicBlock* root = proc.addBlock();
3378 root->appendNewControlValue(
3379 proc, Return, Origin(),
3380 root->appendNew<Value>(
3381 proc, SShr, Origin(),
3382 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3383 root->appendNew<Const32Value>(proc, Origin(), b)));
3385 CHECK(compileAndRun<int64_t>(proc, a) == (a >> b));
3388 void testSShrArg32(int32_t a)
3391 BasicBlock* root = proc.addBlock();
3392 Value* value = root->appendNew<Value>(
3393 proc, Trunc, Origin(),
3394 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3395 root->appendNewControlValue(
3396 proc, Return, Origin(),
3397 root->appendNew<Value>(proc, SShr, Origin(), value, value));
3399 CHECK(compileAndRun<int32_t>(proc, a) == (a >> (a & 31)));
3402 void testSShrArgs32(int32_t a, int32_t b)
3405 BasicBlock* root = proc.addBlock();
3406 root->appendNewControlValue(
3407 proc, Return, Origin(),
3408 root->appendNew<Value>(
3409 proc, SShr, Origin(),
3410 root->appendNew<Value>(
3411 proc, Trunc, Origin(),
3412 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3413 root->appendNew<Value>(
3414 proc, Trunc, Origin(),
3415 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3417 CHECK(compileAndRun<int32_t>(proc, a, b) == (a >> b));
3420 void testSShrImms32(int32_t a, int32_t b)
3423 BasicBlock* root = proc.addBlock();
3424 root->appendNewControlValue(
3425 proc, Return, Origin(),
3426 root->appendNew<Value>(
3427 proc, SShr, Origin(),
3428 root->appendNew<Const32Value>(proc, Origin(), a),
3429 root->appendNew<Const32Value>(proc, Origin(), b)));
3431 CHECK(compileAndRun<int32_t>(proc) == (a >> b));
3434 void testSShrArgImm32(int32_t a, int32_t b)
3437 BasicBlock* root = proc.addBlock();
3438 root->appendNewControlValue(
3439 proc, Return, Origin(),
3440 root->appendNew<Value>(
3441 proc, SShr, Origin(),
3442 root->appendNew<Value>(
3443 proc, Trunc, Origin(),
3444 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3445 root->appendNew<Const32Value>(proc, Origin(), b)));
3447 CHECK(compileAndRun<int32_t>(proc, a) == (a >> b));
3450 void testZShrArgs(uint64_t a, uint64_t b)
3453 BasicBlock* root = proc.addBlock();
3454 root->appendNewControlValue(
3455 proc, Return, Origin(),
3456 root->appendNew<Value>(
3457 proc, ZShr, Origin(),
3458 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3459 root->appendNew<Value>(
3460 proc, Trunc, Origin(),
3461 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3463 CHECK(compileAndRun<uint64_t>(proc, a, b) == (a >> b));
3466 void testZShrImms(uint64_t a, uint64_t b)
3469 BasicBlock* root = proc.addBlock();
3470 root->appendNewControlValue(
3471 proc, Return, Origin(),
3472 root->appendNew<Value>(
3473 proc, ZShr, Origin(),
3474 root->appendNew<Const64Value>(proc, Origin(), a),
3475 root->appendNew<Const32Value>(proc, Origin(), b)));
3477 CHECK(compileAndRun<uint64_t>(proc) == (a >> b));
3480 void testZShrArgImm(uint64_t a, uint64_t b)
3483 BasicBlock* root = proc.addBlock();
3484 root->appendNewControlValue(
3485 proc, Return, Origin(),
3486 root->appendNew<Value>(
3487 proc, ZShr, Origin(),
3488 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3489 root->appendNew<Const32Value>(proc, Origin(), b)));
3491 CHECK(compileAndRun<uint64_t>(proc, a) == (a >> b));
3494 void testZShrArg32(uint32_t a)
3497 BasicBlock* root = proc.addBlock();
3498 Value* value = root->appendNew<Value>(
3499 proc, Trunc, Origin(),
3500 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3501 root->appendNewControlValue(
3502 proc, Return, Origin(),
3503 root->appendNew<Value>(proc, ZShr, Origin(), value, value));
3505 CHECK(compileAndRun<uint32_t>(proc, a) == (a >> (a & 31)));
3508 void testZShrArgs32(uint32_t a, uint32_t b)
3511 BasicBlock* root = proc.addBlock();
3512 root->appendNewControlValue(
3513 proc, Return, Origin(),
3514 root->appendNew<Value>(
3515 proc, ZShr, Origin(),
3516 root->appendNew<Value>(
3517 proc, Trunc, Origin(),
3518 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3519 root->appendNew<Value>(
3520 proc, Trunc, Origin(),
3521 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3523 CHECK(compileAndRun<uint32_t>(proc, a, b) == (a >> b));
3526 void testZShrImms32(uint32_t a, uint32_t b)
3529 BasicBlock* root = proc.addBlock();
3530 root->appendNewControlValue(
3531 proc, Return, Origin(),
3532 root->appendNew<Value>(
3533 proc, ZShr, Origin(),
3534 root->appendNew<Const32Value>(proc, Origin(), a),
3535 root->appendNew<Const32Value>(proc, Origin(), b)));
3537 CHECK(compileAndRun<uint32_t>(proc) == (a >> b));
3540 void testZShrArgImm32(uint32_t a, uint32_t b)
3543 BasicBlock* root = proc.addBlock();
3544 root->appendNewControlValue(
3545 proc, Return, Origin(),
3546 root->appendNew<Value>(
3547 proc, ZShr, Origin(),
3548 root->appendNew<Value>(
3549 proc, Trunc, Origin(),
3550 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3551 root->appendNew<Const32Value>(proc, Origin(), b)));
3553 CHECK(compileAndRun<uint32_t>(proc, a) == (a >> b));
3556 template<typename IntegerType>
3557 static unsigned countLeadingZero(IntegerType value)
3559 unsigned bitCount = sizeof(IntegerType) * 8;
3563 unsigned counter = 0;
3564 while (!(static_cast<uint64_t>(value) & (1l << (bitCount - 1)))) {
3571 void testClzArg64(int64_t a)
3574 BasicBlock* root = proc.addBlock();
3575 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3576 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
3577 root->appendNewControlValue(proc, Return, Origin(), clzValue);
3578 CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
3581 void testClzMem64(int64_t a)
3584 BasicBlock* root = proc.addBlock();
3585 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3586 MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
3587 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
3588 root->appendNewControlValue(proc, Return, Origin(), clzValue);
3589 CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
3592 void testClzArg32(int32_t a)
3595 BasicBlock* root = proc.addBlock();
3596 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
3597 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3598 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
3599 root->appendNewControlValue(proc, Return, Origin(), clzValue);
3600 CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
3603 void testClzMem32(int32_t a)
3606 BasicBlock* root = proc.addBlock();
3607 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3608 MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
3609 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
3610 root->appendNewControlValue(proc, Return, Origin(), clzValue);
3611 CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
3614 void testAbsArg(double a)
3617 BasicBlock* root = proc.addBlock();
3618 root->appendNewControlValue(
3619 proc, Return, Origin(),
3620 root->appendNew<Value>(
3621 proc, Abs, Origin(),
3622 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
3624 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
3627 void testAbsImm(double a)
3630 BasicBlock* root = proc.addBlock();
3631 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
3632 root->appendNewControlValue(
3633 proc, Return, Origin(),
3634 root->appendNew<Value>(proc, Abs, Origin(), argument));
3636 CHECK(isIdentical(compileAndRun<double>(proc), fabs(a)));
3639 void testAbsMem(double a)
3642 BasicBlock* root = proc.addBlock();
3643 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3644 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3645 root->appendNewControlValue(
3646 proc, Return, Origin(),
3647 root->appendNew<Value>(proc, Abs, Origin(), loadDouble));
3649 CHECK(isIdentical(compileAndRun<double>(proc, &a), fabs(a)));
3652 void testAbsAbsArg(double a)
3655 BasicBlock* root = proc.addBlock();
3656 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(),
3657 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
3658 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
3659 root->appendNewControlValue(proc, Return, Origin(), secondAbs);
3661 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
3664 void testAbsBitwiseCastArg(double a)
3667 BasicBlock* root = proc.addBlock();
3668 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3669 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
3670 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
3671 root->appendNewControlValue(proc, Return, Origin(), absValue);
3673 CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int64_t>(a)), fabs(a)));
3676 void testBitwiseCastAbsBitwiseCastArg(double a)
3679 BasicBlock* root = proc.addBlock();
3680 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3681 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
3682 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
3683 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
3685 root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
3687 int64_t expectedResult = bitwise_cast<int64_t>(fabs(a));
3688 CHECK(isIdentical(compileAndRun<int64_t>(proc, bitwise_cast<int64_t>(a)), expectedResult));
3691 void testAbsArg(float a)
3694 BasicBlock* root = proc.addBlock();
3695 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3696 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3697 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3698 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
3699 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3700 root->appendNewControlValue(proc, Return, Origin(), result32);
3702 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3705 void testAbsImm(float a)
3708 BasicBlock* root = proc.addBlock();
3709 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
3710 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
3711 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3712 root->appendNewControlValue(proc, Return, Origin(), result32);
3714 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3717 void testAbsMem(float a)
3720 BasicBlock* root = proc.addBlock();
3721 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3722 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
3723 Value* result = root->appendNew<Value>(proc, Abs, Origin(), loadFloat);
3724 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3725 root->appendNewControlValue(proc, Return, Origin(), result32);
3727 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3730 void testAbsAbsArg(float a)
3733 BasicBlock* root = proc.addBlock();
3734 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3735 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3736 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3737 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(), argument);
3738 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
3739 root->appendNewControlValue(proc, Return, Origin(), secondAbs);
3741 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
3744 void testAbsBitwiseCastArg(float a)
3747 BasicBlock* root = proc.addBlock();
3748 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
3749 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3750 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
3751 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
3752 root->appendNewControlValue(proc, Return, Origin(), absValue);
3754 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
3757 void testBitwiseCastAbsBitwiseCastArg(float a)
3760 BasicBlock* root = proc.addBlock();
3761 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
3762 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3763 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
3764 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
3765 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
3767 root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
3769 int32_t expectedResult = bitwise_cast<int32_t>(static_cast<float>(fabs(a)));
3770 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), expectedResult));
3773 void testAbsArgWithUselessDoubleConversion(float a)
3776 BasicBlock* root = proc.addBlock();
3777 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3778 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3779 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3780 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3781 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
3782 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3783 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3784 root->appendNewControlValue(proc, Return, Origin(), result32);
3786 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3789 void testAbsArgWithEffectfulDoubleConversion(float a)
3792 BasicBlock* root = proc.addBlock();
3793 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3794 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3795 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3796 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3797 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
3798 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3799 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3800 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3801 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
3802 root->appendNewControlValue(proc, Return, Origin(), result32);
3805 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
3806 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3807 CHECK(isIdentical(effect, fabs(a)));
3810 void testCeilArg(double a)
3813 BasicBlock* root = proc.addBlock();
3814 root->appendNewControlValue(
3815 proc, Return, Origin(),
3816 root->appendNew<Value>(
3817 proc, Ceil, Origin(),
3818 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
3820 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
3823 void testCeilImm(double a)
3826 BasicBlock* root = proc.addBlock();
3827 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
3828 root->appendNewControlValue(
3829 proc, Return, Origin(),
3830 root->appendNew<Value>(proc, Ceil, Origin(), argument));
3832 CHECK(isIdentical(compileAndRun<double>(proc), ceil(a)));
3835 void testCeilMem(double a)
3838 BasicBlock* root = proc.addBlock();
3839 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3840 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3841 root->appendNewControlValue(
3842 proc, Return, Origin(),
3843 root->appendNew<Value>(proc, Ceil, Origin(), loadDouble));
3845 CHECK(isIdentical(compileAndRun<double>(proc, &a), ceil(a)));
3848 void testCeilCeilArg(double a)
3851 BasicBlock* root = proc.addBlock();
3852 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
3853 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
3854 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
3855 root->appendNewControlValue(proc, Return, Origin(), secondCeil);
3857 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
3860 void testFloorCeilArg(double a)
3863 BasicBlock* root = proc.addBlock();
3864 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
3865 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
3866 Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
3867 root->appendNewControlValue(proc, Return, Origin(), wrappingFloor);
3869 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
3872 void testCeilIToD64(int64_t a)
3875 BasicBlock* root = proc.addBlock();
3876 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3877 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
3879 root->appendNewControlValue(
3880 proc, Return, Origin(),
3881 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
3883 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
3886 void testCeilIToD32(int64_t a)
3889 BasicBlock* root = proc.addBlock();
3890 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
3891 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3892 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
3894 root->appendNewControlValue(
3895 proc, Return, Origin(),
3896 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
3898 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
3901 void testCeilArg(float a)
3904 BasicBlock* root = proc.addBlock();
3905 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3906 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3907 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3908 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
3909 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3910 root->appendNewControlValue(proc, Return, Origin(), result32);
3912 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
3915 void testCeilImm(float a)
3918 BasicBlock* root = proc.addBlock();
3919 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
3920 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
3921 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3922 root->appendNewControlValue(proc, Return, Origin(), result32);
3924 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
3927 void testCeilMem(float a)
3930 BasicBlock* root = proc.addBlock();
3931 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3932 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
3933 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), loadFloat);
3934 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3935 root->appendNewControlValue(proc, Return, Origin(), result32);
3937 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(ceilf(a))));
3940 void testCeilCeilArg(float a)
3943 BasicBlock* root = proc.addBlock();
3944 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3945 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3946 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3947 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
3948 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
3949 root->appendNewControlValue(proc, Return, Origin(), secondCeil);
3951 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
3954 void testFloorCeilArg(float a)
3957 BasicBlock* root = proc.addBlock();
3958 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3959 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3960 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3961 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
3962 Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
3963 root->appendNewControlValue(proc, Return, Origin(), wrappingFloor);
3965 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
3968 void testCeilArgWithUselessDoubleConversion(float a)
3971 BasicBlock* root = proc.addBlock();
3972 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3973 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3974 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3975 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3976 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
3977 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3978 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3979 root->appendNewControlValue(proc, Return, Origin(), result32);
3981 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
3984 void testCeilArgWithEffectfulDoubleConversion(float a)
3987 BasicBlock* root = proc.addBlock();
3988 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3989 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3990 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3991 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3992 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
3993 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3994 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3995 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3996 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
3997 root->appendNewControlValue(proc, Return, Origin(), result32);
4000 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
4001 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(ceilf(a))));
4002 CHECK(isIdentical(effect, ceilf(a)));
4005 void testFloorArg(double a)
4008 BasicBlock* root = proc.addBlock();
4009 root->appendNewControlValue(
4010 proc, Return, Origin(),
4011 root->appendNew<Value>(
4012 proc, Floor, Origin(),
4013 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
4015 CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
4018 void testFloorImm(double a)
4021 BasicBlock* root = proc.addBlock();
4022 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
4023 root->appendNewControlValue(
4024 proc, Return, Origin(),
4025 root->appendNew<Value>(proc, Floor, Origin(), argument));
4027 CHECK(isIdentical(compileAndRun<double>(proc), floor(a)));
4030 void testFloorMem(double a)
4033 BasicBlock* root = proc.addBlock();
4034 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
4035 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
4036 root->appendNewControlValue(
4037 proc, Return, Origin(),
4038 root->appendNew<Value>(proc, Floor, Origin(), loadDouble));
4040 CHECK(isIdentical(compileAndRun<double>(proc, &a), floor(a)));
4043 void testFloorFloorArg(double a)
4046 BasicBlock* root = proc.addBlock();
4047 Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(),
4048 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
4049 Value* secondFloor = root->appendNew<Value>(proc, Floor, Origin(), firstFloor);
4050 root->appendNewControlValue(proc, Return, Origin(), secondFloor);
4052 CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
4055 void testCeilFloorArg(double a)
4058 BasicBlock* root = proc.addBlock();
4059 Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(),
4060 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
4061 Value* wrappingCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstFloor);
4062 root->appendNewControlValue(proc, Return, Origin(), wrappingCeil);
4064 CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
4067 void testFloorIToD64(int64_t a)
4070 BasicBlock* root = proc.addBlock();
4071 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
4072 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
4074 root->appendNewControlValue(
4075 proc, Return, Origin(),
4076 root->appendNew<Value>(proc, Floor, Origin(), argumentAsDouble));
4078 CHECK(isIdentical(compileAndRun<double>(proc, a), floor(static_cast<double>(a))));
4081 void testFloorIToD32(int64_t a)
4084 BasicBlock* root = proc.addBlock();