2 * Copyright (C) 2015-2019 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.
34 BasicBlock* root = proc.addBlock();
35 Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
36 root->appendNewControlValue(proc, Return, Origin(), const42);
38 CHECK(compileAndRun<int>(proc) == 42);
44 BasicBlock* root = proc.addBlock();
46 root->appendNewControlValue(
47 proc, Return, Origin(),
48 root->appendNew<MemoryValue>(
49 proc, Load, Int32, Origin(),
50 root->appendNew<ConstPtrValue>(proc, Origin(), &x)));
52 CHECK(compileAndRun<int>(proc) == 42);
58 BasicBlock* root = proc.addBlock();
60 root->appendNewControlValue(
61 proc, Return, Origin(),
62 root->appendNew<MemoryValue>(
63 proc, Load, Int32, Origin(),
64 root->appendNew<ConstPtrValue>(proc, Origin(), &x),
65 0, HeapRange(42), HeapRange(42)));
67 auto code = compileProc(proc);
69 checkUsesInstruction(*code, "lda");
70 CHECK(invoke<int>(*code) == 42);
73 void testLoadWithOffsetImpl(int32_t offset64, int32_t offset32)
77 BasicBlock* root = proc.addBlock();
79 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
80 root->appendNewControlValue(
81 proc, Return, Origin(),
82 root->appendNew<MemoryValue>(
83 proc, Load, Int64, Origin(),
87 char* address = reinterpret_cast<char*>(&x) - offset64;
88 CHECK(compileAndRun<int64_t>(proc, address) == -42);
92 BasicBlock* root = proc.addBlock();
94 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
95 root->appendNewControlValue(
96 proc, Return, Origin(),
97 root->appendNew<MemoryValue>(
98 proc, Load, Int32, Origin(),
102 char* address = reinterpret_cast<char*>(&x) - offset32;
103 CHECK(compileAndRun<int32_t>(proc, address) == -42);
107 void testLoadOffsetImm9Max()
109 testLoadWithOffsetImpl(255, 255);
112 void testLoadOffsetImm9MaxPlusOne()
114 testLoadWithOffsetImpl(256, 256);
117 void testLoadOffsetImm9MaxPlusTwo()
119 testLoadWithOffsetImpl(257, 257);
122 void testLoadOffsetImm9Min()
124 testLoadWithOffsetImpl(-256, -256);
127 void testLoadOffsetImm9MinMinusOne()
129 testLoadWithOffsetImpl(-257, -257);
132 void testLoadOffsetScaledUnsignedImm12Max()
134 testLoadWithOffsetImpl(32760, 16380);
137 void testLoadOffsetScaledUnsignedOverImm12Max()
139 testLoadWithOffsetImpl(32760, 32760);
140 testLoadWithOffsetImpl(32761, 16381);
141 testLoadWithOffsetImpl(32768, 16384);
144 static void testBitXorTreeArgs(int64_t a, int64_t b)
147 BasicBlock* root = proc.addBlock();
148 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
149 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
150 Value* node = root->appendNew<Value>(proc, BitXor, Origin(), argA, argB);
151 node = root->appendNew<Value>(proc, BitXor, Origin(), node, argB);
152 node = root->appendNew<Value>(proc, BitXor, Origin(), node, argA);
153 node = root->appendNew<Value>(proc, BitXor, Origin(), node, argB);
154 root->appendNew<Value>(proc, Return, Origin(), node);
156 CHECK_EQ(compileAndRun<int64_t>(proc, a, b), (((a ^ b) ^ b) ^ a) ^ b);
159 static void testBitXorTreeArgsEven(int64_t a, int64_t b)
162 BasicBlock* root = proc.addBlock();
163 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
164 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
165 Value* node = root->appendNew<Value>(proc, BitXor, Origin(), argA, argB);
166 node = root->appendNew<Value>(proc, BitXor, Origin(), node, argB);
167 node = root->appendNew<Value>(proc, BitXor, Origin(), node, argA);
168 root->appendNew<Value>(proc, Return, Origin(), node);
170 CHECK_EQ(compileAndRun<int64_t>(proc, a, b), ((a ^ b) ^ b) ^ a);
173 static void testBitXorTreeArgImm(int64_t a, int64_t b)
176 BasicBlock* root = proc.addBlock();
177 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
178 Value* immB = root->appendNew<Const64Value>(proc, Origin(), b);
179 Value* node = root->appendNew<Value>(proc, BitXor, Origin(), argA, immB);
180 node = root->appendNew<Value>(proc, BitXor, Origin(), argA, node);
181 node = root->appendNew<Value>(proc, BitXor, Origin(), argA, node);
182 node = root->appendNew<Value>(proc, BitXor, Origin(), immB, node);
183 root->appendNew<Value>(proc, Return, Origin(), node);
185 CHECK_EQ(compileAndRun<int64_t>(proc, a), b ^ (a ^ (a ^ (a ^ b))));
188 void testAddTreeArg32(int32_t a)
191 BasicBlock* root = proc.addBlock();
192 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
193 argA = root->appendNew<Value>(proc, Trunc, Origin(), argA);
195 int32_t expectedResult = a;
196 for (unsigned i = 0; i < 20; ++i) {
199 otherNode = root->appendNew<Const32Value>(proc, Origin(), i);
205 node = root->appendNew<Value>(proc, Add, Origin(), node, otherNode);
207 root->appendNew<Value>(proc, Return, Origin(), node);
209 CHECK_EQ(compileAndRun<int32_t>(proc, a), expectedResult);
212 void testMulTreeArg32(int32_t a)
214 // Fibonacci-like expression tree with multiplication instead of addition.
215 // Verifies that we don't explode on heavily factored graphs.
217 BasicBlock* root = proc.addBlock();
218 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
219 argA = root->appendNew<Value>(proc, Trunc, Origin(), argA);
222 int32_t expectedA = a, expectedResult = a;
223 for (unsigned i = 0; i < 20; ++i) {
224 Value* newNodeB = root->appendNew<Value>(proc, Mul, Origin(), nodeA, nodeB);
227 int32_t newExpectedResult = expectedA * expectedResult;
228 expectedA = expectedResult;
229 expectedResult = newExpectedResult;
231 root->appendNew<Value>(proc, Return, Origin(), nodeB);
233 CHECK_EQ(compileAndRun<int32_t>(proc, a), expectedResult);
236 static void testBitAndTreeArg32(int32_t a)
239 BasicBlock* root = proc.addBlock();
240 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
241 argA = root->appendNew<Value>(proc, Trunc, Origin(), argA);
243 for (unsigned i = 0; i < 8; ++i) {
244 Value* constI = root->appendNew<Const32Value>(proc, Origin(), i | 42);
245 Value* newBitAnd = root->appendNew<Value>(proc, BitAnd, Origin(), argA, constI);
246 node = root->appendNew<Value>(proc, BitAnd, Origin(), node, newBitAnd);
248 root->appendNew<Value>(proc, Return, Origin(), node);
250 CHECK_EQ(compileAndRun<int32_t>(proc, a), a & 42);
253 static void testBitOrTreeArg32(int32_t a)
256 BasicBlock* root = proc.addBlock();
257 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
258 argA = root->appendNew<Value>(proc, Trunc, Origin(), argA);
260 for (unsigned i = 0; i < 8; ++i) {
261 Value* constI = root->appendNew<Const32Value>(proc, Origin(), i);
262 Value* newBitAnd = root->appendNew<Value>(proc, BitOr, Origin(), argA, constI);
263 node = root->appendNew<Value>(proc, BitOr, Origin(), node, newBitAnd);
265 root->appendNew<Value>(proc, Return, Origin(), node);
267 CHECK_EQ(compileAndRun<int32_t>(proc, a), a | 7);
270 void testArg(int argument)
273 BasicBlock* root = proc.addBlock();
274 root->appendNewControlValue(
275 proc, Return, Origin(),
276 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
278 CHECK(compileAndRun<int>(proc, argument) == argument);
281 void testReturnConst64(int64_t value)
284 BasicBlock* root = proc.addBlock();
285 root->appendNewControlValue(
286 proc, Return, Origin(),
287 root->appendNew<Const64Value>(proc, Origin(), value));
289 CHECK(compileAndRun<int64_t>(proc) == value);
292 void testReturnVoid()
295 BasicBlock* root = proc.addBlock();
296 root->appendNewControlValue(proc, Return, Origin());
297 compileAndRun<void>(proc);
300 void testAddArg(int a)
303 BasicBlock* root = proc.addBlock();
304 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
305 root->appendNewControlValue(
306 proc, Return, Origin(),
307 root->appendNew<Value>(proc, Add, Origin(), value, value));
309 CHECK(compileAndRun<int>(proc, a) == a + a);
312 void testAddArgs(int a, int b)
315 BasicBlock* root = proc.addBlock();
316 root->appendNewControlValue(
317 proc, Return, Origin(),
318 root->appendNew<Value>(
320 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
321 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
323 CHECK(compileAndRun<int>(proc, a, b) == a + b);
326 void testAddArgImm(int a, int b)
329 BasicBlock* root = proc.addBlock();
330 root->appendNewControlValue(
331 proc, Return, Origin(),
332 root->appendNew<Value>(
334 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
335 root->appendNew<Const64Value>(proc, Origin(), b)));
337 CHECK(compileAndRun<int>(proc, a) == a + b);
340 void testAddImmArg(int a, int b)
343 BasicBlock* root = proc.addBlock();
344 root->appendNewControlValue(
345 proc, Return, Origin(),
346 root->appendNew<Value>(
348 root->appendNew<Const64Value>(proc, Origin(), a),
349 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
351 CHECK(compileAndRun<int>(proc, b) == a + b);
354 void testAddArgMem(int64_t a, int64_t b)
357 BasicBlock* root = proc.addBlock();
358 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
359 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
360 Value* result = root->appendNew<Value>(proc, Add, Origin(),
361 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
363 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
364 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
366 int64_t inputOutput = b;
367 CHECK(!compileAndRun<int64_t>(proc, a, &inputOutput));
368 CHECK(inputOutput == a + b);
371 void testAddMemArg(int64_t a, int64_t b)
374 BasicBlock* root = proc.addBlock();
375 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
376 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
377 Value* result = root->appendNew<Value>(proc, Add, Origin(),
379 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
380 root->appendNewControlValue(proc, Return, Origin(), result);
382 CHECK(compileAndRun<int64_t>(proc, &a, b) == a + b);
385 void testAddImmMem(int64_t a, int64_t b)
388 BasicBlock* root = proc.addBlock();
389 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
390 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
391 Value* result = root->appendNew<Value>(proc, Add, Origin(),
392 root->appendNew<Const64Value>(proc, Origin(), a),
394 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
395 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
397 int64_t inputOutput = b;
398 CHECK(!compileAndRun<int>(proc, &inputOutput));
399 CHECK(inputOutput == a + b);
402 void testAddArg32(int a)
405 BasicBlock* root = proc.addBlock();
406 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
407 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
408 root->appendNewControlValue(
409 proc, Return, Origin(),
410 root->appendNew<Value>(proc, Add, Origin(), value, value));
412 CHECK(compileAndRun<int>(proc, a) == a + a);
415 void testAddArgs32(int a, int b)
418 BasicBlock* root = proc.addBlock();
419 root->appendNewControlValue(
420 proc, Return, Origin(),
421 root->appendNew<Value>(
423 root->appendNew<Value>(
424 proc, Trunc, Origin(),
425 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
426 root->appendNew<Value>(
427 proc, Trunc, Origin(),
428 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
430 CHECK(compileAndRun<int>(proc, a, b) == a + b);
433 void testAddArgMem32(int32_t a, int32_t b)
436 BasicBlock* root = proc.addBlock();
437 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
438 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
439 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
440 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
441 Value* result = root->appendNew<Value>(proc, Add, Origin(), argument, load);
442 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
443 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
445 int32_t inputOutput = b;
446 CHECK(!compileAndRun<int32_t>(proc, a, &inputOutput));
447 CHECK(inputOutput == a + b);
450 void testAddMemArg32(int32_t a, int32_t b)
453 BasicBlock* root = proc.addBlock();
454 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
455 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
456 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
457 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
458 Value* result = root->appendNew<Value>(proc, Add, Origin(), load, argument);
459 root->appendNewControlValue(proc, Return, Origin(), result);
461 CHECK(compileAndRun<int32_t>(proc, &a, b) == a + b);
464 void testAddImmMem32(int32_t a, int32_t b)
467 BasicBlock* root = proc.addBlock();
468 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
469 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
470 Value* result = root->appendNew<Value>(proc, Add, Origin(),
471 root->appendNew<Const32Value>(proc, Origin(), a),
473 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
474 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
476 int32_t inputOutput = b;
477 CHECK(!compileAndRun<int>(proc, &inputOutput));
478 CHECK(inputOutput == a + b);
481 void testAddNeg1(int a, int b)
484 BasicBlock* root = proc.addBlock();
485 root->appendNewControlValue(
486 proc, Return, Origin(),
487 root->appendNew<Value>(
489 root->appendNew<Value>(proc, Neg, Origin(),
490 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
491 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
493 CHECK(compileAndRun<int>(proc, a, b) == (- a) + b);
496 void testAddNeg2(int a, int b)
499 BasicBlock* root = proc.addBlock();
500 root->appendNewControlValue(
501 proc, Return, Origin(),
502 root->appendNew<Value>(
504 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
505 root->appendNew<Value>(proc, Neg, Origin(),
506 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
508 CHECK(compileAndRun<int>(proc, a, b) == a + (- b));
511 void testAddArgZeroImmZDef()
514 BasicBlock* root = proc.addBlock();
515 Value* arg = root->appendNew<Value>(
516 proc, Trunc, Origin(),
517 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
518 Value* constZero = root->appendNew<Const32Value>(proc, Origin(), 0);
519 root->appendNewControlValue(
520 proc, Return, Origin(),
521 root->appendNew<Value>(
526 auto code = compileProc(proc, 0);
527 CHECK(invoke<int64_t>(*code, 0x0123456789abcdef) == 0x89abcdef);
530 void testAddLoadTwice()
534 BasicBlock* root = proc.addBlock();
536 Value* load = root->appendNew<MemoryValue>(
537 proc, Load, Int32, Origin(),
538 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
539 root->appendNewControlValue(
540 proc, Return, Origin(),
541 root->appendNew<Value>(proc, Add, Origin(), load, load));
543 auto code = compileProc(proc);
544 CHECK(invoke<int32_t>(*code) == 42 * 2);
550 void testAddArgDouble(double a)
553 BasicBlock* root = proc.addBlock();
554 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
555 root->appendNewControlValue(
556 proc, Return, Origin(),
557 root->appendNew<Value>(proc, Add, Origin(), value, value));
559 CHECK(isIdentical(compileAndRun<double>(proc, a), a + a));
562 void testAddArgsDouble(double a, double b)
565 BasicBlock* root = proc.addBlock();
566 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
567 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
568 root->appendNewControlValue(
569 proc, Return, Origin(),
570 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
572 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a + b));
575 void testAddArgImmDouble(double a, double b)
578 BasicBlock* root = proc.addBlock();
579 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
580 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
581 root->appendNewControlValue(
582 proc, Return, Origin(),
583 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
585 CHECK(isIdentical(compileAndRun<double>(proc, a), a + b));
588 void testAddImmArgDouble(double a, double b)
591 BasicBlock* root = proc.addBlock();
592 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
593 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
594 root->appendNewControlValue(
595 proc, Return, Origin(),
596 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
598 CHECK(isIdentical(compileAndRun<double>(proc, b), a + b));
601 void testAddImmsDouble(double a, double b)
604 BasicBlock* root = proc.addBlock();
605 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
606 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
607 root->appendNewControlValue(
608 proc, Return, Origin(),
609 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
611 CHECK(isIdentical(compileAndRun<double>(proc), a + b));
614 void testAddArgFloat(float a)
617 BasicBlock* root = proc.addBlock();
618 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
619 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
620 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
621 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, floatValue);
622 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
623 root->appendNewControlValue(proc, Return, Origin(), result32);
626 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
629 void testAddArgsFloat(float a, float b)
632 BasicBlock* root = proc.addBlock();
633 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
634 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
635 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
636 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
637 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
638 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
639 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue1, floatValue2);
640 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
641 root->appendNewControlValue(proc, Return, Origin(), result32);
643 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
646 void testAddFPRArgsFloat(float a, float b)
649 BasicBlock* root = proc.addBlock();
650 Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
651 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
652 Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
653 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1));
654 Value* result = root->appendNew<Value>(proc, Add, Origin(), argument1, argument2);
655 root->appendNewControlValue(proc, Return, Origin(), result);
657 CHECK(isIdentical(compileAndRun<float>(proc, a, b), a + b));
660 void testAddArgImmFloat(float a, float b)
663 BasicBlock* root = proc.addBlock();
664 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
665 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
666 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
667 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
668 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, constValue);
669 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
670 root->appendNewControlValue(proc, Return, Origin(), result32);
672 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + b)));
675 void testAddImmArgFloat(float a, float b)
678 BasicBlock* root = proc.addBlock();
679 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
680 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
681 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
682 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
683 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue, floatValue);
684 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
685 root->appendNewControlValue(proc, Return, Origin(), result32);
687 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
690 void testAddImmsFloat(float a, float b)
693 BasicBlock* root = proc.addBlock();
694 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
695 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
696 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue1, constValue2);
697 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
698 root->appendNewControlValue(proc, Return, Origin(), result32);
700 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a + b)));
703 void testAddArgFloatWithUselessDoubleConversion(float a)
706 BasicBlock* root = proc.addBlock();
707 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
708 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
709 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
710 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
711 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble, asDouble);
712 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
713 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
714 root->appendNewControlValue(proc, Return, Origin(), result32);
716 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
719 void testAddArgsFloatWithUselessDoubleConversion(float a, float b)
722 BasicBlock* root = proc.addBlock();
723 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
724 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
725 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
726 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
727 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
728 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
729 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
730 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
731 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
732 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
733 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
734 root->appendNewControlValue(proc, Return, Origin(), result32);
736 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
739 void testAddArgsFloatWithEffectfulDoubleConversion(float a, float b)
742 BasicBlock* root = proc.addBlock();
743 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
744 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
745 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
746 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
747 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
748 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
749 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
750 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
751 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
752 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
753 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
754 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
755 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
756 root->appendNewControlValue(proc, Return, Origin(), result32);
759 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a + b)));
760 CHECK(isIdentical(effect, static_cast<double>(a) + static_cast<double>(b)));
763 void testAddMulMulArgs(int64_t a, int64_t b, int64_t c)
765 // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
766 // ((a * b) + (a * c))
767 // ((a * b) + (c * a))
768 // ((b * a) + (a * c))
769 // ((b * a) + (c * a))
770 for (int i = 0; i < 4; ++i) {
772 BasicBlock* root = proc.addBlock();
773 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
774 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
775 Value* argC = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
776 Value* mulAB = i & 2 ? root->appendNew<Value>(proc, Mul, Origin(), argA, argB)
777 : root->appendNew<Value>(proc, Mul, Origin(), argB, argA);
778 Value* mulAC = i & 1 ? root->appendNew<Value>(proc, Mul, Origin(), argA, argC)
779 : root->appendNew<Value>(proc, Mul, Origin(), argC, argA);
780 root->appendNew<Value>(proc, Return, Origin(),
781 root->appendNew<Value>(proc, Add, Origin(),
785 CHECK_EQ(compileAndRun<int64_t>(proc, a, b, c), ((a * b) + (a * c)));
789 void testMulArg(int a)
792 BasicBlock* root = proc.addBlock();
793 Value* value = root->appendNew<Value>(
794 proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
795 root->appendNewControlValue(
796 proc, Return, Origin(),
797 root->appendNew<Value>(proc, Mul, Origin(), value, value));
799 CHECK(compileAndRun<int>(proc, a) == a * a);
802 void testMulArgStore(int a)
805 BasicBlock* root = proc.addBlock();
810 Value* value = root->appendNew<Value>(
811 proc, Trunc, Origin(),
812 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
813 Value* mul = root->appendNew<Value>(proc, Mul, Origin(), value, value);
815 root->appendNew<MemoryValue>(
816 proc, Store, Origin(), value,
817 root->appendNew<ConstPtrValue>(proc, Origin(), &valueSlot), 0);
818 root->appendNew<MemoryValue>(
819 proc, Store, Origin(), mul,
820 root->appendNew<ConstPtrValue>(proc, Origin(), &mulSlot), 0);
822 root->appendNewControlValue(
823 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
825 CHECK(!compileAndRun<int>(proc, a));
826 CHECK(mulSlot == a * a);
827 CHECK(valueSlot == a);
830 void testMulAddArg(int a)
833 BasicBlock* root = proc.addBlock();
834 Value* value = root->appendNew<Value>(
835 proc, Trunc, Origin(),
836 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
837 root->appendNewControlValue(
838 proc, Return, Origin(),
839 root->appendNew<Value>(
841 root->appendNew<Value>(proc, Mul, Origin(), value, value),
844 CHECK(compileAndRun<int>(proc, a) == a * a + a);
847 void testMulArgs(int a, int b)
850 BasicBlock* root = proc.addBlock();
851 root->appendNewControlValue(
852 proc, Return, Origin(),
853 root->appendNew<Value>(
855 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
856 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
858 CHECK(compileAndRun<int>(proc, a, b) == a * b);
861 void testMulArgNegArg(int a, int b)
864 BasicBlock* root = proc.addBlock();
865 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
866 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
867 Value* negB = root->appendNew<Value>(proc, Neg, Origin(), argB);
868 Value* result = root->appendNew<Value>(proc, Mul, Origin(), argA, negB);
869 root->appendNew<Value>(proc, Return, Origin(), result);
871 CHECK(compileAndRun<int>(proc, a, b) == a * (-b));
874 void testMulNegArgArg(int a, int b)
877 BasicBlock* root = proc.addBlock();
878 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
879 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
880 Value* negA = root->appendNew<Value>(proc, Neg, Origin(), argA);
881 Value* result = root->appendNew<Value>(proc, Mul, Origin(), negA, argB);
882 root->appendNew<Value>(proc, Return, Origin(), result);
884 CHECK(compileAndRun<int>(proc, a, b) == (-a) * b);
887 void testMulArgImm(int64_t a, int64_t b)
890 BasicBlock* root = proc.addBlock();
891 root->appendNewControlValue(
892 proc, Return, Origin(),
893 root->appendNew<Value>(
895 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
896 root->appendNew<Const64Value>(proc, Origin(), b)));
898 CHECK(compileAndRun<int64_t>(proc, a) == a * b);
901 void testMulImmArg(int a, int b)
904 BasicBlock* root = proc.addBlock();
905 root->appendNewControlValue(
906 proc, Return, Origin(),
907 root->appendNew<Value>(
909 root->appendNew<Const64Value>(proc, Origin(), a),
910 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
912 CHECK(compileAndRun<int>(proc, b) == a * b);
915 void testMulArgs32(int a, int b)
918 BasicBlock* root = proc.addBlock();
919 root->appendNewControlValue(
920 proc, Return, Origin(),
921 root->appendNew<Value>(
923 root->appendNew<Value>(
924 proc, Trunc, Origin(),
925 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
926 root->appendNew<Value>(
927 proc, Trunc, Origin(),
928 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
930 CHECK(compileAndRun<int>(proc, a, b) == a * b);
933 void testMulArgs32SignExtend(int a, int b)
936 if (proc.optLevel() < 1)
938 BasicBlock* root = proc.addBlock();
939 Value* arg1 = root->appendNew<Value>(
940 proc, Trunc, Origin(),
941 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
942 Value* arg2 = root->appendNew<Value>(
943 proc, Trunc, Origin(),
944 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
945 Value* arg164 = root->appendNew<Value>(proc, SExt32, Origin(), arg1);
946 Value* arg264 = root->appendNew<Value>(proc, SExt32, Origin(), arg2);
947 Value* mul = root->appendNew<Value>(proc, Mul, Origin(), arg164, arg264);
948 root->appendNewControlValue(proc, Return, Origin(), mul);
950 auto code = compileProc(proc);
952 CHECK(invoke<long int>(*code, a, b) == ((long int) a) * ((long int) b));
955 void testMulImm32SignExtend(const int a, int b)
958 if (proc.optLevel() < 1)
960 BasicBlock* root = proc.addBlock();
961 Value* arg1 = root->appendNew<Const64Value>(proc, Origin(), a);
962 Value* arg2 = root->appendNew<Value>(
963 proc, Trunc, Origin(),
964 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
965 Value* arg264 = root->appendNew<Value>(proc, SExt32, Origin(), arg2);
966 Value* mul = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg264);
967 root->appendNewControlValue(proc, Return, Origin(), mul);
969 auto code = compileProc(proc);
971 CHECK_EQ(invoke<long int>(*code, b), ((long int) a) * ((long int) b));
974 void testMulLoadTwice()
978 BasicBlock* root = proc.addBlock();
980 Value* load = root->appendNew<MemoryValue>(
981 proc, Load, Int32, Origin(),
982 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
983 root->appendNewControlValue(
984 proc, Return, Origin(),
985 root->appendNew<Value>(proc, Mul, Origin(), load, load));
987 auto code = compileProc(proc);
988 CHECK(invoke<int32_t>(*code) == 42 * 42);
994 void testMulAddArgsLeft()
997 BasicBlock* root = proc.addBlock();
999 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1000 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1001 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1002 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1003 Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
1004 root->appendNewControlValue(proc, Return, Origin(), added);
1006 auto code = compileProc(proc);
1008 auto testValues = int64Operands();
1009 for (auto a : testValues) {
1010 for (auto b : testValues) {
1011 for (auto c : testValues) {
1012 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
1018 void testMulAddArgsRight()
1021 BasicBlock* root = proc.addBlock();
1023 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1024 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1025 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1026 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1027 Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
1028 root->appendNewControlValue(proc, Return, Origin(), added);
1030 auto code = compileProc(proc);
1032 auto testValues = int64Operands();
1033 for (auto a : testValues) {
1034 for (auto b : testValues) {
1035 for (auto c : testValues) {
1036 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
1042 void testMulAddArgsLeft32()
1045 BasicBlock* root = proc.addBlock();
1047 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1048 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1049 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1050 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1051 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1052 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1053 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1054 Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
1055 root->appendNewControlValue(proc, Return, Origin(), added);
1057 auto code = compileProc(proc);
1059 auto testValues = int32Operands();
1060 for (auto a : testValues) {
1061 for (auto b : testValues) {
1062 for (auto c : testValues) {
1063 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
1069 void testMulAddArgsRight32()
1072 BasicBlock* root = proc.addBlock();
1074 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1075 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1076 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1077 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1078 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1079 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1080 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1081 Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
1082 root->appendNewControlValue(proc, Return, Origin(), added);
1084 auto code = compileProc(proc);
1086 auto testValues = int32Operands();
1087 for (auto a : testValues) {
1088 for (auto b : testValues) {
1089 for (auto c : testValues) {
1090 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
1096 void testMulSubArgsLeft()
1099 BasicBlock* root = proc.addBlock();
1101 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1102 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1103 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1104 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1105 Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
1106 root->appendNewControlValue(proc, Return, Origin(), added);
1108 auto code = compileProc(proc);
1110 auto testValues = int64Operands();
1111 for (auto a : testValues) {
1112 for (auto b : testValues) {
1113 for (auto c : testValues) {
1114 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
1120 void testMulSubArgsRight()
1123 BasicBlock* root = proc.addBlock();
1125 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1126 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1127 Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1128 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1129 Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
1130 root->appendNewControlValue(proc, Return, Origin(), added);
1132 auto code = compileProc(proc);
1134 auto testValues = int64Operands();
1135 for (auto a : testValues) {
1136 for (auto b : testValues) {
1137 for (auto c : testValues) {
1138 CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
1144 void testMulSubArgsLeft32()
1147 BasicBlock* root = proc.addBlock();
1149 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1150 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1151 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1152 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1153 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1154 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1155 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1156 Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
1157 root->appendNewControlValue(proc, Return, Origin(), added);
1159 auto code = compileProc(proc);
1161 auto testValues = int32Operands();
1162 for (auto a : testValues) {
1163 for (auto b : testValues) {
1164 for (auto c : testValues) {
1165 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
1171 void testMulSubArgsRight32()
1174 BasicBlock* root = proc.addBlock();
1176 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1177 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1178 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1179 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1180 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
1181 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
1182 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
1183 Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
1184 root->appendNewControlValue(proc, Return, Origin(), added);
1186 auto code = compileProc(proc);
1188 auto testValues = int32Operands();
1189 for (auto a : testValues) {
1190 for (auto b : testValues) {
1191 for (auto c : testValues) {
1192 CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
1198 void testMulNegArgs()
1201 BasicBlock* root = proc.addBlock();
1203 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1204 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1205 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1206 Value* zero = root->appendNew<Const64Value>(proc, Origin(), 0);
1207 Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
1208 root->appendNewControlValue(proc, Return, Origin(), added);
1210 auto code = compileProc(proc);
1212 auto testValues = int64Operands();
1213 for (auto a : testValues) {
1214 for (auto b : testValues) {
1215 CHECK(invoke<int64_t>(*code, a.value, b.value) == -(a.value * b.value));
1220 void testMulNegArgs32()
1223 BasicBlock* root = proc.addBlock();
1225 Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
1226 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1227 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
1228 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1229 Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
1230 Value* zero = root->appendNew<Const32Value>(proc, Origin(), 0);
1231 Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
1232 root->appendNewControlValue(proc, Return, Origin(), added);
1234 auto code = compileProc(proc);
1236 auto testValues = int32Operands();
1237 for (auto a : testValues) {
1238 for (auto b : testValues) {
1239 CHECK(invoke<int32_t>(*code, a.value, b.value) == -(a.value * b.value));
1244 void testMulArgDouble(double a)
1247 BasicBlock* root = proc.addBlock();
1248 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1249 root->appendNewControlValue(
1250 proc, Return, Origin(),
1251 root->appendNew<Value>(proc, Mul, Origin(), value, value));
1253 CHECK(isIdentical(compileAndRun<double>(proc, a), a * a));
1256 void testMulArgsDouble(double a, double b)
1259 BasicBlock* root = proc.addBlock();
1260 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1261 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1262 root->appendNewControlValue(
1263 proc, Return, Origin(),
1264 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1266 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a * b));
1269 void testMulArgImmDouble(double a, double b)
1272 BasicBlock* root = proc.addBlock();
1273 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1274 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1275 root->appendNewControlValue(
1276 proc, Return, Origin(),
1277 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1279 CHECK(isIdentical(compileAndRun<double>(proc, a), a * b));
1282 void testMulImmArgDouble(double a, double b)
1285 BasicBlock* root = proc.addBlock();
1286 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1287 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1288 root->appendNewControlValue(
1289 proc, Return, Origin(),
1290 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1292 CHECK(isIdentical(compileAndRun<double>(proc, b), a * b));
1295 void testMulImmsDouble(double a, double b)
1298 BasicBlock* root = proc.addBlock();
1299 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1300 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1301 root->appendNewControlValue(
1302 proc, Return, Origin(),
1303 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
1305 CHECK(isIdentical(compileAndRun<double>(proc), a * b));
1308 void testMulArgFloat(float a)
1311 BasicBlock* root = proc.addBlock();
1312 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1313 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1314 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1315 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, floatValue);
1316 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1317 root->appendNewControlValue(proc, Return, Origin(), result32);
1320 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
1323 void testMulArgsFloat(float a, float b)
1326 BasicBlock* root = proc.addBlock();
1327 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1328 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1329 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1330 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1331 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1332 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1333 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue1, floatValue2);
1334 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1335 root->appendNewControlValue(proc, Return, Origin(), result32);
1337 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1340 void testMulArgImmFloat(float a, float b)
1343 BasicBlock* root = proc.addBlock();
1344 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1345 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1346 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1347 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1348 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, constValue);
1349 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1350 root->appendNewControlValue(proc, Return, Origin(), result32);
1352 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * b)));
1355 void testMulImmArgFloat(float a, float b)
1358 BasicBlock* root = proc.addBlock();
1359 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1360 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1361 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1362 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1363 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue, floatValue);
1364 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1365 root->appendNewControlValue(proc, Return, Origin(), result32);
1367 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1370 void testMulImmsFloat(float a, float b)
1373 BasicBlock* root = proc.addBlock();
1374 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1375 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1376 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue1, constValue2);
1377 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1378 root->appendNewControlValue(proc, Return, Origin(), result32);
1380 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a * b)));
1383 void testMulArgFloatWithUselessDoubleConversion(float a)
1386 BasicBlock* root = proc.addBlock();
1387 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1388 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1389 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1390 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1391 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble, asDouble);
1392 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1393 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1394 root->appendNewControlValue(proc, Return, Origin(), result32);
1396 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
1399 void testMulArgsFloatWithUselessDoubleConversion(float a, float b)
1402 BasicBlock* root = proc.addBlock();
1403 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1404 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1405 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1406 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1407 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1408 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1409 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1410 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1411 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
1412 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1413 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1414 root->appendNewControlValue(proc, Return, Origin(), result32);
1416 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
1419 void testMulArgsFloatWithEffectfulDoubleConversion(float a, float b)
1422 BasicBlock* root = proc.addBlock();
1423 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1424 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1425 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1426 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1427 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1428 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1429 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1430 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1431 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
1432 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1433 Value* doubleMulress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1434 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleMulress);
1435 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1436 root->appendNewControlValue(proc, Return, Origin(), result32);
1439 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a * b)));
1440 CHECK(isIdentical(effect, static_cast<double>(a) * static_cast<double>(b)));
1443 void testDivArgDouble(double a)
1446 BasicBlock* root = proc.addBlock();
1447 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1448 root->appendNewControlValue(
1449 proc, Return, Origin(),
1450 root->appendNew<Value>(proc, Div, Origin(), value, value));
1452 CHECK(isIdentical(compileAndRun<double>(proc, a), a / a));
1455 void testDivArgsDouble(double a, double b)
1458 BasicBlock* root = proc.addBlock();
1459 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1460 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1461 root->appendNewControlValue(
1462 proc, Return, Origin(),
1463 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1465 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a / b));
1468 void testDivArgImmDouble(double a, double b)
1471 BasicBlock* root = proc.addBlock();
1472 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1473 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1474 root->appendNewControlValue(
1475 proc, Return, Origin(),
1476 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1478 CHECK(isIdentical(compileAndRun<double>(proc, a), a / b));
1481 void testDivImmArgDouble(double a, double b)
1484 BasicBlock* root = proc.addBlock();
1485 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1486 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1487 root->appendNewControlValue(
1488 proc, Return, Origin(),
1489 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1491 CHECK(isIdentical(compileAndRun<double>(proc, b), a / b));
1494 void testDivImmsDouble(double a, double b)
1497 BasicBlock* root = proc.addBlock();
1498 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1499 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1500 root->appendNewControlValue(
1501 proc, Return, Origin(),
1502 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1504 CHECK(isIdentical(compileAndRun<double>(proc), a / b));
1507 void testDivArgFloat(float a)
1510 BasicBlock* root = proc.addBlock();
1511 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1512 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1513 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1514 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, floatValue);
1515 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1516 root->appendNewControlValue(proc, Return, Origin(), result32);
1519 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1522 void testDivArgsFloat(float a, float b)
1525 BasicBlock* root = proc.addBlock();
1526 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1527 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1528 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1529 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1530 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1531 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1532 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue1, floatValue2);
1533 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1534 root->appendNewControlValue(proc, Return, Origin(), result32);
1536 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1539 void testDivArgImmFloat(float a, float b)
1542 BasicBlock* root = proc.addBlock();
1543 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1544 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1545 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1546 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1547 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, constValue);
1548 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1549 root->appendNewControlValue(proc, Return, Origin(), result32);
1551 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / b)));
1554 void testDivImmArgFloat(float a, float b)
1557 BasicBlock* root = proc.addBlock();
1558 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1559 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1560 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1561 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1562 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue, floatValue);
1563 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1564 root->appendNewControlValue(proc, Return, Origin(), result32);
1566 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1569 void testDivImmsFloat(float a, float b)
1572 BasicBlock* root = proc.addBlock();
1573 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1574 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1575 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue1, constValue2);
1576 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1577 root->appendNewControlValue(proc, Return, Origin(), result32);
1579 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a / b)));
1582 void testModArgDouble(double a)
1585 BasicBlock* root = proc.addBlock();
1586 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1587 root->appendNewControlValue(
1588 proc, Return, Origin(),
1589 root->appendNew<Value>(proc, Mod, Origin(), value, value));
1591 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, a)));
1594 void testModArgsDouble(double a, double b)
1597 BasicBlock* root = proc.addBlock();
1598 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1599 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1600 root->appendNewControlValue(
1601 proc, Return, Origin(),
1602 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1604 CHECK(isIdentical(compileAndRun<double>(proc, a, b), fmod(a, b)));
1607 void testModArgImmDouble(double a, double b)
1610 BasicBlock* root = proc.addBlock();
1611 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1612 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1613 root->appendNewControlValue(
1614 proc, Return, Origin(),
1615 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1617 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, b)));
1620 void testModImmArgDouble(double a, double b)
1623 BasicBlock* root = proc.addBlock();
1624 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1625 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1626 root->appendNewControlValue(
1627 proc, Return, Origin(),
1628 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1630 CHECK(isIdentical(compileAndRun<double>(proc, b), fmod(a, b)));
1633 void testModImmsDouble(double a, double b)
1636 BasicBlock* root = proc.addBlock();
1637 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1638 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1639 root->appendNewControlValue(
1640 proc, Return, Origin(),
1641 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1643 CHECK(isIdentical(compileAndRun<double>(proc), fmod(a, b)));
1646 void testModArgFloat(float a)
1649 BasicBlock* root = proc.addBlock();
1650 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1651 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1652 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1653 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, floatValue);
1654 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1655 root->appendNewControlValue(proc, Return, Origin(), result32);
1658 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, a)))));
1661 void testModArgsFloat(float a, float b)
1664 BasicBlock* root = proc.addBlock();
1665 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1666 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1667 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1668 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1669 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1670 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1671 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue1, floatValue2);
1672 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1673 root->appendNewControlValue(proc, Return, Origin(), result32);
1675 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)))));
1678 void testModArgImmFloat(float a, float b)
1681 BasicBlock* root = proc.addBlock();
1682 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1683 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1684 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1685 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1686 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, constValue);
1687 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1688 root->appendNewControlValue(proc, Return, Origin(), result32);
1690 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1693 void testModImmArgFloat(float a, float b)
1696 BasicBlock* root = proc.addBlock();
1697 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1698 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1699 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1700 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1701 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue, floatValue);
1702 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1703 root->appendNewControlValue(proc, Return, Origin(), result32);
1705 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1708 void testModImmsFloat(float a, float b)
1711 BasicBlock* root = proc.addBlock();
1712 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1713 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1714 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue1, constValue2);
1715 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1716 root->appendNewControlValue(proc, Return, Origin(), result32);
1718 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1721 void testDivArgFloatWithUselessDoubleConversion(float a)
1724 BasicBlock* root = proc.addBlock();
1725 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1726 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1727 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1728 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1729 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble, asDouble);
1730 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1731 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1732 root->appendNewControlValue(proc, Return, Origin(), result32);
1734 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1737 void testDivArgsFloatWithUselessDoubleConversion(float a, float b)
1740 BasicBlock* root = proc.addBlock();
1741 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1742 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1743 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1744 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1745 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1746 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1747 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1748 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1749 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1750 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1751 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1752 root->appendNewControlValue(proc, Return, Origin(), result32);
1754 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1757 void testDivArgsFloatWithEffectfulDoubleConversion(float a, float b)
1760 BasicBlock* root = proc.addBlock();
1761 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1762 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1763 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1764 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1765 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1766 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1767 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1768 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1769 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1770 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1771 Value* doubleDivress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1772 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleDivress);
1773 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1774 root->appendNewControlValue(proc, Return, Origin(), result32);
1777 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a / b)));
1778 CHECK(isIdentical(effect, static_cast<double>(a) / static_cast<double>(b)));
1781 void testUDivArgsInt32(uint32_t a, uint32_t b)
1783 // UDiv with denominator == 0 is invalid.
1788 BasicBlock* root = proc.addBlock();
1789 Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
1790 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1791 Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
1792 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1793 Value* result = root->appendNew<Value>(proc, UDiv, Origin(), argument1, argument2);
1794 root->appendNew<Value>(proc, Return, Origin(), result);
1796 CHECK_EQ(compileAndRun<uint32_t>(proc, a, b), a / b);
1799 void testUDivArgsInt64(uint64_t a, uint64_t b)
1801 // UDiv with denominator == 0 is invalid.
1806 BasicBlock* root = proc.addBlock();
1807 Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1808 Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1809 Value* result = root->appendNew<Value>(proc, UDiv, Origin(), argument1, argument2);
1810 root->appendNew<Value>(proc, Return, Origin(), result);
1812 CHECK_EQ(compileAndRun<uint64_t>(proc, a, b), a / b);
1815 void testUModArgsInt32(uint32_t a, uint32_t b)
1817 // UMod with denominator == 0 is invalid.
1822 BasicBlock* root = proc.addBlock();
1823 Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
1824 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1825 Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
1826 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1827 Value* result = root->appendNew<Value>(proc, UMod, Origin(), argument1, argument2);
1828 root->appendNew<Value>(proc, Return, Origin(), result);
1830 CHECK_EQ(compileAndRun<uint32_t>(proc, a, b), a % b);
1833 void testUModArgsInt64(uint64_t a, uint64_t b)
1835 // UMod with denominator == 0 is invalid.
1840 BasicBlock* root = proc.addBlock();
1841 Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1842 Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1843 Value* result = root->appendNew<Value>(proc, UMod, Origin(), argument1, argument2);
1844 root->appendNew<Value>(proc, Return, Origin(), result);
1846 CHECK_EQ(compileAndRun<uint64_t>(proc, a, b), a % b);
1849 void testSubArg(int a)
1852 BasicBlock* root = proc.addBlock();
1853 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1854 root->appendNewControlValue(
1855 proc, Return, Origin(),
1856 root->appendNew<Value>(proc, Sub, Origin(), value, value));
1858 CHECK(!compileAndRun<int>(proc, a));
1861 void testSubArgs(int a, int b)
1864 BasicBlock* root = proc.addBlock();
1865 root->appendNewControlValue(
1866 proc, Return, Origin(),
1867 root->appendNew<Value>(
1868 proc, Sub, Origin(),
1869 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1870 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
1872 CHECK(compileAndRun<int>(proc, a, b) == a - b);
1875 void testSubArgImm(int64_t a, int64_t b)
1878 BasicBlock* root = proc.addBlock();
1879 root->appendNewControlValue(
1880 proc, Return, Origin(),
1881 root->appendNew<Value>(
1882 proc, Sub, Origin(),
1883 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1884 root->appendNew<Const64Value>(proc, Origin(), b)));
1886 CHECK(compileAndRun<int64_t>(proc, a) == a - b);
1889 void testSubNeg(int a, int b)
1892 BasicBlock* root = proc.addBlock();
1893 root->appendNewControlValue(
1894 proc, Return, Origin(),
1895 root->appendNew<Value>(
1896 proc, Sub, Origin(),
1897 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1898 root->appendNew<Value>(proc, Neg, Origin(),
1899 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1901 CHECK(compileAndRun<int>(proc, a, b) == a - (- b));
1904 void testNegSub(int a, int b)
1907 BasicBlock* root = proc.addBlock();
1908 root->appendNewControlValue(
1909 proc, Return, Origin(),
1910 root->appendNew<Value>(
1911 proc, Neg, Origin(),
1912 root->appendNew<Value>(proc, Sub, Origin(),
1913 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1914 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1916 CHECK(compileAndRun<int>(proc, a, b) == -(a - b));
1919 void testNegValueSubOne(int a)
1922 BasicBlock* root = proc.addBlock();
1923 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1924 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
1925 root->appendNew<Const64Value>(proc, Origin(), 0),
1927 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
1929 root->appendNew<Const64Value>(proc, Origin(), 1));
1930 root->appendNewControlValue(proc, Return, Origin(), negArgumentMinusOne);
1931 CHECK(compileAndRun<int>(proc, a) == -a - 1);
1934 void testSubSub(int a, int b, int c)
1937 BasicBlock* root = proc.addBlock();
1938 root->appendNewControlValue(
1939 proc, Return, Origin(),
1940 root->appendNew<Value>(
1941 proc, Sub, Origin(),
1942 root->appendNew<Value>(proc, Sub, Origin(),
1943 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1944 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)),
1945 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
1947 CHECK(compileAndRun<int>(proc, a, b, c) == (a-b)-c);
1950 void testSubSub2(int a, int b, int c)
1953 BasicBlock* root = proc.addBlock();
1954 root->appendNewControlValue(
1955 proc, Return, Origin(),
1956 root->appendNew<Value>(
1957 proc, Sub, Origin(),
1958 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1959 root->appendNew<Value>(proc, Sub, Origin(),
1960 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
1961 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2))));
1963 CHECK(compileAndRun<int>(proc, a, b, c) == a-(b-c));
1966 void testSubAdd(int a, int b, int c)
1969 BasicBlock* root = proc.addBlock();
1970 root->appendNewControlValue(
1971 proc, Return, Origin(),
1972 root->appendNew<Value>(
1973 proc, Sub, Origin(),
1974 root->appendNew<Value>(proc, Add, Origin(),
1975 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1976 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)),
1977 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
1979 CHECK(compileAndRun<int>(proc, a, b, c) == (a+b)-c);
1982 void testSubFirstNeg(int a, int b)
1985 BasicBlock* root = proc.addBlock();
1986 root->appendNewControlValue(
1987 proc, Return, Origin(),
1988 root->appendNew<Value>(
1989 proc, Sub, Origin(),
1990 root->appendNew<Value>(proc, Neg, Origin(),
1991 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1992 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
1994 CHECK(compileAndRun<int>(proc, a, b) == (-a)-b);
1997 void testSubImmArg(int a, int b)
2000 BasicBlock* root = proc.addBlock();
2001 root->appendNewControlValue(
2002 proc, Return, Origin(),
2003 root->appendNew<Value>(
2004 proc, Sub, Origin(),
2005 root->appendNew<Const64Value>(proc, Origin(), a),
2006 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2008 CHECK(compileAndRun<int>(proc, b) == a - b);
2011 void testSubArgMem(int64_t a, int64_t b)
2014 BasicBlock* root = proc.addBlock();
2015 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2016 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2017 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2018 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2020 root->appendNewControlValue(proc, Return, Origin(), result);
2022 CHECK(compileAndRun<int64_t>(proc, a, &b) == a - b);
2025 void testSubMemArg(int64_t a, int64_t b)
2028 BasicBlock* root = proc.addBlock();
2029 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2030 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2031 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2033 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2034 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2035 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2037 int64_t inputOutput = a;
2038 CHECK(!compileAndRun<int64_t>(proc, &inputOutput, b));
2039 CHECK(inputOutput == a - b);
2042 void testSubImmMem(int64_t a, int64_t b)
2045 BasicBlock* root = proc.addBlock();
2046 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2047 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2048 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2049 root->appendNew<Const64Value>(proc, Origin(), a),
2051 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2052 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2054 int64_t inputOutput = b;
2055 CHECK(!compileAndRun<int>(proc, &inputOutput));
2056 CHECK(inputOutput == a - b);
2059 void testSubMemImm(int64_t a, int64_t b)
2062 BasicBlock* root = proc.addBlock();
2063 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2064 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2065 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2067 root->appendNew<Const64Value>(proc, Origin(), b));
2068 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2069 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2071 int64_t inputOutput = a;
2072 CHECK(!compileAndRun<int>(proc, &inputOutput));
2073 CHECK(inputOutput == a - b);
2077 void testSubArgs32(int a, int b)
2080 BasicBlock* root = proc.addBlock();
2081 root->appendNewControlValue(
2082 proc, Return, Origin(),
2083 root->appendNew<Value>(
2084 proc, Sub, Origin(),
2085 root->appendNew<Value>(
2086 proc, Trunc, Origin(),
2087 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2088 root->appendNew<Value>(
2089 proc, Trunc, Origin(),
2090 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2092 CHECK(compileAndRun<int>(proc, a, b) == a - b);
2095 void testSubArgImm32(int a, int b)
2098 BasicBlock* root = proc.addBlock();
2099 root->appendNewControlValue(
2100 proc, Return, Origin(),
2101 root->appendNew<Value>(
2102 proc, Sub, Origin(),
2103 root->appendNew<Value>(
2104 proc, Trunc, Origin(),
2105 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2106 root->appendNew<Const32Value>(proc, Origin(), b)));
2108 CHECK(compileAndRun<int>(proc, a) == a - b);
2111 void testSubImmArg32(int a, int b)
2114 BasicBlock* root = proc.addBlock();
2115 root->appendNewControlValue(
2116 proc, Return, Origin(),
2117 root->appendNew<Value>(
2118 proc, Sub, Origin(),
2119 root->appendNew<Const32Value>(proc, Origin(), a),
2120 root->appendNew<Value>(
2121 proc, Trunc, Origin(),
2122 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2124 CHECK(compileAndRun<int>(proc, b) == a - b);
2127 void testSubMemArg32(int32_t a, int32_t b)
2130 BasicBlock* root = proc.addBlock();
2131 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2132 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2133 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2134 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2135 Value* result = root->appendNew<Value>(proc, Sub, Origin(), load, argument);
2136 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2137 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2139 int32_t inputOutput = a;
2140 CHECK(!compileAndRun<int32_t>(proc, &inputOutput, b));
2141 CHECK(inputOutput == a - b);
2144 void testSubArgMem32(int32_t a, int32_t b)
2147 BasicBlock* root = proc.addBlock();
2148 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2149 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2150 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2151 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2152 Value* result = root->appendNew<Value>(proc, Sub, Origin(), argument, load);
2153 root->appendNewControlValue(proc, Return, Origin(), result);
2155 CHECK(compileAndRun<int32_t>(proc, a, &b) == a - b);
2158 void testSubImmMem32(int32_t a, int32_t b)
2161 BasicBlock* root = proc.addBlock();
2162 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2163 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2164 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2165 root->appendNew<Const32Value>(proc, Origin(), a),
2167 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2168 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2170 int32_t inputOutput = b;
2171 CHECK(!compileAndRun<int>(proc, &inputOutput));
2172 CHECK(inputOutput == a - b);
2175 void testSubMemImm32(int32_t a, int32_t b)
2178 BasicBlock* root = proc.addBlock();
2179 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2180 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2181 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
2183 root->appendNew<Const32Value>(proc, Origin(), b));
2184 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
2185 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2187 int32_t inputOutput = a;
2188 CHECK(!compileAndRun<int>(proc, &inputOutput));
2189 CHECK(inputOutput == a - b);
2192 void testNegValueSubOne32(int a)
2195 BasicBlock* root = proc.addBlock();
2196 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2197 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2198 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
2199 root->appendNew<Const32Value>(proc, Origin(), 0),
2201 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
2203 root->appendNew<Const32Value>(proc, Origin(), 1));
2204 root->appendNewControlValue(proc, Return, Origin(), negArgumentMinusOne);
2205 CHECK(compileAndRun<int>(proc, a) == -a - 1);
2208 void testNegMulArgImm(int64_t a, int64_t b)
2211 BasicBlock* root = proc.addBlock();
2212 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2213 Value* constant = root->appendNew<Const64Value>(proc, Origin(), b);
2214 Value* mul = root->appendNew<Value>(proc, Mul, Origin(), argument, constant);
2215 Value* result = root->appendNew<Value>(proc, Neg, Origin(), mul);
2216 root->appendNew<Value>(proc, Return, Origin(), result);
2218 CHECK(compileAndRun<int64_t>(proc, a) == -(a * b));
2221 void testSubMulMulArgs(int64_t a, int64_t b, int64_t c)
2223 // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
2224 // ((a * b) - (a * c))
2225 // ((a * b) - (c * a))
2226 // ((b * a) - (a * c))
2227 // ((b * a) - (c * a))
2228 for (int i = 0; i < 4; ++i) {
2230 BasicBlock* root = proc.addBlock();
2231 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2232 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2233 Value* argC = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2234 Value* mulAB = i & 2 ? root->appendNew<Value>(proc, Mul, Origin(), argA, argB)
2235 : root->appendNew<Value>(proc, Mul, Origin(), argB, argA);
2236 Value* mulAC = i & 1 ? root->appendNew<Value>(proc, Mul, Origin(), argA, argC)
2237 : root->appendNew<Value>(proc, Mul, Origin(), argC, argA);
2238 root->appendNew<Value>(proc, Return, Origin(),
2239 root->appendNew<Value>(proc, Sub, Origin(),
2243 CHECK_EQ(compileAndRun<int64_t>(proc, a, b, c), ((a * b) - (a * c)));
2247 void testSubArgDouble(double a)
2250 BasicBlock* root = proc.addBlock();
2251 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2252 root->appendNewControlValue(
2253 proc, Return, Origin(),
2254 root->appendNew<Value>(proc, Sub, Origin(), value, value));
2256 CHECK(isIdentical(compileAndRun<double>(proc, a), a - a));
2259 void testSubArgsDouble(double a, double b)
2262 BasicBlock* root = proc.addBlock();
2263 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2264 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
2265 root->appendNewControlValue(
2266 proc, Return, Origin(),
2267 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2269 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a - b));
2272 void testSubArgImmDouble(double a, double b)
2275 BasicBlock* root = proc.addBlock();
2276 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2277 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2278 root->appendNewControlValue(
2279 proc, Return, Origin(),
2280 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2282 CHECK(isIdentical(compileAndRun<double>(proc, a), a - b));
2285 void testSubImmArgDouble(double a, double b)
2288 BasicBlock* root = proc.addBlock();
2289 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2290 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2291 root->appendNewControlValue(
2292 proc, Return, Origin(),
2293 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2295 CHECK(isIdentical(compileAndRun<double>(proc, b), a - b));
2298 void testSubImmsDouble(double a, double b)
2301 BasicBlock* root = proc.addBlock();
2302 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2303 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2304 root->appendNewControlValue(
2305 proc, Return, Origin(),
2306 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
2308 CHECK(isIdentical(compileAndRun<double>(proc), a - b));
2311 void testSubArgFloat(float a)
2314 BasicBlock* root = proc.addBlock();
2315 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2316 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2317 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2318 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, floatValue);
2319 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2320 root->appendNewControlValue(proc, Return, Origin(), result32);
2323 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
2326 void testSubArgsFloat(float a, float b)
2329 BasicBlock* root = proc.addBlock();
2330 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2331 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2332 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2333 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2334 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2335 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2336 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue1, floatValue2);
2337 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2338 root->appendNewControlValue(proc, Return, Origin(), result32);
2340 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2343 void testSubArgImmFloat(float a, float b)
2346 BasicBlock* root = proc.addBlock();
2347 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2348 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2349 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2350 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2351 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, constValue);
2352 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2353 root->appendNewControlValue(proc, Return, Origin(), result32);
2355 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - b)));
2358 void testSubImmArgFloat(float a, float b)
2361 BasicBlock* root = proc.addBlock();
2362 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2363 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2364 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2365 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2366 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue, floatValue);
2367 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2368 root->appendNewControlValue(proc, Return, Origin(), result32);
2370 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2373 void testSubImmsFloat(float a, float b)
2376 BasicBlock* root = proc.addBlock();
2377 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2378 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2379 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue1, constValue2);
2380 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
2381 root->appendNewControlValue(proc, Return, Origin(), result32);
2383 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a - b)));
2386 void testSubArgFloatWithUselessDoubleConversion(float a)
2389 BasicBlock* root = proc.addBlock();
2390 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
2391 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2392 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
2393 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2394 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble, asDouble);
2395 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2396 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2397 root->appendNewControlValue(proc, Return, Origin(), result32);
2399 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
2402 void testSubArgsFloatWithUselessDoubleConversion(float a, float b)
2405 BasicBlock* root = proc.addBlock();
2406 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2407 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2408 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2409 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2410 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2411 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2412 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
2413 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
2414 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
2415 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2416 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2417 root->appendNewControlValue(proc, Return, Origin(), result32);
2419 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
2422 void testSubArgsFloatWithEffectfulDoubleConversion(float a, float b)
2425 BasicBlock* root = proc.addBlock();
2426 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2427 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2428 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
2429 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2430 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
2431 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
2432 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
2433 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
2434 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
2435 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2436 Value* doubleSubress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2437 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleSubress);
2438 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
2439 root->appendNewControlValue(proc, Return, Origin(), result32);
2442 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a - b)));
2443 CHECK(isIdentical(effect, static_cast<double>(a) - static_cast<double>(b)));
2446 void testTernarySubInstructionSelection(B3::Opcode valueModifier, Type valueType, Air::Opcode expectedOpcode)
2449 BasicBlock* root = proc.addBlock();
2451 Value* left = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2452 Value* right = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2454 if (valueModifier == Trunc) {
2455 left = root->appendNew<Value>(proc, valueModifier, valueType, Origin(), left);
2456 right = root->appendNew<Value>(proc, valueModifier, valueType, Origin(), right);
2459 root->appendNewControlValue(
2460 proc, Return, Origin(),
2461 root->appendNew<Value>(proc, Sub, Origin(), left, right));
2463 lowerToAirForTesting(proc);
2465 auto block = proc.code()[0];
2466 unsigned numberOfSubInstructions = 0;
2467 for (auto instruction : *block) {
2468 if (instruction.kind.opcode == expectedOpcode) {
2469 CHECK_EQ(instruction.args.size(), 3ul);
2470 CHECK_EQ(instruction.args[0].kind(), Air::Arg::Tmp);
2471 CHECK_EQ(instruction.args[1].kind(), Air::Arg::Tmp);
2472 CHECK_EQ(instruction.args[2].kind(), Air::Arg::Tmp);
2473 numberOfSubInstructions++;
2476 CHECK_EQ(numberOfSubInstructions, 1ul);
2479 void testNegDouble(double a)
2482 BasicBlock* root = proc.addBlock();
2483 root->appendNewControlValue(
2484 proc, Return, Origin(),
2485 root->appendNew<Value>(
2486 proc, Neg, Origin(),
2487 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
2489 CHECK(isIdentical(compileAndRun<double>(proc, a), -a));
2492 void testNegFloat(float a)
2495 BasicBlock* root = proc.addBlock();
2496 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2497 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2498 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2499 root->appendNewControlValue(
2500 proc, Return, Origin(),
2501 root->appendNew<Value>(proc, Neg, Origin(), floatValue));
2503 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), -a));
2506 void testNegFloatWithUselessDoubleConversion(float a)
2509 BasicBlock* root = proc.addBlock();
2510 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
2511 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2512 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
2513 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2514 Value* result = root->appendNew<Value>(proc, Neg, Origin(), asDouble);
2515 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
2516 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2518 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), -a));
2521 static void testBitAndArgs(int64_t a, int64_t b)
2524 BasicBlock* root = proc.addBlock();
2525 root->appendNewControlValue(
2526 proc, Return, Origin(),
2527 root->appendNew<Value>(
2528 proc, BitAnd, Origin(),
2529 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2530 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2532 CHECK(compileAndRun<int64_t>(proc, a, b) == (a & b));
2535 static void testBitAndSameArg(int64_t a)
2538 BasicBlock* root = proc.addBlock();
2539 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2540 root->appendNewControlValue(
2541 proc, Return, Origin(),
2542 root->appendNew<Value>(
2543 proc, BitAnd, Origin(),
2547 CHECK(compileAndRun<int64_t>(proc, a) == a);
2550 static void testBitAndNotNot(int64_t a, int64_t b)
2553 BasicBlock* root = proc.addBlock();
2554 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2555 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2556 Value* notA = root->appendNew<Value>(proc, BitXor, Origin(), argA, root->appendNew<Const64Value>(proc, Origin(), -1));
2557 Value* notB = root->appendNew<Value>(proc, BitXor, Origin(), argB, root->appendNew<Const64Value>(proc, Origin(), -1));
2558 root->appendNewControlValue(
2559 proc, Return, Origin(),
2560 root->appendNew<Value>(
2561 proc, BitAnd, Origin(),
2565 CHECK_EQ(compileAndRun<int64_t>(proc, a, b), (~a & ~b));
2568 static void testBitAndNotImm(int64_t a, int64_t b)
2571 BasicBlock* root = proc.addBlock();
2572 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2573 Value* notA = root->appendNew<Value>(proc, BitXor, Origin(), argA, root->appendNew<Const64Value>(proc, Origin(), -1));
2574 Value* cstB = root->appendNew<Const64Value>(proc, Origin(), b);
2575 root->appendNewControlValue(
2576 proc, Return, Origin(),
2577 root->appendNew<Value>(
2578 proc, BitAnd, Origin(),
2582 CHECK_EQ(compileAndRun<int64_t>(proc, a, b), (~a & b));
2585 static void testBitAndImms(int64_t a, int64_t b)
2588 BasicBlock* root = proc.addBlock();
2589 root->appendNewControlValue(
2590 proc, Return, Origin(),
2591 root->appendNew<Value>(
2592 proc, BitAnd, Origin(),
2593 root->appendNew<Const64Value>(proc, Origin(), a),
2594 root->appendNew<Const64Value>(proc, Origin(), b)));
2596 CHECK(compileAndRun<int64_t>(proc) == (a & b));
2599 static void testBitAndArgImm(int64_t a, int64_t b)
2602 BasicBlock* root = proc.addBlock();
2603 root->appendNewControlValue(
2604 proc, Return, Origin(),
2605 root->appendNew<Value>(
2606 proc, BitAnd, Origin(),
2607 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2608 root->appendNew<Const64Value>(proc, Origin(), b)));
2610 CHECK(compileAndRun<int64_t>(proc, a) == (a & b));
2613 static void testBitAndImmArg(int64_t a, int64_t b)
2616 BasicBlock* root = proc.addBlock();
2617 root->appendNewControlValue(
2618 proc, Return, Origin(),
2619 root->appendNew<Value>(
2620 proc, BitAnd, Origin(),
2621 root->appendNew<Const64Value>(proc, Origin(), a),
2622 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2624 CHECK(compileAndRun<int64_t>(proc, b) == (a & b));
2627 static void testBitAndBitAndArgImmImm(int64_t a, int64_t b, int64_t c)
2630 BasicBlock* root = proc.addBlock();
2631 Value* innerBitAnd = root->appendNew<Value>(
2632 proc, BitAnd, Origin(),
2633 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2634 root->appendNew<Const64Value>(proc, Origin(), b));
2635 root->appendNewControlValue(
2636 proc, Return, Origin(),
2637 root->appendNew<Value>(
2638 proc, BitAnd, Origin(),
2640 root->appendNew<Const64Value>(proc, Origin(), c)));
2642 CHECK(compileAndRun<int64_t>(proc, a) == ((a & b) & c));
2645 static void testBitAndImmBitAndArgImm(int64_t a, int64_t b, int64_t c)
2648 BasicBlock* root = proc.addBlock();
2649 Value* innerBitAnd = root->appendNew<Value>(
2650 proc, BitAnd, Origin(),
2651 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2652 root->appendNew<Const64Value>(proc, Origin(), c));
2653 root->appendNewControlValue(
2654 proc, Return, Origin(),
2655 root->appendNew<Value>(
2656 proc, BitAnd, Origin(),
2657 root->appendNew<Const64Value>(proc, Origin(), a),
2660 CHECK(compileAndRun<int64_t>(proc, b) == (a & (b & c)));
2663 static void testBitAndArgs32(int a, int b)
2666 BasicBlock* root = proc.addBlock();
2667 root->appendNewControlValue(
2668 proc, Return, Origin(),
2669 root->appendNew<Value>(
2670 proc, BitAnd, Origin(),
2671 root->appendNew<Value>(
2672 proc, Trunc, Origin(),
2673 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2674 root->appendNew<Value>(
2675 proc, Trunc, Origin(),
2676 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2678 CHECK(compileAndRun<int>(proc, a, b) == (a & b));
2681 static void testBitAndSameArg32(int a)
2684 BasicBlock* root = proc.addBlock();
2685 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2686 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2687 root->appendNewControlValue(
2688 proc, Return, Origin(),
2689 root->appendNew<Value>(
2690 proc, BitAnd, Origin(),
2694 CHECK(compileAndRun<int>(proc, a) == a);
2697 static void testBitAndImms32(int a, int b)
2700 BasicBlock* root = proc.addBlock();
2701 root->appendNewControlValue(
2702 proc, Return, Origin(),
2703 root->appendNew<Value>(
2704 proc, BitAnd, Origin(),
2705 root->appendNew<Const32Value>(proc, Origin(), a),
2706 root->appendNew<Const32Value>(proc, Origin(), b)));
2708 CHECK(compileAndRun<int>(proc) == (a & b));
2711 static void testBitAndArgImm32(int a, int b)
2714 BasicBlock* root = proc.addBlock();
2715 root->appendNewControlValue(
2716 proc, Return, Origin(),
2717 root->appendNew<Value>(
2718 proc, BitAnd, Origin(),
2719 root->appendNew<Value>(
2720 proc, Trunc, Origin(),
2721 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2722 root->appendNew<Const32Value>(proc, Origin(), b)));
2724 CHECK(compileAndRun<int>(proc, a) == (a & b));
2727 static void testBitAndImmArg32(int a, int b)
2730 BasicBlock* root = proc.addBlock();
2731 root->appendNewControlValue(
2732 proc, Return, Origin(),
2733 root->appendNew<Value>(
2734 proc, BitAnd, Origin(),
2735 root->appendNew<Const32Value>(proc, Origin(), a),
2736 root->appendNew<Value>(
2737 proc, Trunc, Origin(),
2738 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2740 CHECK(compileAndRun<int>(proc, b) == (a & b));
2743 static void testBitAndBitAndArgImmImm32(int a, int b, int c)
2746 BasicBlock* root = proc.addBlock();
2747 Value* innerBitAnd = root->appendNew<Value>(
2748 proc, BitAnd, Origin(),
2749 root->appendNew<Value>(
2750 proc, Trunc, Origin(),
2751 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2752 root->appendNew<Const32Value>(proc, Origin(), b));
2753 root->appendNewControlValue(
2754 proc, Return, Origin(),
2755 root->appendNew<Value>(
2756 proc, BitAnd, Origin(),
2758 root->appendNew<Const32Value>(proc, Origin(), c)));
2760 CHECK(compileAndRun<int>(proc, a) == ((a & b) & c));
2763 static void testBitAndImmBitAndArgImm32(int a, int b, int c)
2766 BasicBlock* root = proc.addBlock();
2767 Value* innerBitAnd = root->appendNew<Value>(
2768 proc, BitAnd, Origin(),
2769 root->appendNew<Value>(
2770 proc, Trunc, Origin(),
2771 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2772 root->appendNew<Const32Value>(proc, Origin(), c));
2773 root->appendNewControlValue(
2774 proc, Return, Origin(),
2775 root->appendNew<Value>(
2776 proc, BitAnd, Origin(),
2777 root->appendNew<Const32Value>(proc, Origin(), a),
2780 CHECK(compileAndRun<int>(proc, b) == (a & (b & c)));
2783 static void testBitAndWithMaskReturnsBooleans(int64_t a, int64_t b)
2786 BasicBlock* root = proc.addBlock();
2787 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2788 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2789 Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg0, arg1);
2790 Value* maskedEqual = root->appendNew<Value>(proc, BitAnd, Origin(),
2791 root->appendNew<Const32Value>(proc, Origin(), 0x5),
2793 Value* inverted = root->appendNew<Value>(proc, BitXor, Origin(),
2794 root->appendNew<Const32Value>(proc, Origin(), 0x1),
2796 Value* select = root->appendNew<Value>(proc, Select, Origin(), inverted,
2797 root->appendNew<Const64Value>(proc, Origin(), 42),
2798 root->appendNew<Const64Value>(proc, Origin(), -5));
2800 root->appendNewControlValue(proc, Return, Origin(), select);
2802 int64_t expected = (a == b) ? -5 : 42;
2803 CHECK(compileAndRun<int64_t>(proc, a, b) == expected);
2806 static double bitAndDouble(double a, double b)
2808 return bitwise_cast<double>(bitwise_cast<uint64_t>(a) & bitwise_cast<uint64_t>(b));
2811 static void testBitAndArgDouble(double a)
2814 BasicBlock* root = proc.addBlock();
2815 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2816 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2817 root->appendNewControlValue(proc, Return, Origin(), result);
2819 CHECK(isIdentical(compileAndRun<double>(proc, a), bitAndDouble(a, a)));
2822 static void testBitAndArgsDouble(double a, double b)
2825 BasicBlock* root = proc.addBlock();
2826 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2827 Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
2828 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2829 root->appendNewControlValue(proc, Return, Origin(), result);
2831 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2834 static void testBitAndArgImmDouble(double a, double b)
2837 BasicBlock* root = proc.addBlock();
2838 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2839 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2840 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2841 root->appendNewControlValue(proc, Return, Origin(), result);
2843 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2846 static void testBitAndImmsDouble(double a, double b)
2849 BasicBlock* root = proc.addBlock();
2850 Value* argumentA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2851 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2852 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2853 root->appendNewControlValue(proc, Return, Origin(), result);
2855 CHECK(isIdentical(compileAndRun<double>(proc), bitAndDouble(a, b)));
2858 static float bitAndFloat(float a, float b)
2860 return bitwise_cast<float>(bitwise_cast<uint32_t>(a) & bitwise_cast<uint32_t>(b));
2863 static void testBitAndArgFloat(float a)
2866 BasicBlock* root = proc.addBlock();
2867 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2868 root->appendNew<Value>(proc, Trunc, Origin(),
2869 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2870 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2871 root->appendNewControlValue(proc, Return, Origin(), result);
2873 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), bitAndFloat(a, a)));
2876 static void testBitAndArgsFloat(float a, float b)
2879 BasicBlock* root = proc.addBlock();
2880 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2881 root->appendNew<Value>(proc, Trunc, Origin(),
2882 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2883 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2884 root->appendNew<Value>(proc, Trunc, Origin(),
2885 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2886 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2887 root->appendNewControlValue(proc, Return, Origin(), result);
2889 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2892 static void testBitAndArgImmFloat(float a, float b)
2895 BasicBlock* root = proc.addBlock();
2896 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2897 root->appendNew<Value>(proc, Trunc, Origin(),
2898 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2899 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2900 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2901 root->appendNewControlValue(proc, Return, Origin(), result);
2903 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2906 static void testBitAndImmsFloat(float a, float b)
2909 BasicBlock* root = proc.addBlock();
2910 Value* argumentA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2911 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2912 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2913 root->appendNewControlValue(proc, Return, Origin(), result);
2915 CHECK(isIdentical(compileAndRun<float>(proc), bitAndFloat(a, b)));
2918 static void testBitAndArgsFloatWithUselessDoubleConversion(float a, float b)
2921 BasicBlock* root = proc.addBlock();
2922 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2923 root->appendNew<Value>(proc, Trunc, Origin(),
2924 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2925 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2926 root->appendNew<Value>(proc, Trunc, Origin(),
2927 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2928 Value* argumentAasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentA);
2929 Value* argumentBasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentB);
2930 Value* doubleResult = root->appendNew<Value>(proc, BitAnd, Origin(), argumentAasDouble, argumentBasDouble);
2931 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleResult);
2932 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2936 float expected = static_cast<float>(bitAndDouble(doubleA, doubleB));
2937 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), expected));
2940 static void testBitOrArgs(int64_t a, int64_t b)
2943 BasicBlock* root = proc.addBlock();
2944 root->appendNewControlValue(
2945 proc, Return, Origin(),
2946 root->appendNew<Value>(
2947 proc, BitOr, Origin(),
2948 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2949 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2951 CHECK(compileAndRun<int64_t>(proc, a, b) == (a | b));
2954 static void testBitOrSameArg(int64_t a)
2957 BasicBlock* root = proc.addBlock();
2958 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2959 root->appendNewControlValue(
2960 proc, Return, Origin(),
2961 root->appendNew<Value>(
2962 proc, BitOr, Origin(),
2966 CHECK(compileAndRun<int64_t>(proc, a) == a);
2969 static void testBitOrAndAndArgs(int64_t a, int64_t b, int64_t c)
2971 // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
2972 // ((a & b) | (a & c))
2973 // ((a & b) | (c & a))
2974 // ((b & a) | (a & c))
2975 // ((b & a) | (c & a))
2976 for (int i = 0; i < 4; ++i) {
2978 BasicBlock* root = proc.addBlock();
2979 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2980 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2981 Value* argC = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2982 Value* andAB = i & 2 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
2983 : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
2984 Value* andAC = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argC)
2985 : root->appendNew<Value>(proc, BitAnd, Origin(), argC, argA);
2986 root->appendNewControlValue(
2987 proc, Return, Origin(),
2988 root->appendNew<Value>(
2989 proc, BitOr, Origin(),
2993 CHECK_EQ(compileAndRun<int64_t>(proc, a, b, c), ((a & b) | (a & c)));
2997 static void testBitOrAndSameArgs(int64_t a, int64_t b)
2999 // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
3004 for (int i = 0; i < 4; ++i) {
3006 BasicBlock* root = proc.addBlock();
3007 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3008 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3009 Value* andAB = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
3010 : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
3011 Value* result = i & 2 ? root->appendNew<Value>(proc, BitOr, Origin(), andAB, argA)
3012 : root->appendNew<Value>(proc, BitOr, Origin(), argA, andAB);
3013 root->appendNewControlValue(proc, Return, Origin(), result);
3015 CHECK_EQ(compileAndRun<int64_t>(proc, a, b), ((a & b) | a));
3019 static void testBitOrNotNot(int64_t a, int64_t b)
3022 BasicBlock* root = proc.addBlock();
3023 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3024 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3025 Value* notA = root->appendNew<Value>(proc, BitXor, Origin(), argA, root->appendNew<Const64Value>(proc, Origin(), -1));
3026 Value* notB = root->appendNew<Value>(proc, BitXor, Origin(), argB, root->appendNew<Const64Value>(proc, Origin(), -1));
3027 root->appendNewControlValue(
3028 proc, Return, Origin(),
3029 root->appendNew<Value>(
3030 proc, BitOr, Origin(),
3034 CHECK_EQ(compileAndRun<int64_t>(proc, a, b), (~a | ~b));
3037 static void testBitOrNotImm(int64_t a, int64_t b)
3040 BasicBlock* root = proc.addBlock();
3041 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3042 Value* notA = root->appendNew<Value>(proc, BitXor, Origin(), argA, root->appendNew<Const64Value>(proc, Origin(), -1));
3043 Value* cstB = root->appendNew<Const64Value>(proc, Origin(), b);
3044 root->appendNewControlValue(
3045 proc, Return, Origin(),
3046 root->appendNew<Value>(
3047 proc, BitOr, Origin(),
3051 CHECK_EQ(compileAndRun<int64_t>(proc, a, b), (~a | b));
3054 static void testBitOrImms(int64_t a, int64_t b)
3057 BasicBlock* root = proc.addBlock();
3058 root->appendNewControlValue(
3059 proc, Return, Origin(),
3060 root->appendNew<Value>(
3061 proc, BitOr, Origin(),
3062 root->appendNew<Const64Value>(proc, Origin(), a),
3063 root->appendNew<Const64Value>(proc, Origin(), b)));
3065 CHECK(compileAndRun<int64_t>(proc) == (a | b));
3068 static void testBitOrArgImm(int64_t a, int64_t b)
3071 BasicBlock* root = proc.addBlock();
3072 root->appendNewControlValue(
3073 proc, Return, Origin(),
3074 root->appendNew<Value>(
3075 proc, BitOr, Origin(),
3076 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3077 root->appendNew<Const64Value>(proc, Origin(), b)));
3079 CHECK(compileAndRun<int64_t>(proc, a) == (a | b));
3082 static void testBitOrImmArg(int64_t a, int64_t b)
3085 BasicBlock* root = proc.addBlock();
3086 root->appendNewControlValue(
3087 proc, Return, Origin(),
3088 root->appendNew<Value>(
3089 proc, BitOr, Origin(),
3090 root->appendNew<Const64Value>(proc, Origin(), a),
3091 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
3093 CHECK(compileAndRun<int64_t>(proc, b) == (a | b));
3096 static void testBitOrBitOrArgImmImm(int64_t a, int64_t b, int64_t c)
3099 BasicBlock* root = proc.addBlock();
3100 Value* innerBitOr = root->appendNew<Value>(
3101 proc, BitOr, Origin(),
3102 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3103 root->appendNew<Const64Value>(proc, Origin(), b));
3104 root->appendNewControlValue(
3105 proc, Return, Origin(),
3106 root->appendNew<Value>(
3107 proc, BitOr, Origin(),
3109 root->appendNew<Const64Value>(proc, Origin(), c)));
3111 CHECK(compileAndRun<int64_t>(proc, a) == ((a | b) | c));
3114 static void testBitOrImmBitOrArgImm(int64_t a, int64_t b, int64_t c)
3117 BasicBlock* root = proc.addBlock();
3118 Value* innerBitOr = root->appendNew<Value>(
3119 proc, BitOr, Origin(),
3120 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3121 root->appendNew<Const64Value>(proc, Origin(), c));
3122 root->appendNewControlValue(
3123 proc, Return, Origin(),
3124 root->appendNew<Value>(
3125 proc, BitOr, Origin(),
3126 root->appendNew<Const64Value>(proc, Origin(), a),
3129 CHECK(compileAndRun<int64_t>(proc, b) == (a | (b | c)));
3132 static void testBitOrArgs32(int a, int b)
3135 BasicBlock* root = proc.addBlock();
3136 root->appendNewControlValue(
3137 proc, Return, Origin(),
3138 root->appendNew<Value>(
3139 proc, BitOr, Origin(),
3140 root->appendNew<Value>(
3141 proc, Trunc, Origin(),
3142 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3143 root->appendNew<Value>(
3144 proc, Trunc, Origin(),
3145 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3147 CHECK(compileAndRun<int>(proc, a, b) == (a | b));
3150 static void testBitOrSameArg32(int a)
3153 BasicBlock* root = proc.addBlock();
3154 Value* argument = root->appendNew<Value>(
3155 proc, Trunc, Origin(),
3156 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3157 root->appendNewControlValue(
3158 proc, Return, Origin(),
3159 root->appendNew<Value>(
3160 proc, BitOr, Origin(),
3164 CHECK(compileAndRun<int>(proc, a) == a);
3167 static void testBitOrImms32(int a, int b)
3170 BasicBlock* root = proc.addBlock();
3171 root->appendNewControlValue(
3172 proc, Return, Origin(),
3173 root->appendNew<Value>(
3174 proc, BitOr, Origin(),
3175 root->appendNew<Const32Value>(proc, Origin(), a),
3176 root->appendNew<Const32Value>(proc, Origin(), b)));
3178 CHECK(compileAndRun<int>(proc) == (a | b));
3181 static void testBitOrArgImm32(int a, int b)
3184 BasicBlock* root = proc.addBlock();
3185 root->appendNewControlValue(
3186 proc, Return, Origin(),
3187 root->appendNew<Value>(
3188 proc, BitOr, Origin(),
3189 root->appendNew<Value>(
3190 proc, Trunc, Origin(),
3191 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3192 root->appendNew<Const32Value>(proc, Origin(), b)));
3194 CHECK(compileAndRun<int>(proc, a) == (a | b));
3197 static void testBitOrImmArg32(int a, int b)
3200 BasicBlock* root = proc.addBlock();
3201 root->appendNewControlValue(
3202 proc, Return, Origin(),
3203 root->appendNew<Value>(
3204 proc, BitOr, Origin(),
3205 root->appendNew<Const32Value>(proc, Origin(), a),
3206 root->appendNew<Value>(
3207 proc, Trunc, Origin(),
3208 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
3210 CHECK(compileAndRun<int>(proc, b) == (a | b));
3213 void addBitTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3215 RUN(testBitAndArgs(43, 43));
3216 RUN(testBitAndArgs(43, 0));
3217 RUN(testBitAndArgs(10, 3));
3218 RUN(testBitAndArgs(42, 0xffffffffffffffff));
3219 RUN(testBitAndSameArg(43));
3220 RUN(testBitAndSameArg(0));
3221 RUN(testBitAndSameArg(3));
3222 RUN(testBitAndSameArg(0xffffffffffffffff));
3223 RUN(testBitAndImms(43, 43));
3224 RUN(testBitAndImms(43, 0));
3225 RUN(testBitAndImms(10, 3));
3226 RUN(testBitAndImms(42, 0xffffffffffffffff));
3227 RUN(testBitAndArgImm(43, 43));
3228 RUN(testBitAndArgImm(43, 0));
3229 RUN(testBitAndArgImm(10, 3));
3230 RUN(testBitAndArgImm(42, 0xffffffffffffffff));
3231 RUN(testBitAndArgImm(42, 0xff));
3232 RUN(testBitAndArgImm(300, 0xff));
3233 RUN(testBitAndArgImm(-300, 0xff));
3234 RUN(testBitAndArgImm(42, 0xffff));
3235 RUN(testBitAndArgImm(40000, 0xffff));
3236 RUN(testBitAndArgImm(-40000, 0xffff));
3237 RUN(testBitAndImmArg(43, 43));
3238 RUN(testBitAndImmArg(43, 0));
3239 RUN(testBitAndImmArg(10, 3));
3240 RUN(testBitAndImmArg(42, 0xffffffffffffffff));
3241 RUN(testBitAndBitAndArgImmImm(2, 7, 3));
3242 RUN(testBitAndBitAndArgImmImm(1, 6, 6));
3243 RUN(testBitAndBitAndArgImmImm(0xffff, 24, 7));
3244 RUN(testBitAndImmBitAndArgImm(7, 2, 3));
3245 RUN(testBitAndImmBitAndArgImm(6, 1, 6));
3246 RUN(testBitAndImmBitAndArgImm(24, 0xffff, 7));
3247 RUN(testBitAndArgs32(43, 43));
3248 RUN(testBitAndArgs32(43, 0));
3249 RUN(testBitAndArgs32(10, 3));
3250 RUN(testBitAndArgs32(42, 0xffffffff));
3251 RUN(testBitAndSameArg32(43));
3252 RUN(testBitAndSameArg32(0));
3253 RUN(testBitAndSameArg32(3));
3254 RUN(testBitAndSameArg32(0xffffffff));
3255 RUN(testBitAndImms32(43, 43));
3256 RUN(testBitAndImms32(43, 0));
3257 RUN(testBitAndImms32(10, 3));
3258 RUN(testBitAndImms32(42, 0xffffffff));
3259 RUN(testBitAndArgImm32(43, 43));
3260 RUN(testBitAndArgImm32(43, 0));
3261 RUN(testBitAndArgImm32(10, 3));
3262 RUN(testBitAndArgImm32(42, 0xffffffff));
3263 RUN(testBitAndImmArg32(43, 43));
3264 RUN(testBitAndImmArg32(43, 0));
3265 RUN(testBitAndImmArg32(10, 3));
3266 RUN(testBitAndImmArg32(42, 0xffffffff));
3267 RUN(testBitAndImmArg32(42, 0xff));
3268 RUN(testBitAndImmArg32(300, 0xff));
3269 RUN(testBitAndImmArg32(-300, 0xff));
3270 RUN(testBitAndImmArg32(42, 0xffff));
3271 RUN(testBitAndImmArg32(40000, 0xffff));
3272 RUN(testBitAndImmArg32(-40000, 0xffff));
3273 RUN(testBitAndBitAndArgImmImm32(2, 7, 3));
3274 RUN(testBitAndBitAndArgImmImm32(1, 6, 6));
3275 RUN(testBitAndBitAndArgImmImm32(0xffff, 24, 7));
3276 RUN(testBitAndImmBitAndArgImm32(7, 2, 3));
3277 RUN(testBitAndImmBitAndArgImm32(6, 1, 6));
3278 RUN(testBitAndImmBitAndArgImm32(24, 0xffff, 7));
3279 RUN_BINARY(testBitAndWithMaskReturnsBooleans, int64Operands(), int64Operands());
3280 RUN_UNARY(testBitAndArgDouble, floatingPointOperands<double>());
3281 RUN_BINARY(testBitAndArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3282 RUN_BINARY(testBitAndArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3283 RUN_BINARY(testBitAndImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3284 RUN_UNARY(testBitAndArgFloat, floatingPointOperands<float>());
3285 RUN_BINARY(testBitAndArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3286 RUN_BINARY(testBitAndArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3287 RUN_BINARY(testBitAndImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3288 RUN_BINARY(testBitAndArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3289 RUN_BINARY(testBitAndNotNot, int64Operands(), int64Operands());
3290 RUN_BINARY(testBitAndNotImm, int64Operands(), int64Operands());
3292 RUN(testBitOrArgs(43, 43));
3293 RUN(testBitOrArgs(43, 0));
3294 RUN(testBitOrArgs(10, 3));
3295 RUN(testBitOrArgs(42, 0xffffffffffffffff));
3296 RUN(testBitOrSameArg(43));
3297 RUN(testBitOrSameArg(0));
3298 RUN(testBitOrSameArg(3));
3299 RUN(testBitOrSameArg(0xffffffffffffffff));
3300 RUN(testBitOrImms(43, 43));
3301 RUN(testBitOrImms(43, 0));
3302 RUN(testBitOrImms(10, 3));
3303 RUN(testBitOrImms(42, 0xffffffffffffffff));
3304 RUN(testBitOrArgImm(43, 43));
3305 RUN(testBitOrArgImm(43, 0));
3306 RUN(testBitOrArgImm(10, 3));
3307 RUN(testBitOrArgImm(42, 0xffffffffffffffff));
3308 RUN(testBitOrImmArg(43, 43));
3309 RUN(testBitOrImmArg(43, 0));
3310 RUN(testBitOrImmArg(10, 3));
3311 RUN(testBitOrImmArg(42, 0xffffffffffffffff));
3312 RUN(testBitOrBitOrArgImmImm(2, 7, 3));
3313 RUN(testBitOrBitOrArgImmImm(1, 6, 6));
3314 RUN(testBitOrBitOrArgImmImm(0xffff, 24, 7));
3315 RUN(testBitOrImmBitOrArgImm(7, 2, 3));
3316 RUN(testBitOrImmBitOrArgImm(6, 1, 6));
3317 RUN(testBitOrImmBitOrArgImm(24, 0xffff, 7));
3318 RUN(testBitOrArgs32(43, 43));
3319 RUN(testBitOrArgs32(43, 0));
3320 RUN(testBitOrArgs32(10, 3));
3321 RUN(testBitOrArgs32(42, 0xffffffff));
3322 RUN(testBitOrSameArg32(43));
3323 RUN(testBitOrSameArg32(0));
3324 RUN(testBitOrSameArg32(3));
3325 RUN(testBitOrSameArg32(0xffffffff));
3326 RUN(testBitOrImms32(43, 43));
3327 RUN(testBitOrImms32(43, 0));
3328 RUN(testBitOrImms32(10, 3));
3329 RUN(testBitOrImms32(42, 0xffffffff));
3330 RUN(testBitOrArgImm32(43, 43));
3331 RUN(testBitOrArgImm32(43, 0));
3332 RUN(testBitOrArgImm32(10, 3));
3333 RUN(testBitOrArgImm32(42, 0xffffffff));
3334 RUN(testBitOrImmArg32(43, 43));
3335 RUN(testBitOrImmArg32(43, 0));
3336 RUN(testBitOrImmArg32(10, 3));
3337 RUN(testBitOrImmArg32(42, 0xffffffff));
3338 RUN(testBitOrBitOrArgImmImm32(2, 7, 3));
3339 RUN(testBitOrBitOrArgImmImm32(1, 6, 6));
3340 RUN(testBitOrBitOrArgImmImm32(0xffff, 24, 7));
3341 RUN(testBitOrImmBitOrArgImm32(7, 2, 3));
3342 RUN(testBitOrImmBitOrArgImm32(6, 1, 6));
3343 RUN(testBitOrImmBitOrArgImm32(24, 0xffff, 7));
3344 RUN_UNARY(testBitOrArgDouble, floatingPointOperands<double>());
3345 RUN_BINARY(testBitOrArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3346 RUN_BINARY(testBitOrArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3347 RUN_BINARY(testBitOrImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3348 RUN_UNARY(testBitOrArgFloat, floatingPointOperands<float>());
3349 RUN_BINARY(testBitOrArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3350 RUN_BINARY(testBitOrArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3351 RUN_BINARY(testBitOrImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3352 RUN_BINARY(testBitOrArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3353 RUN_TERNARY(testBitOrAndAndArgs, int64Operands(), int64Operands(), int64Operands());
3354 RUN_BINARY(testBitOrAndSameArgs, int64Operands(), int64Operands());
3355 RUN_BINARY(testBitOrNotNot, int64Operands(), int64Operands());
3356 RUN_BINARY(testBitOrNotImm, int64Operands(), int64Operands());
3358 RUN_BINARY(testBitXorArgs, int64Operands(), int64Operands());
3359 RUN_UNARY(testBitXorSameArg, int64Operands());
3360 RUN_BINARY(testBitXorImms, int64Operands(), int64Operands());
3361 RUN_BINARY(testBitXorArgImm, int64Operands(), int64Operands());
3362 RUN_BINARY(testBitXorImmArg, int64Operands(), int64Operands());
3363 RUN(testBitXorBitXorArgImmImm(2, 7, 3));
3364 RUN(testBitXorBitXorArgImmImm(1, 6, 6));
3365 RUN(testBitXorBitXorArgImmImm(0xffff, 24, 7));
3366 RUN(testBitXorImmBitXorArgImm(7, 2, 3));
3367 RUN(testBitXorImmBitXorArgImm(6, 1, 6));
3368 RUN(testBitXorImmBitXorArgImm(24, 0xffff, 7));
3369 RUN(testBitXorArgs32(43, 43));
3370 RUN(testBitXorArgs32(43, 0));
3371 RUN(testBitXorArgs32(10, 3));
3372 RUN(testBitXorArgs32(42, 0xffffffff));
3373 RUN(testBitXorSameArg32(43));
3374 RUN(testBitXorSameArg32(0));
3375 RUN(testBitXorSameArg32(3));
3376 RUN(testBitXorSameArg32(0xffffffff));
3377 RUN(testBitXorImms32(43, 43));
3378 RUN(testBitXorImms32(43, 0));
3379 RUN(testBitXorImms32(10, 3));
3380 RUN(testBitXorImms32(42, 0xffffffff));
3381 RUN(testBitXorArgImm32(43, 43));
3382 RUN(testBitXorArgImm32(43, 0));
3383 RUN(testBitXorArgImm32(10, 3));
3384 RUN(testBitXorArgImm32(42, 0xffffffff));
3385 RUN(testBitXorImmArg32(43, 43));
3386 RUN(testBitXorImmArg32(43, 0));
3387 RUN(testBitXorImmArg32(10, 3));
3388 RUN(testBitXorImmArg32(42, 0xffffffff));
3389 RUN(testBitXorBitXorArgImmImm32(2, 7, 3));
3390 RUN(testBitXorBitXorArgImmImm32(1, 6, 6));
3391 RUN(testBitXorBitXorArgImmImm32(0xffff, 24, 7));
3392 RUN(testBitXorImmBitXorArgImm32(7, 2, 3));
3393 RUN(testBitXorImmBitXorArgImm32(6, 1, 6));
3394 RUN(testBitXorImmBitXorArgImm32(24, 0xffff, 7));
3395 RUN_TERNARY(testBitXorAndAndArgs, int64Operands(), int64Operands(), int64Operands());
3396 RUN_BINARY(testBitXorAndSameArgs, int64Operands(), int64Operands());
3398 RUN_UNARY(testBitNotArg, int64Operands());
3399 RUN_UNARY(testBitNotImm, int64Operands());
3400 RUN_UNARY(testBitNotMem, int64Operands());
3401 RUN_UNARY(testBitNotArg32, int32Operands());
3402 RUN_UNARY(testBitNotImm32, int32Operands());
3403 RUN_UNARY(testBitNotMem32, int32Operands());
3404 RUN_BINARY(testNotOnBooleanAndBranch32, int32Operands(), int32Operands());
3405 RUN_BINARY(testBitNotOnBooleanAndBranch32, int32Operands(), int32Operands());
3407 RUN_BINARY(testBitXorTreeArgs, int64Operands(), int64Operands());
3408 RUN_BINARY(testBitXorTreeArgsEven, int64Operands(), int64Operands());
3409 RUN_BINARY(testBitXorTreeArgImm, int64Operands(), int64Operands());
3410 RUN_UNARY(testBitAndTreeArg32, int32Operands());
3411 RUN_UNARY(testBitOrTreeArg32, int32Operands());
3414 #endif // ENABLE(B3_JIT)