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.
31 void testBitOrBitOrArgImmImm32(int a, int b, int c)
34 BasicBlock* root = proc.addBlock();
35 Value* innerBitOr = root->appendNew<Value>(
36 proc, BitOr, Origin(),
37 root->appendNew<Value>(
38 proc, Trunc, Origin(),
39 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
40 root->appendNew<Const32Value>(proc, Origin(), b));
41 root->appendNewControlValue(
42 proc, Return, Origin(),
43 root->appendNew<Value>(
44 proc, BitOr, Origin(),
46 root->appendNew<Const32Value>(proc, Origin(), c)));
48 CHECK(compileAndRun<int>(proc, a) == ((a | b) | c));
51 void testBitOrImmBitOrArgImm32(int a, int b, int c)
54 BasicBlock* root = proc.addBlock();
55 Value* innerBitOr = root->appendNew<Value>(
56 proc, BitOr, Origin(),
57 root->appendNew<Value>(
58 proc, Trunc, Origin(),
59 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
60 root->appendNew<Const32Value>(proc, Origin(), c));
61 root->appendNewControlValue(
62 proc, Return, Origin(),
63 root->appendNew<Value>(
64 proc, BitOr, Origin(),
65 root->appendNew<Const32Value>(proc, Origin(), a),
68 CHECK(compileAndRun<int>(proc, b) == (a | (b | c)));
71 double bitOrDouble(double a, double b)
73 return bitwise_cast<double>(bitwise_cast<uint64_t>(a) | bitwise_cast<uint64_t>(b));
76 void testBitOrArgDouble(double a)
79 BasicBlock* root = proc.addBlock();
80 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
81 Value* result = root->appendNew<Value>(proc, BitOr, Origin(), argument, argument);
82 root->appendNewControlValue(proc, Return, Origin(), result);
84 CHECK(isIdentical(compileAndRun<double>(proc, a), bitOrDouble(a, a)));
87 void testBitOrArgsDouble(double a, double b)
90 BasicBlock* root = proc.addBlock();
91 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
92 Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
93 Value* result = root->appendNew<Value>(proc, BitOr, Origin(), argumentA, argumentB);
94 root->appendNewControlValue(proc, Return, Origin(), result);
96 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitOrDouble(a, b)));
99 void testBitOrArgImmDouble(double a, double b)
102 BasicBlock* root = proc.addBlock();
103 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
104 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
105 Value* result = root->appendNew<Value>(proc, BitOr, Origin(), argumentA, argumentB);
106 root->appendNewControlValue(proc, Return, Origin(), result);
108 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitOrDouble(a, b)));
111 void testBitOrImmsDouble(double a, double b)
114 BasicBlock* root = proc.addBlock();
115 Value* argumentA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
116 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
117 Value* result = root->appendNew<Value>(proc, BitOr, Origin(), argumentA, argumentB);
118 root->appendNewControlValue(proc, Return, Origin(), result);
120 CHECK(isIdentical(compileAndRun<double>(proc), bitOrDouble(a, b)));
123 float bitOrFloat(float a, float b)
125 return bitwise_cast<float>(bitwise_cast<uint32_t>(a) | bitwise_cast<uint32_t>(b));
128 void testBitOrArgFloat(float a)
131 BasicBlock* root = proc.addBlock();
132 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(),
133 root->appendNew<Value>(proc, Trunc, Origin(),
134 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
135 Value* result = root->appendNew<Value>(proc, BitOr, Origin(), argument, argument);
136 root->appendNewControlValue(proc, Return, Origin(), result);
138 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), bitOrFloat(a, a)));
141 void testBitOrArgsFloat(float a, float b)
144 BasicBlock* root = proc.addBlock();
145 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
146 root->appendNew<Value>(proc, Trunc, Origin(),
147 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
148 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
149 root->appendNew<Value>(proc, Trunc, Origin(),
150 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
151 Value* result = root->appendNew<Value>(proc, BitOr, Origin(), argumentA, argumentB);
152 root->appendNewControlValue(proc, Return, Origin(), result);
154 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitOrFloat(a, b)));
157 void testBitOrArgImmFloat(float a, float b)
160 BasicBlock* root = proc.addBlock();
161 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
162 root->appendNew<Value>(proc, Trunc, Origin(),
163 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
164 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
165 Value* result = root->appendNew<Value>(proc, BitOr, Origin(), argumentA, argumentB);
166 root->appendNewControlValue(proc, Return, Origin(), result);
168 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitOrFloat(a, b)));
171 void testBitOrImmsFloat(float a, float b)
174 BasicBlock* root = proc.addBlock();
175 Value* argumentA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
176 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
177 Value* result = root->appendNew<Value>(proc, BitOr, Origin(), argumentA, argumentB);
178 root->appendNewControlValue(proc, Return, Origin(), result);
180 CHECK(isIdentical(compileAndRun<float>(proc), bitOrFloat(a, b)));
183 void testBitOrArgsFloatWithUselessDoubleConversion(float a, float b)
186 BasicBlock* root = proc.addBlock();
187 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
188 root->appendNew<Value>(proc, Trunc, Origin(),
189 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
190 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
191 root->appendNew<Value>(proc, Trunc, Origin(),
192 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
193 Value* argumentAasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentA);
194 Value* argumentBasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentB);
195 Value* doubleResult = root->appendNew<Value>(proc, BitOr, Origin(), argumentAasDouble, argumentBasDouble);
196 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleResult);
197 root->appendNewControlValue(proc, Return, Origin(), floatResult);
201 float expected = static_cast<float>(bitOrDouble(doubleA, doubleB));
202 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), expected));
205 void testBitXorArgs(int64_t a, int64_t b)
208 BasicBlock* root = proc.addBlock();
209 root->appendNewControlValue(
210 proc, Return, Origin(),
211 root->appendNew<Value>(
212 proc, BitXor, Origin(),
213 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
214 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
216 CHECK(compileAndRun<int64_t>(proc, a, b) == (a ^ b));
219 void testBitXorSameArg(int64_t a)
222 BasicBlock* root = proc.addBlock();
223 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
224 root->appendNewControlValue(
225 proc, Return, Origin(),
226 root->appendNew<Value>(
227 proc, BitXor, Origin(),
231 CHECK(!compileAndRun<int64_t>(proc, a));
234 void testBitXorAndAndArgs(int64_t a, int64_t b, int64_t c)
236 // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
237 // ((a & b) ^ (a & c))
238 // ((a & b) ^ (c & a))
239 // ((b & a) ^ (a & c))
240 // ((b & a) ^ (c & a))
241 for (int i = 0; i < 4; ++i) {
243 BasicBlock* root = proc.addBlock();
244 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
245 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
246 Value* argC = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
247 Value* andAB = i & 2 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
248 : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
249 Value* andAC = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argC)
250 : root->appendNew<Value>(proc, BitAnd, Origin(), argC, argA);
251 root->appendNewControlValue(
252 proc, Return, Origin(),
253 root->appendNew<Value>(
254 proc, BitXor, Origin(),
258 CHECK_EQ(compileAndRun<int64_t>(proc, a, b, c), ((a & b) ^ (a & c)));
262 void testBitXorAndSameArgs(int64_t a, int64_t b)
264 // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
269 for (int i = 0; i < 4; ++i) {
271 BasicBlock* root = proc.addBlock();
272 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
273 Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
274 Value* andAB = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
275 : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
276 Value* result = i & 2 ? root->appendNew<Value>(proc, BitXor, Origin(), andAB, argA)
277 : root->appendNew<Value>(proc, BitXor, Origin(), argA, andAB);
278 root->appendNewControlValue(proc, Return, Origin(), result);
280 CHECK_EQ(compileAndRun<int64_t>(proc, a, b), ((a & b) ^ a));
284 void testBitXorImms(int64_t a, int64_t b)
287 BasicBlock* root = proc.addBlock();
288 root->appendNewControlValue(
289 proc, Return, Origin(),
290 root->appendNew<Value>(
291 proc, BitXor, Origin(),
292 root->appendNew<Const64Value>(proc, Origin(), a),
293 root->appendNew<Const64Value>(proc, Origin(), b)));
295 CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
298 void testBitXorArgImm(int64_t a, int64_t b)
301 BasicBlock* root = proc.addBlock();
302 root->appendNewControlValue(
303 proc, Return, Origin(),
304 root->appendNew<Value>(
305 proc, BitXor, Origin(),
306 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
307 root->appendNew<Const64Value>(proc, Origin(), b)));
309 CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
312 void testBitXorImmArg(int64_t a, int64_t b)
315 BasicBlock* root = proc.addBlock();
316 root->appendNewControlValue(
317 proc, Return, Origin(),
318 root->appendNew<Value>(
319 proc, BitXor, Origin(),
320 root->appendNew<Const64Value>(proc, Origin(), a),
321 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
323 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
326 void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
329 BasicBlock* root = proc.addBlock();
330 Value* innerBitXor = root->appendNew<Value>(
331 proc, BitXor, Origin(),
332 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
333 root->appendNew<Const64Value>(proc, Origin(), b));
334 root->appendNewControlValue(
335 proc, Return, Origin(),
336 root->appendNew<Value>(
337 proc, BitXor, Origin(),
339 root->appendNew<Const64Value>(proc, Origin(), c)));
341 CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
344 void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
347 BasicBlock* root = proc.addBlock();
348 Value* innerBitXor = root->appendNew<Value>(
349 proc, BitXor, Origin(),
350 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
351 root->appendNew<Const64Value>(proc, Origin(), c));
352 root->appendNewControlValue(
353 proc, Return, Origin(),
354 root->appendNew<Value>(
355 proc, BitXor, Origin(),
356 root->appendNew<Const64Value>(proc, Origin(), a),
359 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
362 void testBitXorArgs32(int a, int b)
365 BasicBlock* root = proc.addBlock();
366 root->appendNewControlValue(
367 proc, Return, Origin(),
368 root->appendNew<Value>(
369 proc, BitXor, Origin(),
370 root->appendNew<Value>(
371 proc, Trunc, Origin(),
372 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
373 root->appendNew<Value>(
374 proc, Trunc, Origin(),
375 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
377 CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
380 void testBitXorSameArg32(int a)
383 BasicBlock* root = proc.addBlock();
384 Value* argument = root->appendNew<Value>(
385 proc, Trunc, Origin(),
386 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
387 root->appendNewControlValue(
388 proc, Return, Origin(),
389 root->appendNew<Value>(
390 proc, BitXor, Origin(),
394 CHECK(!compileAndRun<int>(proc, a));
397 void testBitXorImms32(int a, int b)
400 BasicBlock* root = proc.addBlock();
401 root->appendNewControlValue(
402 proc, Return, Origin(),
403 root->appendNew<Value>(
404 proc, BitXor, Origin(),
405 root->appendNew<Const32Value>(proc, Origin(), a),
406 root->appendNew<Const32Value>(proc, Origin(), b)));
408 CHECK(compileAndRun<int>(proc) == (a ^ b));
411 void testBitXorArgImm32(int a, int b)
414 BasicBlock* root = proc.addBlock();
415 root->appendNewControlValue(
416 proc, Return, Origin(),
417 root->appendNew<Value>(
418 proc, BitXor, Origin(),
419 root->appendNew<Value>(
420 proc, Trunc, Origin(),
421 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
422 root->appendNew<Const32Value>(proc, Origin(), b)));
424 CHECK(compileAndRun<int>(proc, a) == (a ^ b));
427 void testBitXorImmArg32(int a, int b)
430 BasicBlock* root = proc.addBlock();
431 root->appendNewControlValue(
432 proc, Return, Origin(),
433 root->appendNew<Value>(
434 proc, BitXor, Origin(),
435 root->appendNew<Const32Value>(proc, Origin(), a),
436 root->appendNew<Value>(
437 proc, Trunc, Origin(),
438 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
440 CHECK(compileAndRun<int>(proc, b) == (a ^ b));
443 void testBitXorBitXorArgImmImm32(int a, int b, int c)
446 BasicBlock* root = proc.addBlock();
447 Value* innerBitXor = root->appendNew<Value>(
448 proc, BitXor, Origin(),
449 root->appendNew<Value>(
450 proc, Trunc, Origin(),
451 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
452 root->appendNew<Const32Value>(proc, Origin(), b));
453 root->appendNewControlValue(
454 proc, Return, Origin(),
455 root->appendNew<Value>(
456 proc, BitXor, Origin(),
458 root->appendNew<Const32Value>(proc, Origin(), c)));
460 CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
463 void testBitXorImmBitXorArgImm32(int a, int b, int c)
466 BasicBlock* root = proc.addBlock();
467 Value* innerBitXor = root->appendNew<Value>(
468 proc, BitXor, Origin(),
469 root->appendNew<Value>(
470 proc, Trunc, Origin(),
471 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
472 root->appendNew<Const32Value>(proc, Origin(), c));
473 root->appendNewControlValue(
474 proc, Return, Origin(),
475 root->appendNew<Value>(
476 proc, BitXor, Origin(),
477 root->appendNew<Const32Value>(proc, Origin(), a),
480 CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
483 void testBitNotArg(int64_t a)
486 BasicBlock* root = proc.addBlock();
487 root->appendNewControlValue(
488 proc, Return, Origin(),
489 root->appendNew<Value>(
490 proc, BitXor, Origin(),
491 root->appendNew<Const64Value>(proc, Origin(), -1),
492 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
494 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
497 void testBitNotImm(int64_t a)
500 BasicBlock* root = proc.addBlock();
501 root->appendNewControlValue(
502 proc, Return, Origin(),
503 root->appendNew<Value>(
504 proc, BitXor, Origin(),
505 root->appendNew<Const64Value>(proc, Origin(), -1),
506 root->appendNew<Const64Value>(proc, Origin(), a)));
508 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
511 void testBitNotMem(int64_t a)
514 BasicBlock* root = proc.addBlock();
515 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
516 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
517 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
518 root->appendNew<Const64Value>(proc, Origin(), -1),
520 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
521 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
524 compileAndRun<int32_t>(proc, &input);
525 CHECK(isIdentical(input, static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
528 void testBitNotArg32(int32_t a)
531 BasicBlock* root = proc.addBlock();
532 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
533 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
534 root->appendNewControlValue(
535 proc, Return, Origin(),
536 root->appendNew<Value>(proc, BitXor, Origin(),
537 root->appendNew<Const32Value>(proc, Origin(), -1),
539 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
542 void testBitNotImm32(int32_t a)
545 BasicBlock* root = proc.addBlock();
546 root->appendNewControlValue(
547 proc, Return, Origin(),
548 root->appendNew<Value>(
549 proc, BitXor, Origin(),
550 root->appendNew<Const32Value>(proc, Origin(), -1),
551 root->appendNew<Const32Value>(proc, Origin(), a)));
553 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
556 void testBitNotMem32(int32_t a)
559 BasicBlock* root = proc.addBlock();
560 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
561 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
562 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
563 root->appendNew<Const32Value>(proc, Origin(), -1),
565 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
566 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
569 compileAndRun<int32_t>(proc, &input);
570 CHECK(isIdentical(input, static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
573 void testNotOnBooleanAndBranch32(int64_t a, int64_t b)
576 BasicBlock* root = proc.addBlock();
577 BasicBlock* thenCase = proc.addBlock();
578 BasicBlock* elseCase = proc.addBlock();
580 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
581 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
582 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
583 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
584 Value* argsAreEqual = root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2);
585 Value* argsAreNotEqual = root->appendNew<Value>(proc, BitXor, Origin(),
586 root->appendNew<Const32Value>(proc, Origin(), 1),
589 root->appendNewControlValue(
590 proc, Branch, Origin(),
592 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
594 thenCase->appendNewControlValue(
595 proc, Return, Origin(),
596 thenCase->appendNew<Const32Value>(proc, Origin(), 42));
598 elseCase->appendNewControlValue(
599 proc, Return, Origin(),
600 elseCase->appendNew<Const32Value>(proc, Origin(), -42));
602 int32_t expectedValue = (a != b) ? 42 : -42;
603 CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
606 void testBitNotOnBooleanAndBranch32(int64_t a, int64_t b)
609 BasicBlock* root = proc.addBlock();
610 BasicBlock* thenCase = proc.addBlock();
611 BasicBlock* elseCase = proc.addBlock();
613 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
614 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
615 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
616 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
617 Value* argsAreEqual = root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2);
618 Value* bitNotArgsAreEqual = root->appendNew<Value>(proc, BitXor, Origin(),
619 root->appendNew<Const32Value>(proc, Origin(), -1),
622 root->appendNewControlValue(proc, Branch, Origin(),
623 bitNotArgsAreEqual, FrequentedBlock(thenCase), FrequentedBlock(elseCase));
625 thenCase->appendNewControlValue(proc, Return, Origin(),
626 thenCase->appendNew<Const32Value>(proc, Origin(), 42));
628 elseCase->appendNewControlValue(proc, Return, Origin(),
629 elseCase->appendNew<Const32Value>(proc, Origin(), -42));
631 static constexpr int32_t expectedValue = 42;
632 CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
635 void testShlArgs(int64_t a, int64_t b)
638 BasicBlock* root = proc.addBlock();
639 root->appendNewControlValue(
640 proc, Return, Origin(),
641 root->appendNew<Value>(
643 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
644 root->appendNew<Value>(
645 proc, Trunc, Origin(),
646 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
648 CHECK(compileAndRun<int64_t>(proc, a, b) == (a << b));
651 void testShlImms(int64_t a, int64_t b)
654 BasicBlock* root = proc.addBlock();
655 root->appendNewControlValue(
656 proc, Return, Origin(),
657 root->appendNew<Value>(
659 root->appendNew<Const64Value>(proc, Origin(), a),
660 root->appendNew<Const32Value>(proc, Origin(), b)));
662 b = b & 0x3f; // to avoid undefined behaviour below
663 CHECK(compileAndRun<int64_t>(proc) == (a << b));
666 void testShlArgImm(int64_t a, int64_t b)
669 BasicBlock* root = proc.addBlock();
670 root->appendNewControlValue(
671 proc, Return, Origin(),
672 root->appendNew<Value>(
674 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
675 root->appendNew<Const32Value>(proc, Origin(), b)));
677 b = b & 0x3f; // to avoid undefined behaviour below
678 CHECK(compileAndRun<int64_t>(proc, a) == (a << b));
681 void testShlSShrArgImm(int64_t a, int64_t b)
684 BasicBlock* root = proc.addBlock();
685 Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
686 Value* constB = root->appendNew<Const32Value>(proc, Origin(), b);
687 Value* innerShift = root->appendNew<Value>(proc, SShr, Origin(), argA, constB);
688 root->appendNewControlValue(
689 proc, Return, Origin(),
690 root->appendNew<Value>(
695 b = b & 0x3f; // to avoid undefined behaviour below
696 CHECK(compileAndRun<int64_t>(proc, a) == ((a >> b) << b));
699 void testShlArg32(int32_t a)
702 BasicBlock* root = proc.addBlock();
703 Value* value = root->appendNew<Value>(
704 proc, Trunc, Origin(),
705 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
706 root->appendNewControlValue(
707 proc, Return, Origin(),
708 root->appendNew<Value>(proc, Shl, Origin(), value, value));
710 CHECK(compileAndRun<int32_t>(proc, a) == (a << a));
713 void testShlArgs32(int32_t a, int32_t b)
716 BasicBlock* root = proc.addBlock();
717 root->appendNewControlValue(
718 proc, Return, Origin(),
719 root->appendNew<Value>(
721 root->appendNew<Value>(
722 proc, Trunc, Origin(),
723 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
724 root->appendNew<Value>(
725 proc, Trunc, Origin(),
726 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
728 CHECK(compileAndRun<int32_t>(proc, a, b) == (a << b));
731 void testShlImms32(int32_t a, int32_t b)
734 BasicBlock* root = proc.addBlock();
735 root->appendNewControlValue(
736 proc, Return, Origin(),
737 root->appendNew<Value>(
739 root->appendNew<Const32Value>(proc, Origin(), a),
740 root->appendNew<Const32Value>(proc, Origin(), b)));
742 b = b & 0x1f; // to avoid undefined behaviour below
743 CHECK(compileAndRun<int32_t>(proc) == (a << b));
746 void testShlArgImm32(int32_t a, int32_t b)
749 BasicBlock* root = proc.addBlock();
750 root->appendNewControlValue(
751 proc, Return, Origin(),
752 root->appendNew<Value>(
754 root->appendNew<Value>(
755 proc, Trunc, Origin(),
756 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
757 root->appendNew<Const32Value>(proc, Origin(), b)));
759 b = b & 0x1f; // to avoid undefined behaviour below
760 CHECK(compileAndRun<int32_t>(proc, a) == (a << b));
763 void testShlZShrArgImm32(int32_t a, int32_t b)
766 BasicBlock* root = proc.addBlock();
767 Value* argA = root->appendNew<Value>(
768 proc, Trunc, Origin(),
769 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
770 Value* constB = root->appendNew<Const32Value>(proc, Origin(), b);
771 Value* innerShift = root->appendNew<Value>(proc, ZShr, Origin(), argA, constB);
772 root->appendNewControlValue(
773 proc, Return, Origin(),
774 root->appendNew<Value>(
779 b = b & 0x1f; // to avoid undefined behaviour below
780 CHECK(compileAndRun<int32_t>(proc, a) == static_cast<int32_t>((static_cast<uint32_t>(a) >> b) << b));
783 static void testSShrArgs(int64_t a, int64_t b)
786 BasicBlock* root = proc.addBlock();
787 root->appendNewControlValue(
788 proc, Return, Origin(),
789 root->appendNew<Value>(
790 proc, SShr, Origin(),
791 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
792 root->appendNew<Value>(
793 proc, Trunc, Origin(),
794 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
796 CHECK(compileAndRun<int64_t>(proc, a, b) == (a >> b));
799 static void testSShrImms(int64_t a, int64_t b)
802 BasicBlock* root = proc.addBlock();
803 root->appendNewControlValue(
804 proc, Return, Origin(),
805 root->appendNew<Value>(
806 proc, SShr, Origin(),
807 root->appendNew<Const64Value>(proc, Origin(), a),
808 root->appendNew<Const32Value>(proc, Origin(), b)));
810 CHECK(compileAndRun<int64_t>(proc) == (a >> b));
813 static void testSShrArgImm(int64_t a, int64_t b)
816 BasicBlock* root = proc.addBlock();
817 root->appendNewControlValue(
818 proc, Return, Origin(),
819 root->appendNew<Value>(
820 proc, SShr, Origin(),
821 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
822 root->appendNew<Const32Value>(proc, Origin(), b)));
824 CHECK(compileAndRun<int64_t>(proc, a) == (a >> b));
827 static void testSShrArg32(int32_t a)
830 BasicBlock* root = proc.addBlock();
831 Value* value = root->appendNew<Value>(
832 proc, Trunc, Origin(),
833 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
834 root->appendNewControlValue(
835 proc, Return, Origin(),
836 root->appendNew<Value>(proc, SShr, Origin(), value, value));
838 CHECK(compileAndRun<int32_t>(proc, a) == (a >> (a & 31)));
841 static void testSShrArgs32(int32_t a, int32_t b)
844 BasicBlock* root = proc.addBlock();
845 root->appendNewControlValue(
846 proc, Return, Origin(),
847 root->appendNew<Value>(
848 proc, SShr, Origin(),
849 root->appendNew<Value>(
850 proc, Trunc, Origin(),
851 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
852 root->appendNew<Value>(
853 proc, Trunc, Origin(),
854 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
856 CHECK(compileAndRun<int32_t>(proc, a, b) == (a >> b));
859 static void testSShrImms32(int32_t a, int32_t b)
862 BasicBlock* root = proc.addBlock();
863 root->appendNewControlValue(
864 proc, Return, Origin(),
865 root->appendNew<Value>(
866 proc, SShr, Origin(),
867 root->appendNew<Const32Value>(proc, Origin(), a),
868 root->appendNew<Const32Value>(proc, Origin(), b)));
870 CHECK(compileAndRun<int32_t>(proc) == (a >> b));
873 static void testSShrArgImm32(int32_t a, int32_t b)
876 BasicBlock* root = proc.addBlock();
877 root->appendNewControlValue(
878 proc, Return, Origin(),
879 root->appendNew<Value>(
880 proc, SShr, Origin(),
881 root->appendNew<Value>(
882 proc, Trunc, Origin(),
883 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
884 root->appendNew<Const32Value>(proc, Origin(), b)));
886 CHECK(compileAndRun<int32_t>(proc, a) == (a >> b));
889 static void testZShrArgs(uint64_t a, uint64_t b)
892 BasicBlock* root = proc.addBlock();
893 root->appendNewControlValue(
894 proc, Return, Origin(),
895 root->appendNew<Value>(
896 proc, ZShr, Origin(),
897 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
898 root->appendNew<Value>(
899 proc, Trunc, Origin(),
900 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
902 CHECK(compileAndRun<uint64_t>(proc, a, b) == (a >> b));
905 static void testZShrImms(uint64_t a, uint64_t b)
908 BasicBlock* root = proc.addBlock();
909 root->appendNewControlValue(
910 proc, Return, Origin(),
911 root->appendNew<Value>(
912 proc, ZShr, Origin(),
913 root->appendNew<Const64Value>(proc, Origin(), a),
914 root->appendNew<Const32Value>(proc, Origin(), b)));
916 CHECK(compileAndRun<uint64_t>(proc) == (a >> b));
919 static void testZShrArgImm(uint64_t a, uint64_t b)
922 BasicBlock* root = proc.addBlock();
923 root->appendNewControlValue(
924 proc, Return, Origin(),
925 root->appendNew<Value>(
926 proc, ZShr, Origin(),
927 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
928 root->appendNew<Const32Value>(proc, Origin(), b)));
930 CHECK(compileAndRun<uint64_t>(proc, a) == (a >> b));
933 static void testZShrArg32(uint32_t a)
936 BasicBlock* root = proc.addBlock();
937 Value* value = root->appendNew<Value>(
938 proc, Trunc, Origin(),
939 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
940 root->appendNewControlValue(
941 proc, Return, Origin(),
942 root->appendNew<Value>(proc, ZShr, Origin(), value, value));
944 CHECK(compileAndRun<uint32_t>(proc, a) == (a >> (a & 31)));
947 static void testZShrArgs32(uint32_t a, uint32_t b)
950 BasicBlock* root = proc.addBlock();
951 root->appendNewControlValue(
952 proc, Return, Origin(),
953 root->appendNew<Value>(
954 proc, ZShr, Origin(),
955 root->appendNew<Value>(
956 proc, Trunc, Origin(),
957 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
958 root->appendNew<Value>(
959 proc, Trunc, Origin(),
960 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
962 CHECK(compileAndRun<uint32_t>(proc, a, b) == (a >> b));
965 static void testZShrImms32(uint32_t a, uint32_t b)
968 BasicBlock* root = proc.addBlock();
969 root->appendNewControlValue(
970 proc, Return, Origin(),
971 root->appendNew<Value>(
972 proc, ZShr, Origin(),
973 root->appendNew<Const32Value>(proc, Origin(), a),
974 root->appendNew<Const32Value>(proc, Origin(), b)));
976 CHECK(compileAndRun<uint32_t>(proc) == (a >> b));
979 static void testZShrArgImm32(uint32_t a, uint32_t b)
982 BasicBlock* root = proc.addBlock();
983 root->appendNewControlValue(
984 proc, Return, Origin(),
985 root->appendNew<Value>(
986 proc, ZShr, Origin(),
987 root->appendNew<Value>(
988 proc, Trunc, Origin(),
989 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
990 root->appendNew<Const32Value>(proc, Origin(), b)));
992 CHECK(compileAndRun<uint32_t>(proc, a) == (a >> b));
995 template<typename IntegerType>
996 static unsigned countLeadingZero(IntegerType value)
998 unsigned bitCount = sizeof(IntegerType) * 8;
1002 unsigned counter = 0;
1003 while (!(static_cast<uint64_t>(value) & (1l << (bitCount - 1)))) {
1010 void testClzArg64(int64_t a)
1013 BasicBlock* root = proc.addBlock();
1014 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1015 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
1016 root->appendNewControlValue(proc, Return, Origin(), clzValue);
1017 CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
1020 void testClzMem64(int64_t a)
1023 BasicBlock* root = proc.addBlock();
1024 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1025 MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1026 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
1027 root->appendNewControlValue(proc, Return, Origin(), clzValue);
1028 CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
1031 void testClzArg32(int32_t a)
1034 BasicBlock* root = proc.addBlock();
1035 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1036 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1037 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
1038 root->appendNewControlValue(proc, Return, Origin(), clzValue);
1039 CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
1042 void testClzMem32(int32_t a)
1045 BasicBlock* root = proc.addBlock();
1046 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1047 MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1048 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
1049 root->appendNewControlValue(proc, Return, Origin(), clzValue);
1050 CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
1053 void testAbsArg(double a)
1056 BasicBlock* root = proc.addBlock();
1057 root->appendNewControlValue(
1058 proc, Return, Origin(),
1059 root->appendNew<Value>(
1060 proc, Abs, Origin(),
1061 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
1063 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
1066 void testAbsImm(double a)
1069 BasicBlock* root = proc.addBlock();
1070 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1071 root->appendNewControlValue(
1072 proc, Return, Origin(),
1073 root->appendNew<Value>(proc, Abs, Origin(), argument));
1075 CHECK(isIdentical(compileAndRun<double>(proc), fabs(a)));
1078 void testAbsMem(double a)
1081 BasicBlock* root = proc.addBlock();
1082 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1083 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
1084 root->appendNewControlValue(
1085 proc, Return, Origin(),
1086 root->appendNew<Value>(proc, Abs, Origin(), loadDouble));
1088 CHECK(isIdentical(compileAndRun<double>(proc, &a), fabs(a)));
1091 void testAbsAbsArg(double a)
1094 BasicBlock* root = proc.addBlock();
1095 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(),
1096 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1097 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
1098 root->appendNewControlValue(proc, Return, Origin(), secondAbs);
1100 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(fabs(a))));
1103 void testAbsNegArg(double a)
1106 BasicBlock* root = proc.addBlock();
1107 Value* neg = root->appendNew<Value>(proc, Neg, Origin(),
1108 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1109 Value* abs = root->appendNew<Value>(proc, Abs, Origin(), neg);
1110 root->appendNewControlValue(proc, Return, Origin(), abs);
1112 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(- a)));
1115 void testAbsBitwiseCastArg(double a)
1118 BasicBlock* root = proc.addBlock();
1119 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1120 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
1121 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
1122 root->appendNewControlValue(proc, Return, Origin(), absValue);
1124 CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int64_t>(a)), fabs(a)));
1127 void testBitwiseCastAbsBitwiseCastArg(double a)
1130 BasicBlock* root = proc.addBlock();
1131 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1132 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
1133 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
1134 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
1136 root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
1138 int64_t expectedResult = bitwise_cast<int64_t>(fabs(a));
1139 CHECK(isIdentical(compileAndRun<int64_t>(proc, bitwise_cast<int64_t>(a)), expectedResult));
1142 void testAbsArg(float a)
1145 BasicBlock* root = proc.addBlock();
1146 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1147 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1148 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1149 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
1150 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1151 root->appendNewControlValue(proc, Return, Origin(), result32);
1153 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1156 void testAbsImm(float a)
1159 BasicBlock* root = proc.addBlock();
1160 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1161 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
1162 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1163 root->appendNewControlValue(proc, Return, Origin(), result32);
1165 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1168 void testAbsMem(float a)
1171 BasicBlock* root = proc.addBlock();
1172 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1173 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
1174 Value* result = root->appendNew<Value>(proc, Abs, Origin(), loadFloat);
1175 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1176 root->appendNewControlValue(proc, Return, Origin(), result32);
1178 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1181 void testAbsAbsArg(float a)
1184 BasicBlock* root = proc.addBlock();
1185 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1186 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1187 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1188 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(), argument);
1189 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
1190 root->appendNewControlValue(proc, Return, Origin(), secondAbs);
1192 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(fabs(a)))));
1195 void testAbsNegArg(float a)
1198 BasicBlock* root = proc.addBlock();
1199 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1200 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1201 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1202 Value* neg = root->appendNew<Value>(proc, Neg, Origin(), argument);
1203 Value* abs = root->appendNew<Value>(proc, Abs, Origin(), neg);
1204 root->appendNewControlValue(proc, Return, Origin(), abs);
1206 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(- a))));
1209 void testAbsBitwiseCastArg(float a)
1212 BasicBlock* root = proc.addBlock();
1213 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1214 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1215 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
1216 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
1217 root->appendNewControlValue(proc, Return, Origin(), absValue);
1219 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
1222 void testBitwiseCastAbsBitwiseCastArg(float a)
1225 BasicBlock* root = proc.addBlock();
1226 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1227 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1228 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
1229 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
1230 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
1232 root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
1234 int32_t expectedResult = bitwise_cast<int32_t>(static_cast<float>(fabs(a)));
1235 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), expectedResult));
1238 void testAbsArgWithUselessDoubleConversion(float a)
1241 BasicBlock* root = proc.addBlock();
1242 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1243 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1244 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1245 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1246 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
1247 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1248 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1249 root->appendNewControlValue(proc, Return, Origin(), result32);
1251 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1254 void testAbsArgWithEffectfulDoubleConversion(float a)
1257 BasicBlock* root = proc.addBlock();
1258 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1259 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1260 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1261 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1262 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
1263 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1264 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1265 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1266 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
1267 root->appendNewControlValue(proc, Return, Origin(), result32);
1270 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
1271 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1272 CHECK(isIdentical(effect, static_cast<double>(fabs(a))));
1275 void testCeilArg(double a)
1278 BasicBlock* root = proc.addBlock();
1279 root->appendNewControlValue(
1280 proc, Return, Origin(),
1281 root->appendNew<Value>(
1282 proc, Ceil, Origin(),
1283 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
1285 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
1288 void testCeilImm(double a)
1291 BasicBlock* root = proc.addBlock();
1292 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1293 root->appendNewControlValue(
1294 proc, Return, Origin(),
1295 root->appendNew<Value>(proc, Ceil, Origin(), argument));
1297 CHECK(isIdentical(compileAndRun<double>(proc), ceil(a)));
1300 void testCeilMem(double a)
1303 BasicBlock* root = proc.addBlock();
1304 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1305 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
1306 root->appendNewControlValue(
1307 proc, Return, Origin(),
1308 root->appendNew<Value>(proc, Ceil, Origin(), loadDouble));
1310 CHECK(isIdentical(compileAndRun<double>(proc, &a), ceil(a)));
1313 void testCeilCeilArg(double a)
1316 BasicBlock* root = proc.addBlock();
1317 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
1318 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1319 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
1320 root->appendNewControlValue(proc, Return, Origin(), secondCeil);
1322 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
1325 void testFloorCeilArg(double a)
1328 BasicBlock* root = proc.addBlock();
1329 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
1330 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1331 Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
1332 root->appendNewControlValue(proc, Return, Origin(), wrappingFloor);
1334 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
1337 void testCeilIToD64(int64_t a)
1340 BasicBlock* root = proc.addBlock();
1341 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1342 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
1344 root->appendNewControlValue(
1345 proc, Return, Origin(),
1346 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
1348 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
1351 void testCeilIToD32(int64_t a)
1354 BasicBlock* root = proc.addBlock();
1355 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1356 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1357 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
1359 root->appendNewControlValue(
1360 proc, Return, Origin(),
1361 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
1363 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
1366 void testCeilArg(float a)
1369 BasicBlock* root = proc.addBlock();
1370 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1371 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1372 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1373 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
1374 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1375 root->appendNewControlValue(proc, Return, Origin(), result32);
1377 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
1380 void testCeilImm(float a)
1383 BasicBlock* root = proc.addBlock();
1384 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1385 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
1386 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1387 root->appendNewControlValue(proc, Return, Origin(), result32);
1389 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
1392 void testCeilMem(float a)
1395 BasicBlock* root = proc.addBlock();
1396 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1397 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
1398 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), loadFloat);
1399 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1400 root->appendNewControlValue(proc, Return, Origin(), result32);
1402 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(ceilf(a))));
1405 void testCeilCeilArg(float a)
1408 BasicBlock* root = proc.addBlock();
1409 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1410 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1411 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1412 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
1413 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
1414 root->appendNewControlValue(proc, Return, Origin(), secondCeil);
1416 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
1419 void testFloorCeilArg(float a)
1422 BasicBlock* root = proc.addBlock();
1423 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1424 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1425 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1426 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
1427 Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
1428 root->appendNewControlValue(proc, Return, Origin(), wrappingFloor);
1430 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
1433 void testCeilArgWithUselessDoubleConversion(float a)
1436 BasicBlock* root = proc.addBlock();
1437 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1438 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1439 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1440 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1441 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
1442 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1443 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1444 root->appendNewControlValue(proc, Return, Origin(), result32);
1446 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
1449 void testCeilArgWithEffectfulDoubleConversion(float a)
1452 BasicBlock* root = proc.addBlock();
1453 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1454 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1455 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1456 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1457 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
1458 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1459 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1460 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1461 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
1462 root->appendNewControlValue(proc, Return, Origin(), result32);
1465 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
1466 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(ceilf(a))));
1467 CHECK(isIdentical(effect, static_cast<double>(ceilf(a))));
1470 void testFloorArg(double a)
1473 BasicBlock* root = proc.addBlock();
1474 root->appendNewControlValue(
1475 proc, Return, Origin(),
1476 root->appendNew<Value>(
1477 proc, Floor, Origin(),
1478 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
1480 CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
1483 void testFloorImm(double a)
1486 BasicBlock* root = proc.addBlock();
1487 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1488 root->appendNewControlValue(
1489 proc, Return, Origin(),
1490 root->appendNew<Value>(proc, Floor, Origin(), argument));
1492 CHECK(isIdentical(compileAndRun<double>(proc), floor(a)));
1495 void testFloorMem(double a)
1498 BasicBlock* root = proc.addBlock();
1499 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1500 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
1501 root->appendNewControlValue(
1502 proc, Return, Origin(),
1503 root->appendNew<Value>(proc, Floor, Origin(), loadDouble));
1505 CHECK(isIdentical(compileAndRun<double>(proc, &a), floor(a)));
1508 void testFloorFloorArg(double a)
1511 BasicBlock* root = proc.addBlock();
1512 Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(),
1513 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1514 Value* secondFloor = root->appendNew<Value>(proc, Floor, Origin(), firstFloor);
1515 root->appendNewControlValue(proc, Return, Origin(), secondFloor);
1517 CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
1520 void testCeilFloorArg(double a)
1523 BasicBlock* root = proc.addBlock();
1524 Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(),
1525 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1526 Value* wrappingCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstFloor);
1527 root->appendNewControlValue(proc, Return, Origin(), wrappingCeil);
1529 CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
1532 void testFloorIToD64(int64_t a)
1535 BasicBlock* root = proc.addBlock();
1536 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1537 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
1539 root->appendNewControlValue(
1540 proc, Return, Origin(),
1541 root->appendNew<Value>(proc, Floor, Origin(), argumentAsDouble));
1543 CHECK(isIdentical(compileAndRun<double>(proc, a), floor(static_cast<double>(a))));
1546 void testFloorIToD32(int64_t a)
1549 BasicBlock* root = proc.addBlock();
1550 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1551 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1552 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
1554 root->appendNewControlValue(
1555 proc, Return, Origin(),
1556 root->appendNew<Value>(proc, Floor, Origin(), argumentAsDouble));
1558 CHECK(isIdentical(compileAndRun<double>(proc, a), floor(static_cast<double>(a))));
1561 void testFloorArg(float a)
1564 BasicBlock* root = proc.addBlock();
1565 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1566 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1567 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1568 Value* result = root->appendNew<Value>(proc, Floor, Origin(), argument);
1569 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1570 root->appendNewControlValue(proc, Return, Origin(), result32);
1572 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
1575 void testFloorImm(float a)
1578 BasicBlock* root = proc.addBlock();
1579 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1580 Value* result = root->appendNew<Value>(proc, Floor, Origin(), argument);
1581 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1582 root->appendNewControlValue(proc, Return, Origin(), result32);
1584 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
1587 void testFloorMem(float a)
1590 BasicBlock* root = proc.addBlock();
1591 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1592 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
1593 Value* result = root->appendNew<Value>(proc, Floor, Origin(), loadFloat);
1594 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1595 root->appendNewControlValue(proc, Return, Origin(), result32);
1597 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(floorf(a))));
1600 void testFloorFloorArg(float a)
1603 BasicBlock* root = proc.addBlock();
1604 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1605 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1606 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1607 Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(), argument);
1608 Value* secondFloor = root->appendNew<Value>(proc, Floor, Origin(), firstFloor);
1609 root->appendNewControlValue(proc, Return, Origin(), secondFloor);
1611 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), floorf(a)));
1614 void testCeilFloorArg(float a)
1617 BasicBlock* root = proc.addBlock();
1618 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1619 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1620 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1621 Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(), argument);
1622 Value* wrappingCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstFloor);
1623 root->appendNewControlValue(proc, Return, Origin(), wrappingCeil);
1625 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), floorf(a)));
1628 void testFloorArgWithUselessDoubleConversion(float a)
1631 BasicBlock* root = proc.addBlock();
1632 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1633 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1634 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1635 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1636 Value* result = root->appendNew<Value>(proc, Floor, Origin(), asDouble);
1637 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1638 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1639 root->appendNewControlValue(proc, Return, Origin(), result32);
1641 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
1644 void testFloorArgWithEffectfulDoubleConversion(float a)
1647 BasicBlock* root = proc.addBlock();
1648 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1649 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1650 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1651 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1652 Value* result = root->appendNew<Value>(proc, Floor, Origin(), asDouble);
1653 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1654 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1655 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1656 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
1657 root->appendNewControlValue(proc, Return, Origin(), result32);
1660 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
1661 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(floorf(a))));
1662 CHECK(isIdentical(effect, static_cast<double>(floorf(a))));
1665 double correctSqrt(double value)
1667 #if CPU(X86) || CPU(X86_64)
1669 asm ("sqrtsd %1, %0" : "=x"(result) : "x"(value));
1676 void testSqrtArg(double a)
1679 BasicBlock* root = proc.addBlock();
1680 root->appendNewControlValue(
1681 proc, Return, Origin(),
1682 root->appendNew<Value>(
1683 proc, Sqrt, Origin(),
1684 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
1686 CHECK(isIdentical(compileAndRun<double>(proc, a), correctSqrt(a)));
1689 void testSqrtImm(double a)
1692 BasicBlock* root = proc.addBlock();
1693 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1694 root->appendNewControlValue(
1695 proc, Return, Origin(),
1696 root->appendNew<Value>(proc, Sqrt, Origin(), argument));
1698 CHECK(isIdentical(compileAndRun<double>(proc), correctSqrt(a)));
1701 void testSqrtMem(double a)
1704 BasicBlock* root = proc.addBlock();
1705 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1706 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
1707 root->appendNewControlValue(
1708 proc, Return, Origin(),
1709 root->appendNew<Value>(proc, Sqrt, Origin(), loadDouble));
1711 CHECK(isIdentical(compileAndRun<double>(proc, &a), correctSqrt(a)));
1714 void testSqrtArg(float a)
1717 BasicBlock* root = proc.addBlock();
1718 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1719 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1720 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1721 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), argument);
1722 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1723 root->appendNewControlValue(proc, Return, Origin(), result32);
1725 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1728 void testSqrtImm(float a)
1731 BasicBlock* root = proc.addBlock();
1732 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1733 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), argument);
1734 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1735 root->appendNewControlValue(proc, Return, Origin(), result32);
1737 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1740 void testSqrtMem(float a)
1743 BasicBlock* root = proc.addBlock();
1744 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1745 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
1746 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), loadFloat);
1747 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1748 root->appendNewControlValue(proc, Return, Origin(), result32);
1750 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1753 void testSqrtArgWithUselessDoubleConversion(float a)
1756 BasicBlock* root = proc.addBlock();
1757 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1758 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1759 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1760 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1761 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), asDouble);
1762 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1763 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1764 root->appendNewControlValue(proc, Return, Origin(), result32);
1766 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1769 void testSqrtArgWithEffectfulDoubleConversion(float a)
1772 BasicBlock* root = proc.addBlock();
1773 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1774 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1775 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1776 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1777 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), asDouble);
1778 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1779 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1780 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1781 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
1782 root->appendNewControlValue(proc, Return, Origin(), result32);
1785 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
1786 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1787 double expected = static_cast<double>(correctSqrt(a));
1788 CHECK(isIdentical(effect, expected));
1791 void testCompareTwoFloatToDouble(float a, float b)
1794 BasicBlock* root = proc.addBlock();
1796 Value* arg1As32 = root->appendNew<Value>(proc, Trunc, Origin(),
1797 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1798 Value* arg1Float = root->appendNew<Value>(proc, BitwiseCast, Origin(), arg1As32);
1799 Value* arg1AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg1Float);
1801 Value* arg2As32 = root->appendNew<Value>(proc, Trunc, Origin(),
1802 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1803 Value* arg2Float = root->appendNew<Value>(proc, BitwiseCast, Origin(), arg2As32);
1804 Value* arg2AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg2Float);
1805 Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg1AsDouble, arg2AsDouble);
1807 root->appendNewControlValue(proc, Return, Origin(), equal);
1809 CHECK(compileAndRun<int64_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)) == (a == b));
1812 void testCompareOneFloatToDouble(float a, double b)
1815 BasicBlock* root = proc.addBlock();
1817 Value* arg1As32 = root->appendNew<Value>(proc, Trunc, Origin(),
1818 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1819 Value* arg1Float = root->appendNew<Value>(proc, BitwiseCast, Origin(), arg1As32);
1820 Value* arg1AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg1Float);
1822 Value* arg2AsDouble = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1823 Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg1AsDouble, arg2AsDouble);
1825 root->appendNewControlValue(proc, Return, Origin(), equal);
1827 CHECK(compileAndRun<int64_t>(proc, bitwise_cast<int32_t>(a), b) == (a == b));
1830 void testCompareFloatToDoubleThroughPhi(float a, float b)
1833 BasicBlock* root = proc.addBlock();
1834 BasicBlock* thenCase = proc.addBlock();
1835 BasicBlock* elseCase = proc.addBlock();
1836 BasicBlock* tail = proc.addBlock();
1838 Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1840 Value* arg1As32 = root->appendNew<Value>(proc, Trunc, Origin(),
1841 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1842 Value* arg1Float = root->appendNew<Value>(proc, BitwiseCast, Origin(), arg1As32);
1843 Value* arg1AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg1Float);
1845 Value* arg2AsDouble = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1846 Value* arg2AsFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), arg2AsDouble);
1847 Value* arg2AsFRoundedDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg2AsFloat);
1849 root->appendNewControlValue(
1850 proc, Branch, Origin(),
1852 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1854 UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), arg1AsDouble);
1855 thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1857 Value* elseConst = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), 0.);
1858 UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), elseConst);
1859 elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1861 Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
1862 thenValue->setPhi(doubleInput);
1863 elseValue->setPhi(doubleInput);
1864 Value* equal = tail->appendNew<Value>(proc, Equal, Origin(), doubleInput, arg2AsFRoundedDouble);
1865 tail->appendNewControlValue(proc, Return, Origin(), equal);
1867 auto code = compileProc(proc);
1868 int32_t integerA = bitwise_cast<int32_t>(a);
1870 CHECK(invoke<int64_t>(*code, 1, integerA, doubleB) == (a == b));
1871 CHECK(invoke<int64_t>(*code, 0, integerA, doubleB) == (b == 0));
1874 void testDoubleToFloatThroughPhi(float value)
1878 // x = DoubleAdd(a, b)
1880 // x = DoubleAdd(a, c)
1883 // Both Adds can be converted to float add.
1885 BasicBlock* root = proc.addBlock();
1886 BasicBlock* thenCase = proc.addBlock();
1887 BasicBlock* elseCase = proc.addBlock();
1888 BasicBlock* tail = proc.addBlock();
1890 Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1891 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1892 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1893 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1894 Value* argAsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1896 root->appendNewControlValue(
1897 proc, Branch, Origin(),
1899 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1901 Value* postitiveConst = thenCase->appendNew<ConstDoubleValue>(proc, Origin(), 42.5f);
1902 Value* thenAdd = thenCase->appendNew<Value>(proc, Add, Origin(), argAsDouble, postitiveConst);
1903 UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), thenAdd);
1904 thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1906 Value* elseConst = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), M_PI);
1907 UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), elseConst);
1908 elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1910 Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
1911 thenValue->setPhi(doubleInput);
1912 elseValue->setPhi(doubleInput);
1913 Value* floatResult = tail->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleInput);
1914 tail->appendNewControlValue(proc, Return, Origin(), floatResult);
1916 auto code = compileProc(proc);
1917 CHECK(isIdentical(invoke<float>(*code, 1, bitwise_cast<int32_t>(value)), value + 42.5f));
1918 CHECK(isIdentical(invoke<float>(*code, 0, bitwise_cast<int32_t>(value)), static_cast<float>(M_PI)));
1921 void testReduceFloatToDoubleValidates()
1924 // f = DoubleToFloat(Bitcast(argGPR0))
1935 // This should not crash in the validator after ReduceFloatToDouble.
1937 BasicBlock* root = proc.addBlock();
1938 BasicBlock* thenCase = proc.addBlock();
1939 BasicBlock* elseCase = proc.addBlock();
1940 BasicBlock* tail = proc.addBlock();
1942 Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1943 Value* thingy = root->appendNew<Value>(proc, BitwiseCast, Origin(), condition);
1944 thingy = root->appendNew<Value>(proc, DoubleToFloat, Origin(), thingy); // Make the phase think it has work to do.
1945 root->appendNewControlValue(
1946 proc, Branch, Origin(),
1948 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1950 UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(),
1951 thenCase->appendNew<ConstFloatValue>(proc, Origin(), 11.5));
1952 thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1954 UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(),
1955 elseCase->appendNew<ConstFloatValue>(proc, Origin(), 10.5));
1956 elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1958 Value* phi = tail->appendNew<Value>(proc, Phi, Float, Origin());
1959 thenValue->setPhi(phi);
1960 elseValue->setPhi(phi);
1961 Value* result = tail->appendNew<Value>(proc, Mul, Origin(),
1963 result = tail->appendNew<Value>(proc, Add, Origin(),
1966 result = tail->appendNew<Value>(proc, Add, Origin(),
1969 tail->appendNewControlValue(proc, Return, Origin(), result);
1971 auto code = compileProc(proc);
1972 CHECK(isIdentical(invoke<float>(*code, 1), 11.5f * 11.5f + static_cast<float>(bitwise_cast<double>(static_cast<uint64_t>(1))) + 11.5f));
1973 CHECK(isIdentical(invoke<float>(*code, 0), 10.5f * 10.5f + static_cast<float>(bitwise_cast<double>(static_cast<uint64_t>(0))) + 10.5f));
1976 void testDoubleProducerPhiToFloatConversion(float value)
1979 BasicBlock* root = proc.addBlock();
1980 BasicBlock* thenCase = proc.addBlock();
1981 BasicBlock* elseCase = proc.addBlock();
1982 BasicBlock* tail = proc.addBlock();
1984 Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1985 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1986 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1987 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1989 root->appendNewControlValue(
1990 proc, Branch, Origin(),
1992 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1994 Value* asDouble = thenCase->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1995 UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), asDouble);
1996 thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1998 Value* constDouble = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), 42.5);
1999 UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), constDouble);
2000 elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2002 Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
2003 thenValue->setPhi(doubleInput);
2004 elseValue->setPhi(doubleInput);
2006 Value* argAsDoubleAgain = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2007 Value* finalAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, argAsDoubleAgain);
2008 Value* floatResult = tail->appendNew<Value>(proc, DoubleToFloat, Origin(), finalAdd);
2009 tail->appendNewControlValue(proc, Return, Origin(), floatResult);
2011 auto code = compileProc(proc);
2012 CHECK(isIdentical(invoke<float>(*code, 1, bitwise_cast<int32_t>(value)), value + value));
2013 CHECK(isIdentical(invoke<float>(*code, 0, bitwise_cast<int32_t>(value)), 42.5f + value));
2016 void testDoubleProducerPhiToFloatConversionWithDoubleConsumer(float value)
2018 // In this case, the Upsilon-Phi effectively contains a Float value, but it is used
2019 // as a Float and as a Double.
2021 BasicBlock* root = proc.addBlock();
2022 BasicBlock* thenCase = proc.addBlock();
2023 BasicBlock* elseCase = proc.addBlock();
2024 BasicBlock* tail = proc.addBlock();
2026 Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2027 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2028 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2029 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2031 root->appendNewControlValue(
2032 proc, Branch, Origin(),
2034 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2036 Value* asDouble = thenCase->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2037 UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), asDouble);
2038 thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2040 Value* constDouble = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), 42.5);
2041 UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), constDouble);
2042 elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2044 Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
2045 thenValue->setPhi(doubleInput);
2046 elseValue->setPhi(doubleInput);
2048 Value* argAsDoubleAgain = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2049 Value* floatAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, argAsDoubleAgain);
2052 Value* floatResult = tail->appendNew<Value>(proc, DoubleToFloat, Origin(), floatAdd);
2053 Value* doubleResult = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatResult);
2055 // This one *cannot* be eliminated
2056 Value* doubleAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, doubleResult);
2058 tail->appendNewControlValue(proc, Return, Origin(), doubleAdd);
2060 auto code = compileProc(proc);
2061 CHECK(isIdentical(invoke<double>(*code, 1, bitwise_cast<int32_t>(value)), (value + value) + static_cast<double>(value)));
2062 CHECK(isIdentical(invoke<double>(*code, 0, bitwise_cast<int32_t>(value)), static_cast<double>((42.5f + value) + 42.5f)));
2065 void testDoubleProducerPhiWithNonFloatConst(float value, double constValue)
2068 BasicBlock* root = proc.addBlock();
2069 BasicBlock* thenCase = proc.addBlock();
2070 BasicBlock* elseCase = proc.addBlock();
2071 BasicBlock* tail = proc.addBlock();
2073 Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2074 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2075 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2076 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2078 root->appendNewControlValue(
2079 proc, Branch, Origin(),
2081 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2083 Value* asDouble = thenCase->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2084 UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), asDouble);
2085 thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2087 Value* constDouble = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), constValue);
2088 UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), constDouble);
2089 elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2091 Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
2092 thenValue->setPhi(doubleInput);
2093 elseValue->setPhi(doubleInput);
2095 Value* argAsDoubleAgain = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2096 Value* finalAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, argAsDoubleAgain);
2097 Value* floatResult = tail->appendNew<Value>(proc, DoubleToFloat, Origin(), finalAdd);
2098 tail->appendNewControlValue(proc, Return, Origin(), floatResult);
2100 auto code = compileProc(proc);
2101 CHECK(isIdentical(invoke<float>(*code, 1, bitwise_cast<int32_t>(value)), value + value));
2102 CHECK(isIdentical(invoke<float>(*code, 0, bitwise_cast<int32_t>(value)), static_cast<float>(constValue + value)));
2105 void testDoubleArgToInt64BitwiseCast(double value)
2108 BasicBlock* root = proc.addBlock();
2109 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2111 root->appendNewControlValue(
2112 proc, Return, Origin(),
2113 root->appendNew<Value>(
2114 proc, BitwiseCast, Origin(), argument));
2116 CHECK(isIdentical(compileAndRun<int64_t>(proc, value), bitwise_cast<int64_t>(value)));
2119 void testDoubleImmToInt64BitwiseCast(double value)
2122 BasicBlock* root = proc.addBlock();
2123 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
2125 root->appendNewControlValue(
2126 proc, Return, Origin(),
2127 root->appendNew<Value>(
2128 proc, BitwiseCast, Origin(), argument));
2130 CHECK(isIdentical(compileAndRun<int64_t>(proc), bitwise_cast<int64_t>(value)));
2133 void testTwoBitwiseCastOnDouble(double value)
2136 BasicBlock* root = proc.addBlock();
2137 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2138 Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
2139 Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
2140 root->appendNewControlValue(proc, Return, Origin(), second);
2142 CHECK(isIdentical(compileAndRun<double>(proc, value), value));
2145 void testBitwiseCastOnDoubleInMemory(double value)
2148 BasicBlock* root = proc.addBlock();
2149 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2150 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
2151 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
2152 root->appendNewControlValue(proc, Return, Origin(), cast);
2154 CHECK(isIdentical(compileAndRun<int64_t>(proc, &value), bitwise_cast<int64_t>(value)));
2157 void testBitwiseCastOnDoubleInMemoryIndexed(double value)
2160 BasicBlock* root = proc.addBlock();
2161 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2162 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2163 Value* scaledOffset = root->appendNew<Value>(proc, Shl, Origin(),
2165 root->appendNew<Const32Value>(proc, Origin(), 3));
2166 Value* address = root->appendNew<Value>(proc, Add, Origin(), base, scaledOffset);
2167 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
2168 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
2169 root->appendNewControlValue(proc, Return, Origin(), cast);
2171 CHECK(isIdentical(compileAndRun<int64_t>(proc, &value, 0), bitwise_cast<int64_t>(value)));
2174 void testInt64BArgToDoubleBitwiseCast(int64_t value)
2177 BasicBlock* root = proc.addBlock();
2178 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2180 root->appendNewControlValue(
2181 proc, Return, Origin(),
2182 root->appendNew<Value>(
2183 proc, BitwiseCast, Origin(), argument));
2185 CHECK(isIdentical(compileAndRun<double>(proc, value), bitwise_cast<double>(value)));
2188 void testInt64BImmToDoubleBitwiseCast(int64_t value)
2191 BasicBlock* root = proc.addBlock();
2192 Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
2194 root->appendNewControlValue(
2195 proc, Return, Origin(),
2196 root->appendNew<Value>(
2197 proc, BitwiseCast, Origin(), argument));
2199 CHECK(isIdentical(compileAndRun<double>(proc), bitwise_cast<double>(value)));
2202 void testTwoBitwiseCastOnInt64(int64_t value)
2205 BasicBlock* root = proc.addBlock();
2206 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2207 Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
2208 Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
2209 root->appendNewControlValue(proc, Return, Origin(), second);
2211 CHECK(isIdentical(compileAndRun<int64_t>(proc, value), value));
2214 void testBitwiseCastOnInt64InMemory(int64_t value)
2217 BasicBlock* root = proc.addBlock();
2218 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2219 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2220 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
2221 root->appendNewControlValue(proc, Return, Origin(), cast);
2223 CHECK(isIdentical(compileAndRun<double>(proc, &value), bitwise_cast<double>(value)));
2226 void testBitwiseCastOnInt64InMemoryIndexed(int64_t value)
2229 BasicBlock* root = proc.addBlock();
2230 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2231 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2232 Value* scaledOffset = root->appendNew<Value>(proc, Shl, Origin(),
2234 root->appendNew<Const32Value>(proc, Origin(), 3));
2235 Value* address = root->appendNew<Value>(proc, Add, Origin(), base, scaledOffset);
2236 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2237 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
2238 root->appendNewControlValue(proc, Return, Origin(), cast);
2240 CHECK(isIdentical(compileAndRun<double>(proc, &value, 0), bitwise_cast<double>(value)));
2243 void testFloatImmToInt32BitwiseCast(float value)
2246 BasicBlock* root = proc.addBlock();
2247 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), value);
2249 root->appendNewControlValue(
2250 proc, Return, Origin(),
2251 root->appendNew<Value>(
2252 proc, BitwiseCast, Origin(), argument));
2254 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(value)));
2257 void testBitwiseCastOnFloatInMemory(float value)
2260 BasicBlock* root = proc.addBlock();
2261 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2262 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
2263 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadFloat);
2264 root->appendNewControlValue(proc, Return, Origin(), cast);
2266 CHECK(isIdentical(compileAndRun<int32_t>(proc, &value), bitwise_cast<int32_t>(value)));
2269 void testInt32BArgToFloatBitwiseCast(int32_t value)
2272 BasicBlock* root = proc.addBlock();
2273 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2275 root->appendNewControlValue(
2276 proc, Return, Origin(),
2277 root->appendNew<Value>(
2278 proc, BitwiseCast, Origin(), argument));
2280 CHECK(isIdentical(compileAndRun<float>(proc, value), bitwise_cast<float>(value)));
2283 void testInt32BImmToFloatBitwiseCast(int32_t value)
2286 BasicBlock* root = proc.addBlock();
2287 Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
2289 root->appendNewControlValue(
2290 proc, Return, Origin(),
2291 root->appendNew<Value>(
2292 proc, BitwiseCast, Origin(), argument));
2294 CHECK(isIdentical(compileAndRun<float>(proc), bitwise_cast<float>(value)));
2297 void testTwoBitwiseCastOnInt32(int32_t value)
2300 BasicBlock* root = proc.addBlock();
2301 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2302 Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
2303 Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
2304 root->appendNewControlValue(proc, Return, Origin(), second);
2306 CHECK(isIdentical(compileAndRun<int32_t>(proc, value), value));
2309 void testBitwiseCastOnInt32InMemory(int32_t value)
2312 BasicBlock* root = proc.addBlock();
2313 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2314 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2315 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadFloat);
2316 root->appendNewControlValue(proc, Return, Origin(), cast);
2318 CHECK(isIdentical(compileAndRun<float>(proc, &value), bitwise_cast<float>(value)));
2321 void testConvertDoubleToFloatArg(double value)
2324 BasicBlock* root = proc.addBlock();
2325 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2326 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
2327 root->appendNewControlValue(proc, Return, Origin(), asFloat);
2329 CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
2332 void testConvertDoubleToFloatImm(double value)
2335 BasicBlock* root = proc.addBlock();
2336 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
2337 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
2338 root->appendNewControlValue(proc, Return, Origin(), asFloat);
2340 CHECK(isIdentical(compileAndRun<float>(proc), static_cast<float>(value)));
2343 void testConvertDoubleToFloatMem(double value)
2346 BasicBlock* root = proc.addBlock();
2347 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2348 MemoryValue* loadedDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
2349 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), loadedDouble);
2350 root->appendNewControlValue(proc, Return, Origin(), asFloat);
2352 CHECK(isIdentical(compileAndRun<float>(proc, &value), static_cast<float>(value)));
2355 void testConvertFloatToDoubleArg(float value)
2358 BasicBlock* root = proc.addBlock();
2359 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2360 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2361 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2362 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2363 root->appendNewControlValue(proc, Return, Origin(), asDouble);
2365 CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int32_t>(value)), static_cast<double>(value)));
2368 void testConvertFloatToDoubleImm(float value)
2371 BasicBlock* root = proc.addBlock();
2372 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), value);
2373 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argument);
2374 root->appendNewControlValue(proc, Return, Origin(), asDouble);
2376 CHECK(isIdentical(compileAndRun<double>(proc), static_cast<double>(value)));
2379 void testConvertFloatToDoubleMem(float value)
2382 BasicBlock* root = proc.addBlock();
2383 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2384 MemoryValue* loadedFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
2385 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), loadedFloat);
2386 root->appendNewControlValue(proc, Return, Origin(), asDouble);
2388 CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(value)));
2391 void testConvertDoubleToFloatToDoubleToFloat(double value)
2394 BasicBlock* root = proc.addBlock();
2395 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2396 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
2397 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
2398 Value* asFloatAgain = root->appendNew<Value>(proc, DoubleToFloat, Origin(), asDouble);
2399 root->appendNewControlValue(proc, Return, Origin(), asFloatAgain);
2401 CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
2404 void testLoadFloatConvertDoubleConvertFloatStoreFloat(float value)
2407 BasicBlock* root = proc.addBlock();
2408 Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2409 Value* dst = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2410 MemoryValue* loadedFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), src);
2411 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), loadedFloat);
2412 Value* asFloatAgain = root->appendNew<Value>(proc, DoubleToFloat, Origin(), asDouble);
2413 root->appendNew<MemoryValue>(proc, Store, Origin(), asFloatAgain, dst);
2415 root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2417 float input = value;
2419 CHECK(!compileAndRun<int64_t>(proc, &input, &output));
2420 CHECK(isIdentical(input, output));
2423 void testFroundArg(double value)
2426 BasicBlock* root = proc.addBlock();
2427 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2428 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
2429 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
2430 root->appendNewControlValue(proc, Return, Origin(), asDouble);
2432 CHECK(isIdentical(compileAndRun<double>(proc, value), static_cast<double>(static_cast<float>(value))));
2435 void testFroundMem(double value)
2438 BasicBlock* root = proc.addBlock();
2439 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2440 MemoryValue* loadedDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
2441 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), loadedDouble);
2442 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
2443 root->appendNewControlValue(proc, Return, Origin(), asDouble);
2445 CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(static_cast<float>(value))));
2448 void testIToD64Arg()
2451 BasicBlock* root = proc.addBlock();
2452 Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2453 Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), src);
2454 root->appendNewControlValue(proc, Return, Origin(), srcAsDouble);
2456 auto code = compileProc(proc);
2457 for (auto testValue : int64Operands())
2458 CHECK(isIdentical(invoke<double>(*code, testValue.value), static_cast<double>(testValue.value)));
2461 void testIToF64Arg()
2464 BasicBlock* root = proc.addBlock();
2465 Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2466 Value* srcAsFloat = root->appendNew<Value>(proc, IToF, Origin(), src);
2467 root->appendNewControlValue(proc, Return, Origin(), srcAsFloat);
2469 auto code = compileProc(proc);
2470 for (auto testValue : int64Operands())
2471 CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2474 void testIToD32Arg()
2477 BasicBlock* root = proc.addBlock();
2478 Value* src = root->appendNew<Value>(proc, Trunc, Origin(),
2479 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2480 Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), src);
2481 root->appendNewControlValue(proc, Return, Origin(), srcAsDouble);
2483 auto code = compileProc(proc);
2484 for (auto testValue : int32Operands())
2485 CHECK(isIdentical(invoke<double>(*code, testValue.value), static_cast<double>(testValue.value)));
2488 void testIToF32Arg()
2491 BasicBlock* root = proc.addBlock();
2492 Value* src = root->appendNew<Value>(proc, Trunc, Origin(),
2493 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2494 Value* srcAsFloat = root->appendNew<Value>(proc, IToF, Origin(), src);
2495 root->appendNewControlValue(proc, Return, Origin(), srcAsFloat);
2497 auto code = compileProc(proc);
2498 for (auto testValue : int32Operands())
2499 CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2502 void testIToD64Mem()
2505 BasicBlock* root = proc.addBlock();
2506 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2507 MemoryValue* loadedSrc = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2508 Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), loadedSrc);
2509 root->appendNewControlValue(proc, Return, Origin(), srcAsDouble);
2511 auto code = compileProc(proc);
2512 int64_t inMemoryValue;
2513 for (auto testValue : int64Operands()) {
2514 inMemoryValue = testValue.value;
2515 CHECK(isIdentical(invoke<double>(*code, &inMemoryValue), static_cast<double>(testValue.value)));
2516 CHECK(inMemoryValue == testValue.value);
2520 void testIToF64Mem()
2523 BasicBlock* root = proc.addBlock();
2524 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2525 MemoryValue* loadedSrc = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2526 Value* srcAsFloat = root->appendNew<Value>(proc, IToF, Origin(), loadedSrc);
2527 root->appendNewControlValue(proc, Return, Origin(), srcAsFloat);
2529 auto code = compileProc(proc);
2530 int64_t inMemoryValue;
2531 for (auto testValue : int64Operands()) {
2532 inMemoryValue = testValue.value;
2533 CHECK(isIdentical(invoke<float>(*code, &inMemoryValue), static_cast<float>(testValue.value)));
2534 CHECK(inMemoryValue == testValue.value);
2538 void testIToD32Mem()
2541 BasicBlock* root = proc.addBlock();
2542 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2543 MemoryValue* loadedSrc = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2544 Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), loadedSrc);
2545 root->appendNewControlValue(proc, Return, Origin(), srcAsDouble);
2547 auto code = compileProc(proc);
2548 int32_t inMemoryValue;
2549 for (auto testValue : int32Operands()) {
2550 inMemoryValue = testValue.value;
2551 CHECK(isIdentical(invoke<double>(*code, &inMemoryValue), static_cast<double>(testValue.value)));
2552 CHECK(inMemoryValue == testValue.value);
2556 void testIToF32Mem()
2559 BasicBlock* root = proc.addBlock();
2560 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2561 MemoryValue* loadedSrc = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2562 Value* srcAsFloat = root->appendNew<Value>(proc, IToF, Origin(), loadedSrc);
2563 root->appendNewControlValue(proc, Return, Origin(), srcAsFloat);
2565 auto code = compileProc(proc);
2566 int32_t inMemoryValue;
2567 for (auto testValue : int32Operands()) {
2568 inMemoryValue = testValue.value;
2569 CHECK(isIdentical(invoke<float>(*code, &inMemoryValue), static_cast<float>(testValue.value)));
2570 CHECK(inMemoryValue == testValue.value);
2574 void testIToD64Imm(int64_t value)
2577 BasicBlock* root = proc.addBlock();
2578 Value* src = root->appendNew<Const64Value>(proc, Origin(), value);
2579 Value* srcAsFloatingPoint = root->appendNew<Value>(proc, IToD, Origin(), src);
2580 root->appendNewControlValue(proc, Return, Origin(), srcAsFloatingPoint);
2581 CHECK(isIdentical(compileAndRun<double>(proc), static_cast<double>(value)));
2584 void testIToF64Imm(int64_t value)
2587 BasicBlock* root = proc.addBlock();
2588 Value* src = root->appendNew<Const64Value>(proc, Origin(), value);
2589 Value* srcAsFloatingPoint = root->appendNew<Value>(proc, IToF, Origin(), src);
2590 root->appendNewControlValue(proc, Return, Origin(), srcAsFloatingPoint);
2591 CHECK(isIdentical(compileAndRun<float>(proc), static_cast<float>(value)));
2594 void testIToD32Imm(int32_t value)
2597 BasicBlock* root = proc.addBlock();
2598 Value* src = root->appendNew<Const32Value>(proc, Origin(), value);
2599 Value* srcAsFloatingPoint = root->appendNew<Value>(proc, IToD, Origin(), src);
2600 root->appendNewControlValue(proc, Return, Origin(), srcAsFloatingPoint);
2601 CHECK(isIdentical(compileAndRun<double>(proc), static_cast<double>(value)));
2604 void testIToF32Imm(int32_t value)
2607 BasicBlock* root = proc.addBlock();
2608 Value* src = root->appendNew<Const32Value>(proc, Origin(), value);
2609 Value* srcAsFloatingPoint = root->appendNew<Value>(proc, IToF, Origin(), src);
2610 root->appendNewControlValue(proc, Return, Origin(), srcAsFloatingPoint);
2611 CHECK(isIdentical(compileAndRun<float>(proc), static_cast<float>(value)));
2614 void testIToDReducedToIToF64Arg()
2617 BasicBlock* root = proc.addBlock();
2618 Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2619 Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), src);
2620 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), srcAsDouble);
2621 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2623 auto code = compileProc(proc);
2624 for (auto testValue : int64Operands())
2625 CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2628 void testIToDReducedToIToF32Arg()
2631 BasicBlock* root = proc.addBlock();
2632 Value* src = root->appendNew<Value>(proc, Trunc, Origin(),
2633 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2634 Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), src);
2635 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), srcAsDouble);
2636 root->appendNewControlValue(proc, Return, Origin(), floatResult);
2638 auto code = compileProc(proc);
2639 for (auto testValue : int32Operands())
2640 CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2643 void testStore32(int value)
2646 BasicBlock* root = proc.addBlock();
2647 int slot = 0xbaadbeef;
2648 root->appendNew<MemoryValue>(
2649 proc, Store, Origin(),
2650 root->appendNew<Value>(
2651 proc, Trunc, Origin(),
2652 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2653 root->appendNew<ConstPtrValue>(proc, Origin(), &slot), 0);
2654 root->appendNewControlValue(
2655 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2657 CHECK(!compileAndRun<int>(proc, value));
2658 CHECK(slot == value);
2661 void testStoreConstant(int value)
2664 BasicBlock* root = proc.addBlock();
2665 int slot = 0xbaadbeef;
2666 root->appendNew<MemoryValue>(
2667 proc, Store, Origin(),
2668 root->appendNew<Const32Value>(proc, Origin(), value),
2669 root->appendNew<ConstPtrValue>(proc, Origin(), &slot), 0);
2670 root->appendNewControlValue(
2671 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2673 CHECK(!compileAndRun<int>(proc));
2674 CHECK(slot == value);
2677 void testStoreConstantPtr(intptr_t value)
2680 BasicBlock* root = proc.addBlock();
2683 slot = (static_cast<intptr_t>(0xbaadbeef) << 32) + static_cast<intptr_t>(0xbaadbeef);
2687 root->appendNew<MemoryValue>(
2688 proc, Store, Origin(),
2689 root->appendNew<ConstPtrValue>(proc, Origin(), value),
2690 root->appendNew<ConstPtrValue>(proc, Origin(), &slot), 0);
2691 root->appendNewControlValue(
2692 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2694 CHECK(!compileAndRun<int>(proc));
2695 CHECK(slot == value);
2698 void testStore8Arg()
2700 { // Direct addressing.
2702 BasicBlock* root = proc.addBlock();
2704 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
2705 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2706 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2708 root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2709 root->appendNewControlValue(proc, Return, Origin(), value);
2712 CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
2713 CHECK(storage == 42);
2716 { // Indexed addressing.
2718 BasicBlock* root = proc.addBlock();
2720 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
2721 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2722 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2723 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2724 Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
2726 Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2727 Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2729 root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2730 root->appendNewControlValue(proc, Return, Origin(), value);
2733 CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
2734 CHECK(storage == 42);
2738 void testStore8Imm()
2740 { // Direct addressing.
2742 BasicBlock* root = proc.addBlock();
2744 Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2745 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2747 root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2748 root->appendNewControlValue(proc, Return, Origin(), value);
2751 CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
2752 CHECK(storage == 42);
2755 { // Indexed addressing.
2757 BasicBlock* root = proc.addBlock();
2759 Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2760 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2761 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2762 Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
2764 Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2765 Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2767 root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2768 root->appendNewControlValue(proc, Return, Origin(), value);
2771 CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
2772 CHECK(storage == 42);
2776 void testStorePartial8BitRegisterOnX86()
2779 BasicBlock* root = proc.addBlock();
2781 // We want to have this in ECX.
2782 Value* returnValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2784 // We want this suck in EDX.
2785 Value* whereToStore = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2787 // The patch point is there to help us force the hand of the compiler.
2788 PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
2790 // For the value above to be materialized and give the allocator
2791 // a stronger insentive to name those register the way we need.
2792 patchpoint->append(ConstrainedValue(returnValue, ValueRep(GPRInfo::regT3)));
2793 patchpoint->append(ConstrainedValue(whereToStore, ValueRep(GPRInfo::regT2)));
2795 // We'll produce EDI.
2796 patchpoint->resultConstraint = ValueRep::reg(GPRInfo::regT6);
2798 // Give the allocator a good reason not to use any other register.
2799 RegisterSet clobberSet = RegisterSet::allGPRs();
2800 clobberSet.exclude(RegisterSet::stackRegisters());
2801 clobberSet.exclude(RegisterSet::reservedHardwareRegisters());
2802 clobberSet.clear(GPRInfo::regT3);
2803 clobberSet.clear(GPRInfo::regT2);
2804 clobberSet.clear(GPRInfo::regT6);
2805 patchpoint->clobberLate(clobberSet);
2808 patchpoint->setGenerator(
2809 [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2810 AllowMacroScratchRegisterUsage allowScratch(jit);
2811 jit.xor64(params[0].gpr(), params[0].gpr());
2814 // If everything went well, we should have the big number in eax,
2815 // patchpoint == EDI and whereToStore = EDX.
2816 // Since EDI == 5, and AH = 5 on 8 bit store, this would go wrong
2817 // if we use X86 partial registers.
2818 root->appendNew<MemoryValue>(proc, Store8, Origin(), patchpoint, whereToStore);
2820 root->appendNewControlValue(proc, Return, Origin(), returnValue);
2822 int8_t storage = 0xff;
2823 CHECK(compileAndRun<int64_t>(proc, 0x12345678abcdef12, &storage) == 0x12345678abcdef12);
2827 void testStore16Arg()
2829 { // Direct addressing.
2831 BasicBlock* root = proc.addBlock();
2833 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
2834 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2835 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2837 root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2838 root->appendNewControlValue(proc, Return, Origin(), value);
2840 int16_t storage = -1;
2841 CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
2842 CHECK(storage == 42);
2845 { // Indexed addressing.
2847 BasicBlock* root = proc.addBlock();
2849 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
2850 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2851 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2852 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2853 Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
2855 Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2856 Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2858 root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2859 root->appendNewControlValue(proc, Return, Origin(), value);
2861 int16_t storage = -1;
2862 CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
2863 CHECK(storage == 42);
2867 void testStore16Imm()
2869 { // Direct addressing.
2871 BasicBlock* root = proc.addBlock();
2873 Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2874 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2876 root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2877 root->appendNewControlValue(proc, Return, Origin(), value);
2879 int16_t storage = -1;
2880 CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
2881 CHECK(storage == 42);
2884 { // Indexed addressing.
2886 BasicBlock* root = proc.addBlock();
2888 Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2889 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2890 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2891 Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
2893 Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2894 Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2896 root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2897 root->appendNewControlValue(proc, Return, Origin(), value);
2899 int16_t storage = -1;
2900 CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
2901 CHECK(storage == 42);
2905 void testTrunc(int64_t value)
2908 BasicBlock* root = proc.addBlock();
2909 root->appendNewControlValue(
2910 proc, Return, Origin(),
2911 root->appendNew<Value>(
2912 proc, Trunc, Origin(),
2913 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2915 CHECK(compileAndRun<int>(proc, value) == static_cast<int>(value));
2918 void testAdd1(int value)
2921 BasicBlock* root = proc.addBlock();
2922 root->appendNewControlValue(
2923 proc, Return, Origin(),
2924 root->appendNew<Value>(
2925 proc, Add, Origin(),
2926 root->appendNew<Value>(
2927 proc, Trunc, Origin(),
2928 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2929 root->appendNew<Const32Value>(proc, Origin(), 1)));
2931 CHECK(compileAndRun<int>(proc, value) == value + 1);
2934 void testAdd1Ptr(intptr_t value)
2937 BasicBlock* root = proc.addBlock();
2938 root->appendNewControlValue(
2939 proc, Return, Origin(),
2940 root->appendNew<Value>(
2941 proc, Add, Origin(),
2942 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2943 root->appendNew<ConstPtrValue>(proc, Origin(), 1)));
2945 CHECK(compileAndRun<intptr_t>(proc, value) == value + 1);
2948 void testNeg32(int32_t value)
2951 BasicBlock* root = proc.addBlock();
2952 root->appendNewControlValue(
2953 proc, Return, Origin(),
2954 root->appendNew<Value>(
2955 proc, Sub, Origin(),
2956 root->appendNew<Const32Value>(proc, Origin(), 0),
2957 root->appendNew<Value>(
2958 proc, Trunc, Origin(),
2959 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2961 CHECK(compileAndRun<int32_t>(proc, value) == -value);
2964 void testNegPtr(intptr_t value)
2967 BasicBlock* root = proc.addBlock();
2968 root->appendNewControlValue(
2969 proc, Return, Origin(),
2970 root->appendNew<Value>(
2971 proc, Sub, Origin(),
2972 root->appendNew<ConstPtrValue>(proc, Origin(), 0),
2973 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2975 CHECK(compileAndRun<intptr_t>(proc, value) == -value);
2978 void testStoreAddLoad32(int amount)
2981 BasicBlock* root = proc.addBlock();
2983 ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
2984 root->appendNew<MemoryValue>(
2985 proc, Store, Origin(),
2986 root->appendNew<Value>(
2987 proc, Add, Origin(),
2988 root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
2989 root->appendNew<Value>(
2990 proc, Trunc, Origin(),
2991 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
2993 root->appendNewControlValue(
2994 proc, Return, Origin(),
2995 root->appendNew<Const32Value>(proc, Origin(), 0));
2997 CHECK(!compileAndRun<int>(proc, amount));
2998 CHECK(slot == 37 + amount);
3001 // Make sure the compiler does not try to optimize anything out.
3002 static NEVER_INLINE double zero()
3007 static double negativeZero()
3012 void addArgTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3014 RUN(testAddArg(111));
3015 RUN(testAddArgs(1, 1));
3016 RUN(testAddArgs(1, 2));
3017 RUN(testAddArgImm(1, 2));
3018 RUN(testAddArgImm(0, 2));
3019 RUN(testAddArgImm(1, 0));
3020 RUN(testAddImmArg(1, 2));
3021 RUN(testAddImmArg(0, 2));
3022 RUN(testAddImmArg(1, 0));
3023 RUN_BINARY(testAddArgMem, int64Operands(), int64Operands());
3024 RUN_BINARY(testAddMemArg, int64Operands(), int64Operands());
3025 RUN_BINARY(testAddImmMem, int64Operands(), int64Operands());
3026 RUN_UNARY(testAddArg32, int32Operands());
3027 RUN(testAddArgs32(1, 1));
3028 RUN(testAddArgs32(1, 2));
3029 RUN_BINARY(testAddArgMem32, int32Operands(), int32Operands());
3030 RUN_BINARY(testAddMemArg32, int32Operands(), int32Operands());
3031 RUN_BINARY(testAddImmMem32, int32Operands(), int32Operands());
3032 RUN_BINARY(testAddNeg1, int32Operands(), int32Operands());
3033 RUN_BINARY(testAddNeg2, int32Operands(), int32Operands());
3034 RUN(testAddArgZeroImmZDef());
3035 RUN(testAddLoadTwice());
3036 RUN_TERNARY(testAddMulMulArgs, int64Operands(), int64Operands(), int64Operands());
3038 RUN(testAddArgDouble(M_PI));
3039 RUN(testAddArgsDouble(M_PI, 1));
3040 RUN(testAddArgsDouble(M_PI, -M_PI));
3041 RUN(testAddArgImmDouble(M_PI, 1));
3042 RUN(testAddArgImmDouble(M_PI, 0));
3043 RUN(testAddArgImmDouble(M_PI, negativeZero()));
3044 RUN(testAddArgImmDouble(0, 0));
3045 RUN(testAddArgImmDouble(0, negativeZero()));
3046 RUN(testAddArgImmDouble(negativeZero(), 0));
3047 RUN(testAddArgImmDouble(negativeZero(), negativeZero()));
3048 RUN(testAddImmArgDouble(M_PI, 1));
3049 RUN(testAddImmArgDouble(M_PI, 0));
3050 RUN(testAddImmArgDouble(M_PI, negativeZero()));
3051 RUN(testAddImmArgDouble(0, 0));
3052 RUN(testAddImmArgDouble(0, negativeZero()));
3053 RUN(testAddImmArgDouble(negativeZero(), 0));
3054 RUN(testAddImmArgDouble(negativeZero(), negativeZero()));
3055 RUN(testAddImmsDouble(M_PI, 1));
3056 RUN(testAddImmsDouble(M_PI, 0));
3057 RUN(testAddImmsDouble(M_PI, negativeZero()));
3058 RUN(testAddImmsDouble(0, 0));
3059 RUN(testAddImmsDouble(0, negativeZero()));
3060 RUN(testAddImmsDouble(negativeZero(), negativeZero()));
3061 RUN_UNARY(testAddArgFloat, floatingPointOperands<float>());
3062 RUN_BINARY(testAddArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3063 RUN_BINARY(testAddFPRArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3064 RUN_BINARY(testAddArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3065 RUN_BINARY(testAddImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3066 RUN_BINARY(testAddImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3067 RUN_UNARY(testAddArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3068 RUN_BINARY(testAddArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3069 RUN_BINARY(testAddArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3072 RUN(testMulAddArg(5));
3073 RUN(testMulAddArg(85));
3074 RUN(testMulArgStore(5));
3075 RUN(testMulArgStore(85));
3076 RUN(testMulArgs(1, 1));
3077 RUN(testMulArgs(1, 2));
3078 RUN(testMulArgs(3, 3));
3079 RUN(testMulArgImm(1, 2));
3080 RUN(testMulArgImm(1, 4));
3081 RUN(testMulArgImm(1, 8));
3082 RUN(testMulArgImm(1, 16));
3083 RUN(testMulArgImm(1, 0x80000000llu));
3084 RUN(testMulArgImm(1, 0x800000000000llu));
3085 RUN(testMulArgImm(7, 2));
3086 RUN(testMulArgImm(7, 4));
3087 RUN(testMulArgImm(7, 8));
3088 RUN(testMulArgImm(7, 16));
3089 RUN(testMulArgImm(7, 0x80000000llu));
3090 RUN(testMulArgImm(7, 0x800000000000llu));
3091 RUN(testMulArgImm(-42, 2));
3092 RUN(testMulArgImm(-42, 4));
3093 RUN(testMulArgImm(-42, 8));
3094 RUN(testMulArgImm(-42, 16));
3095 RUN(testMulArgImm(-42, 0x80000000llu));
3096 RUN(testMulArgImm(-42, 0x800000000000llu));
3097 RUN(testMulArgImm(0, 2));
3098 RUN(testMulArgImm(1, 0));
3099 RUN(testMulArgImm(3, 3));
3100 RUN(testMulArgImm(3, -1));
3101 RUN(testMulArgImm(-3, -1));
3102 RUN(testMulArgImm(0, -1));
3103 RUN(testMulImmArg(1, 2));
3104 RUN(testMulImmArg(0, 2));
3105 RUN(testMulImmArg(1, 0));
3106 RUN(testMulImmArg(3, 3));
3107 RUN(testMulImm32SignExtend(1, 2));
3108 RUN(testMulImm32SignExtend(0, 2));
3109 RUN(testMulImm32SignExtend(1, 0));
3110 RUN(testMulImm32SignExtend(3, 3));
3111 RUN(testMulImm32SignExtend(0xFFFFFFFF, 0xFFFFFFFF));
3112 RUN(testMulImm32SignExtend(0xFFFFFFFE, 0xFFFFFFFF));
3113 RUN(testMulImm32SignExtend(0xFFFFFFFF, 0xFFFFFFFE));
3114 RUN(testMulArgs32(1, 1));
3115 RUN(testMulArgs32(1, 2));
3116 RUN(testMulArgs32(0xFFFFFFFF, 0xFFFFFFFF));
3117 RUN(testMulArgs32(0xFFFFFFFE, 0xFFFFFFFF));
3118 RUN(testMulArgs32SignExtend(1, 1));
3119 RUN(testMulArgs32SignExtend(1, 2));
3120 RUN(testMulArgs32SignExtend(0xFFFFFFFF, 0xFFFFFFFF));
3121 RUN(testMulArgs32SignExtend(0xFFFFFFFE, 0xFFFFFFFF));
3122 RUN(testMulLoadTwice());
3123 RUN(testMulAddArgsLeft());
3124 RUN(testMulAddArgsRight());
3125 RUN(testMulAddArgsLeft32());
3126 RUN(testMulAddArgsRight32());
3127 RUN(testMulSubArgsLeft());
3128 RUN(testMulSubArgsRight());
3129 RUN(testMulSubArgsLeft32());
3130 RUN(testMulSubArgsRight32());
3131 RUN(testMulNegArgs());
3132 RUN(testMulNegArgs32());
3134 RUN_BINARY(testMulArgNegArg, int64Operands(), int64Operands())
3135 RUN_BINARY(testMulNegArgArg, int64Operands(), int64Operands())
3136 RUN_UNARY(testMulArgDouble, floatingPointOperands<double>());
3137 RUN_BINARY(testMulArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3138 RUN_BINARY(testMulArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3139 RUN_BINARY(testMulImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3140 RUN_BINARY(testMulImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3141 RUN_UNARY(testMulArgFloat, floatingPointOperands<float>());
3142 RUN_BINARY(testMulArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3143 RUN_BINARY(testMulArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3144 RUN_BINARY(testMulImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3145 RUN_BINARY(testMulImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3146 RUN_UNARY(testMulArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3147 RUN_BINARY(testMulArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3148 RUN_BINARY(testMulArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3150 RUN(testDivArgDouble(M_PI));
3151 RUN(testDivArgsDouble(M_PI, 1));
3152 RUN(testDivArgsDouble(M_PI, -M_PI));
3153 RUN(testDivArgImmDouble(M_PI, 1));
3154 RUN(testDivArgImmDouble(M_PI, 0));
3155 RUN(testDivArgImmDouble(M_PI, negativeZero()));
3156 RUN(testDivArgImmDouble(0, 0));
3157 RUN(testDivArgImmDouble(0, negativeZero()));
3158 RUN(testDivArgImmDouble(negativeZero(), 0));
3159 RUN(testDivArgImmDouble(negativeZero(), negativeZero()));
3160 RUN(testDivImmArgDouble(M_PI, 1));
3161 RUN(testDivImmArgDouble(M_PI, 0));
3162 RUN(testDivImmArgDouble(M_PI, negativeZero()));
3163 RUN(testDivImmArgDouble(0, 0));
3164 RUN(testDivImmArgDouble(0, negativeZero()));
3165 RUN(testDivImmArgDouble(negativeZero(), 0));
3166 RUN(testDivImmArgDouble(negativeZero(), negativeZero()));
3167 RUN(testDivImmsDouble(M_PI, 1));
3168 RUN(testDivImmsDouble(M_PI, 0));
3169 RUN(testDivImmsDouble(M_PI, negativeZero()));
3170 RUN(testDivImmsDouble(0, 0));
3171 RUN(testDivImmsDouble(0, negativeZero()));
3172 RUN(testDivImmsDouble(negativeZero(), negativeZero()));
3173 RUN_UNARY(testDivArgFloat, floatingPointOperands<float>());
3174 RUN_BINARY(testDivArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3175 RUN_BINARY(testDivArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3176 RUN_BINARY(testDivImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3177 RUN_BINARY(testDivImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3178 RUN_UNARY(testDivArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3179 RUN_BINARY(testDivArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3180 RUN_BINARY(testDivArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3182 RUN_BINARY(testUDivArgsInt32, int32Operands(), int32Operands());
3183 RUN_BINARY(testUDivArgsInt64, int64Operands(), int64Operands());
3185 RUN_UNARY(testModArgDouble, floatingPointOperands<double>());
3186 RUN_BINARY(testModArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3187 RUN_BINARY(testModArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3188 RUN_BINARY(testModImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3189 RUN_BINARY(testModImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3190 RUN_UNARY(testModArgFloat, floatingPointOperands<float>());
3191 RUN_BINARY(testModArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3192 RUN_BINARY(testModArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3193 RUN_BINARY(testModImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3194 RUN_BINARY(testModImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3196 RUN_BINARY(testUModArgsInt32, int32Operands(), int32Operands());
3197 RUN_BINARY(testUModArgsInt64, int64Operands(), int64Operands());
3199 RUN(testSubArg(24));
3200 RUN(testSubArgs(1, 1));
3201 RUN(testSubArgs(1, 2));
3202 RUN(testSubArgs(13, -42));
3203 RUN(testSubArgs(-13, 42));
3204 RUN(testSubArgImm(1, 1));
3205 RUN(testSubArgImm(1, 2));
3206 RUN(testSubArgImm(13, -42));
3207 RUN(testSubArgImm(-13, 42));
3208 RUN(testSubArgImm(42, 0));
3209 RUN(testSubImmArg(1, 1));
3210 RUN(testSubImmArg(1, 2));
3211 RUN(testSubImmArg(13, -42));
3212 RUN(testSubImmArg(-13, 42));
3213 RUN_BINARY(testSubArgMem, int64Operands(), int64Operands());
3214 RUN_BINARY(testSubMemArg, int64Operands(), int64Operands());
3215 RUN_BINARY(testSubImmMem, int32Operands(), int32Operands());
3216 RUN_BINARY(testSubMemImm, int32Operands(), int32Operands());
3217 RUN_BINARY(testSubNeg, int32Operands(), int32Operands());
3218 RUN_BINARY(testNegSub, int32Operands(), int32Operands());
3219 RUN_UNARY(testNegValueSubOne, int32Operands());
3220 RUN_BINARY(testNegMulArgImm, int64Operands(), int64Operands());
3221 RUN_TERNARY(testSubMulMulArgs, int64Operands(), int64Operands(), int64Operands());
3223 RUN_TERNARY(testSubSub, int32Operands(), int32Operands(), int32Operands());
3224 RUN_TERNARY(testSubSub2, int32Operands(), int32Operands(), int32Operands());
3225 RUN_TERNARY(testSubAdd, int32Operands(), int32Operands(), int32Operands());
3226 RUN_BINARY(testSubFirstNeg, int32Operands(), int32Operands());
3228 RUN(testSubArgs32(1, 1));
3229 RUN(testSubArgs32(1, 2));
3230 RUN(testSubArgs32(13, -42));
3231 RUN(testSubArgs32(-13, 42));
3232 RUN(testSubArgImm32(1, 1));
3233 RUN(testSubArgImm32(1, 2));
3234 RUN(testSubArgImm32(13, -42));
3235 RUN(testSubArgImm32(-13, 42));
3236 RUN(testSubImmArg32(1, 1));
3237 RUN(testSubImmArg32(1, 2));
3238 RUN(testSubImmArg32(13, -42));
3239 RUN(testSubImmArg32(-13, 42));
3240 RUN_BINARY(testSubArgMem32, int32Operands(), int32Operands());
3241 RUN_BINARY(testSubMemArg32, int32Operands(), int32Operands());
3242 RUN_BINARY(testSubImmMem32, int32Operands(), int32Operands());
3243 RUN_BINARY(testSubMemImm32, int32Operands(), int32Operands());
3244 RUN_UNARY(testNegValueSubOne32, int64Operands());
3246 RUN_UNARY(testSubArgDouble, floatingPointOperands<double>());
3247 RUN_BINARY(testSubArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3248 RUN_BINARY(testSubArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3249 RUN_BINARY(testSubImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3250 RUN_BINARY(testSubImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3251 RUN_UNARY(testSubArgFloat, floatingPointOperands<float>());
3252 RUN_BINARY(testSubArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3253 RUN_BINARY(testSubArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3254 RUN_BINARY(testSubImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3255 RUN_BINARY(testSubImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3256 RUN_UNARY(testSubArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3257 RUN_BINARY(testSubArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3258 RUN_BINARY(testSubArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3261 void addCallTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3263 RUN(testCallSimple(1, 2));
3264 RUN(testCallRare(1, 2));
3265 RUN(testCallRareLive(1, 2, 3));
3266 RUN(testCallSimplePure(1, 2));
3267 RUN(testCallFunctionWithHellaArguments());
3268 RUN(testCallFunctionWithHellaArguments2());
3269 RUN(testCallFunctionWithHellaArguments3());
3271 RUN(testReturnDouble(0.0));
3272 RUN(testReturnDouble(negativeZero()));
3273 RUN(testReturnDouble(42.5));
3274 RUN_UNARY(testReturnFloat, floatingPointOperands<float>());
3276 RUN(testCallSimpleDouble(1, 2));
3277 RUN(testCallFunctionWithHellaDoubleArguments());
3278 RUN_BINARY(testCallSimpleFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3279 RUN(testCallFunctionWithHellaFloatArguments());
3282 void addShrTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3284 RUN(testSShrArgs(1, 0));
3285 RUN(testSShrArgs(1, 1));
3286 RUN(testSShrArgs(1, 62));
3287 RUN(testSShrArgs(0xffffffffffffffff, 0));
3288 RUN(testSShrArgs(0xffffffffffffffff, 1));
3289 RUN(testSShrArgs(0xffffffffffffffff, 63));
3290 RUN(testSShrImms(1, 0));
3291 RUN(testSShrImms(1, 1));
3292 RUN(testSShrImms(1, 62));
3293 RUN(testSShrImms(1, 65));
3294 RUN(testSShrImms(0xffffffffffffffff, 0));
3295 RUN(testSShrImms(0xffffffffffffffff, 1));
3296 RUN(testSShrImms(0xffffffffffffffff, 63));
3297 RUN(testSShrArgImm(1, 0));
3298 RUN(testSShrArgImm(1, 1));
3299 RUN(testSShrArgImm(1, 62));
3300 RUN(testSShrArgImm(1, 65));
3301 RUN(testSShrArgImm(0xffffffffffffffff, 0));
3302 RUN(testSShrArgImm(0xffffffffffffffff, 1));
3303 RUN(testSShrArgImm(0xffffffffffffffff, 63));
3304 RUN(testSShrArg32(32));
3305 RUN(testSShrArgs32(1, 0));
3306 RUN(testSShrArgs32(1, 1));
3307 RUN(testSShrArgs32(1, 62));
3308 RUN(testSShrArgs32(1, 33));
3309 RUN(testSShrArgs32(0xffffffff, 0));
3310 RUN(testSShrArgs32(0xffffffff, 1));
3311 RUN(testSShrArgs32(0xffffffff, 63));
3312 RUN(testSShrImms32(1, 0));
3313 RUN(testSShrImms32(1, 1));
3314 RUN(testSShrImms32(1, 62));
3315 RUN(testSShrImms32(1, 33));
3316 RUN(testSShrImms32(0xffffffff, 0));
3317 RUN(testSShrImms32(0xffffffff, 1));
3318 RUN(testSShrImms32(0xffffffff, 63));
3319 RUN(testSShrArgImm32(1, 0));
3320 RUN(testSShrArgImm32(1, 1));
3321 RUN(testSShrArgImm32(1, 62));
3322 RUN(testSShrArgImm32(0xffffffff, 0));
3323 RUN(testSShrArgImm32(0xffffffff, 1));
3324 RUN(testSShrArgImm32(0xffffffff, 63));
3326 RUN(testZShrArgs(1, 0));
3327 RUN(testZShrArgs(1, 1));
3328 RUN(testZShrArgs(1, 62));
3329 RUN(testZShrArgs(0xffffffffffffffff, 0));
3330 RUN(testZShrArgs(0xffffffffffffffff, 1));
3331 RUN(testZShrArgs(0xffffffffffffffff, 63));
3332 RUN(testZShrImms(1, 0));
3333 RUN(testZShrImms(1, 1));
3334 RUN(testZShrImms(1, 62));
3335 RUN(testZShrImms(1, 65));
3336 RUN(testZShrImms(0xffffffffffffffff, 0));
3337 RUN(testZShrImms(0xffffffffffffffff, 1));
3338 RUN(testZShrImms(0xffffffffffffffff, 63));
3339 RUN(testZShrArgImm(1, 0));
3340 RUN(testZShrArgImm(1, 1));
3341 RUN(testZShrArgImm(1, 62));
3342 RUN(testZShrArgImm(1, 65));
3343 RUN(testZShrArgImm(0xffffffffffffffff, 0));
3344 RUN(testZShrArgImm(0xffffffffffffffff, 1));
3345 RUN(testZShrArgImm(0xffffffffffffffff, 63));
3346 RUN(testZShrArg32(32));
3347 RUN(testZShrArgs32(1, 0));
3348 RUN(testZShrArgs32(1, 1));
3349 RUN(testZShrArgs32(1, 62));
3350 RUN(testZShrArgs32(1, 33));
3351 RUN(testZShrArgs32(0xffffffff, 0));
3352 RUN(testZShrArgs32(0xffffffff, 1));
3353 RUN(testZShrArgs32(0xffffffff, 63));
3354 RUN(testZShrImms32(1, 0));
3355 RUN(testZShrImms32(1, 1));
3356 RUN(testZShrImms32(1, 62));
3357 RUN(testZShrImms32(1, 33));
3358 RUN(testZShrImms32(0xffffffff, 0));
3359 RUN(testZShrImms32(0xffffffff, 1));
3360 RUN(testZShrImms32(0xffffffff, 63));
3361 RUN(testZShrArgImm32(1, 0));
3362 RUN(testZShrArgImm32(1, 1));
3363 RUN(testZShrArgImm32(1, 62));
3364 RUN(testZShrArgImm32(0xffffffff, 0));
3365 RUN(testZShrArgImm32(0xffffffff, 1));
3366 RUN(testZShrArgImm32(0xffffffff, 63));
3369 #endif // ENABLE(B3_JIT)