336c82223b2ed91adbf769c00c4b870bb68aa776
[WebKit-https.git] / Source / JavaScriptCore / b3 / testb3_3.cpp
1 /*
2  * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25
26 #include "config.h"
27 #include "testb3.h"
28
29 #if ENABLE(B3_JIT)
30
31 void testBitOrBitOrArgImmImm32(int a, int b, int c)
32 {
33     Procedure proc;
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(),
45             innerBitOr,
46             root->appendNew<Const32Value>(proc, Origin(), c)));
47
48     CHECK(compileAndRun<int>(proc, a) == ((a | b) | c));
49 }
50
51 void testBitOrImmBitOrArgImm32(int a, int b, int c)
52 {
53     Procedure proc;
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),
66             innerBitOr));
67
68     CHECK(compileAndRun<int>(proc, b) == (a | (b | c)));
69 }
70
71 double bitOrDouble(double a, double b)
72 {
73     return bitwise_cast<double>(bitwise_cast<uint64_t>(a) | bitwise_cast<uint64_t>(b));
74 }
75
76 void testBitOrArgDouble(double a)
77 {
78     Procedure proc;
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);
83
84     CHECK(isIdentical(compileAndRun<double>(proc, a), bitOrDouble(a, a)));
85 }
86
87 void testBitOrArgsDouble(double a, double b)
88 {
89     Procedure proc;
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);
95
96     CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitOrDouble(a, b)));
97 }
98
99 void testBitOrArgImmDouble(double a, double b)
100 {
101     Procedure proc;
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);
107
108     CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitOrDouble(a, b)));
109 }
110
111 void testBitOrImmsDouble(double a, double b)
112 {
113     Procedure proc;
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);
119
120     CHECK(isIdentical(compileAndRun<double>(proc), bitOrDouble(a, b)));
121 }
122
123 float bitOrFloat(float a, float b)
124 {
125     return bitwise_cast<float>(bitwise_cast<uint32_t>(a) | bitwise_cast<uint32_t>(b));
126 }
127
128 void testBitOrArgFloat(float a)
129 {
130     Procedure proc;
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);
137
138     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), bitOrFloat(a, a)));
139 }
140
141 void testBitOrArgsFloat(float a, float b)
142 {
143     Procedure proc;
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);
153
154     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitOrFloat(a, b)));
155 }
156
157 void testBitOrArgImmFloat(float a, float b)
158 {
159     Procedure proc;
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);
167
168     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitOrFloat(a, b)));
169 }
170
171 void testBitOrImmsFloat(float a, float b)
172 {
173     Procedure proc;
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);
179
180     CHECK(isIdentical(compileAndRun<float>(proc), bitOrFloat(a, b)));
181 }
182
183 void testBitOrArgsFloatWithUselessDoubleConversion(float a, float b)
184 {
185     Procedure proc;
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);
198
199     double doubleA = a;
200     double doubleB = b;
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));
203 }
204
205 void testBitXorArgs(int64_t a, int64_t b)
206 {
207     Procedure proc;
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)));
215
216     CHECK(compileAndRun<int64_t>(proc, a, b) == (a ^ b));
217 }
218
219 void testBitXorSameArg(int64_t a)
220 {
221     Procedure proc;
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(),
228             argument,
229             argument));
230
231     CHECK(!compileAndRun<int64_t>(proc, a));
232 }
233
234 void testBitXorAndAndArgs(int64_t a, int64_t b, int64_t c)
235 {
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) {
242         Procedure proc;
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(),
255                 andAB,
256                 andAC));
257
258         CHECK_EQ(compileAndRun<int64_t>(proc, a, b, c), ((a & b) ^ (a & c)));
259     }
260 }
261
262 void testBitXorAndSameArgs(int64_t a, int64_t b)
263 {
264     // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
265     // ((a & b) ^ a)
266     // ((b & a) ^ a)
267     // (a ^ (a & b))
268     // (a ^ (b & a))
269     for (int i = 0; i < 4; ++i) {
270         Procedure proc;
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);
279     
280         CHECK_EQ(compileAndRun<int64_t>(proc, a, b), ((a & b) ^ a));
281     }
282 }
283
284 void testBitXorImms(int64_t a, int64_t b)
285 {
286     Procedure proc;
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)));
294
295     CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
296 }
297
298 void testBitXorArgImm(int64_t a, int64_t b)
299 {
300     Procedure proc;
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)));
308
309     CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
310 }
311
312 void testBitXorImmArg(int64_t a, int64_t b)
313 {
314     Procedure proc;
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)));
322
323     CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
324 }
325
326 void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
327 {
328     Procedure proc;
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(),
338             innerBitXor,
339             root->appendNew<Const64Value>(proc, Origin(), c)));
340
341     CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
342 }
343
344 void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
345 {
346     Procedure proc;
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),
357             innerBitXor));
358
359     CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
360 }
361
362 void testBitXorArgs32(int a, int b)
363 {
364     Procedure proc;
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))));
376
377     CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
378 }
379
380 void testBitXorSameArg32(int a)
381 {
382     Procedure proc;
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(),
391             argument,
392             argument));
393
394     CHECK(!compileAndRun<int>(proc, a));
395 }
396
397 void testBitXorImms32(int a, int b)
398 {
399     Procedure proc;
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)));
407
408     CHECK(compileAndRun<int>(proc) == (a ^ b));
409 }
410
411 void testBitXorArgImm32(int a, int b)
412 {
413     Procedure proc;
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)));
423
424     CHECK(compileAndRun<int>(proc, a) == (a ^ b));
425 }
426
427 void testBitXorImmArg32(int a, int b)
428 {
429     Procedure proc;
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))));
439
440     CHECK(compileAndRun<int>(proc, b) == (a ^ b));
441 }
442
443 void testBitXorBitXorArgImmImm32(int a, int b, int c)
444 {
445     Procedure proc;
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(),
457             innerBitXor,
458             root->appendNew<Const32Value>(proc, Origin(), c)));
459
460     CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
461 }
462
463 void testBitXorImmBitXorArgImm32(int a, int b, int c)
464 {
465     Procedure proc;
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),
478             innerBitXor));
479
480     CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
481 }
482
483 void testBitNotArg(int64_t a)
484 {
485     Procedure proc;
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)));
493
494     CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
495 }
496
497 void testBitNotImm(int64_t a)
498 {
499     Procedure proc;
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)));
507
508     CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
509 }
510
511 void testBitNotMem(int64_t a)
512 {
513     Procedure proc;
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),
519         load);
520     root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
521     root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
522
523     int64_t input = a;
524     compileAndRun<int32_t>(proc, &input);
525     CHECK(isIdentical(input, static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
526 }
527
528 void testBitNotArg32(int32_t a)
529 {
530     Procedure proc;
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),
538             argument));
539     CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
540 }
541
542 void testBitNotImm32(int32_t a)
543 {
544     Procedure proc;
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)));
552
553     CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
554 }
555
556 void testBitNotMem32(int32_t a)
557 {
558     Procedure proc;
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),
564         load);
565     root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
566     root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
567
568     int32_t input = a;
569     compileAndRun<int32_t>(proc, &input);
570     CHECK(isIdentical(input, static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
571 }
572
573 void testNotOnBooleanAndBranch32(int64_t a, int64_t b)
574 {
575     Procedure proc;
576     BasicBlock* root = proc.addBlock();
577     BasicBlock* thenCase = proc.addBlock();
578     BasicBlock* elseCase = proc.addBlock();
579
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),
587         argsAreEqual);
588
589     root->appendNewControlValue(
590         proc, Branch, Origin(),
591         argsAreNotEqual,
592         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
593
594     thenCase->appendNewControlValue(
595         proc, Return, Origin(),
596         thenCase->appendNew<Const32Value>(proc, Origin(), 42));
597
598     elseCase->appendNewControlValue(
599         proc, Return, Origin(),
600         elseCase->appendNew<Const32Value>(proc, Origin(), -42));
601
602     int32_t expectedValue = (a != b) ? 42 : -42;
603     CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
604 }
605
606 void testBitNotOnBooleanAndBranch32(int64_t a, int64_t b)
607 {
608     Procedure proc;
609     BasicBlock* root = proc.addBlock();
610     BasicBlock* thenCase = proc.addBlock();
611     BasicBlock* elseCase = proc.addBlock();
612
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),
620         argsAreEqual);
621
622     root->appendNewControlValue(proc, Branch, Origin(),
623         bitNotArgsAreEqual, FrequentedBlock(thenCase), FrequentedBlock(elseCase));
624
625     thenCase->appendNewControlValue(proc, Return, Origin(),
626         thenCase->appendNew<Const32Value>(proc, Origin(), 42));
627
628     elseCase->appendNewControlValue(proc, Return, Origin(),
629         elseCase->appendNew<Const32Value>(proc, Origin(), -42));
630
631     static constexpr int32_t expectedValue = 42;
632     CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
633 }
634
635 void testShlArgs(int64_t a, int64_t b)
636 {
637     Procedure proc;
638     BasicBlock* root = proc.addBlock();
639     root->appendNewControlValue(
640         proc, Return, Origin(),
641         root->appendNew<Value>(
642             proc, Shl, Origin(),
643             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
644             root->appendNew<Value>(
645                 proc, Trunc, Origin(),
646                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
647
648     CHECK(compileAndRun<int64_t>(proc, a, b) == (a << b));
649 }
650
651 void testShlImms(int64_t a, int64_t b)
652 {
653     Procedure proc;
654     BasicBlock* root = proc.addBlock();
655     root->appendNewControlValue(
656         proc, Return, Origin(),
657         root->appendNew<Value>(
658             proc, Shl, Origin(),
659             root->appendNew<Const64Value>(proc, Origin(), a),
660             root->appendNew<Const32Value>(proc, Origin(), b)));
661
662     b = b & 0x3f; // to avoid undefined behaviour below
663     CHECK(compileAndRun<int64_t>(proc) == (a << b));
664 }
665
666 void testShlArgImm(int64_t a, int64_t b)
667 {
668     Procedure proc;
669     BasicBlock* root = proc.addBlock();
670     root->appendNewControlValue(
671         proc, Return, Origin(),
672         root->appendNew<Value>(
673             proc, Shl, Origin(),
674             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
675             root->appendNew<Const32Value>(proc, Origin(), b)));
676
677     b = b & 0x3f; // to avoid undefined behaviour below
678     CHECK(compileAndRun<int64_t>(proc, a) == (a << b));
679 }
680
681 void testShlSShrArgImm(int64_t a, int64_t b)
682 {
683     Procedure proc;
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>(
691             proc, Shl, Origin(),
692             innerShift,
693             constB));
694
695     b = b & 0x3f; // to avoid undefined behaviour below
696     CHECK(compileAndRun<int64_t>(proc, a) == ((a >> b) << b));
697 }
698
699 void testShlArg32(int32_t a)
700 {
701     Procedure proc;
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));
709
710     CHECK(compileAndRun<int32_t>(proc, a) == (a << a));
711 }
712
713 void testShlArgs32(int32_t a, int32_t b)
714 {
715     Procedure proc;
716     BasicBlock* root = proc.addBlock();
717     root->appendNewControlValue(
718         proc, Return, Origin(),
719         root->appendNew<Value>(
720             proc, Shl, Origin(),
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))));
727
728     CHECK(compileAndRun<int32_t>(proc, a, b) == (a << b));
729 }
730
731 void testShlImms32(int32_t a, int32_t b)
732 {
733     Procedure proc;
734     BasicBlock* root = proc.addBlock();
735     root->appendNewControlValue(
736         proc, Return, Origin(),
737         root->appendNew<Value>(
738             proc, Shl, Origin(),
739             root->appendNew<Const32Value>(proc, Origin(), a),
740             root->appendNew<Const32Value>(proc, Origin(), b)));
741
742     b = b & 0x1f; // to avoid undefined behaviour below
743     CHECK(compileAndRun<int32_t>(proc) == (a << b));
744 }
745
746 void testShlArgImm32(int32_t a, int32_t b)
747 {
748     Procedure proc;
749     BasicBlock* root = proc.addBlock();
750     root->appendNewControlValue(
751         proc, Return, Origin(),
752         root->appendNew<Value>(
753             proc, Shl, Origin(),
754             root->appendNew<Value>(
755                 proc, Trunc, Origin(),
756                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
757             root->appendNew<Const32Value>(proc, Origin(), b)));
758
759     b = b & 0x1f; // to avoid undefined behaviour below
760     CHECK(compileAndRun<int32_t>(proc, a) == (a << b));
761 }
762
763 void testShlZShrArgImm32(int32_t a, int32_t b)
764 {
765     Procedure proc;
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>(
775             proc, Shl, Origin(),
776             innerShift,
777             constB));
778
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));
781 }
782
783 static void testSShrArgs(int64_t a, int64_t b)
784 {
785     Procedure proc;
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))));
795
796     CHECK(compileAndRun<int64_t>(proc, a, b) == (a >> b));
797 }
798
799 static void testSShrImms(int64_t a, int64_t b)
800 {
801     Procedure proc;
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)));
809
810     CHECK(compileAndRun<int64_t>(proc) == (a >> b));
811 }
812
813 static void testSShrArgImm(int64_t a, int64_t b)
814 {
815     Procedure proc;
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)));
823
824     CHECK(compileAndRun<int64_t>(proc, a) == (a >> b));
825 }
826
827 static void testSShrArg32(int32_t a)
828 {
829     Procedure proc;
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));
837
838     CHECK(compileAndRun<int32_t>(proc, a) == (a >> (a & 31)));
839 }
840
841 static void testSShrArgs32(int32_t a, int32_t b)
842 {
843     Procedure proc;
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))));
855
856     CHECK(compileAndRun<int32_t>(proc, a, b) == (a >> b));
857 }
858
859 static void testSShrImms32(int32_t a, int32_t b)
860 {
861     Procedure proc;
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)));
869
870     CHECK(compileAndRun<int32_t>(proc) == (a >> b));
871 }
872
873 static void testSShrArgImm32(int32_t a, int32_t b)
874 {
875     Procedure proc;
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)));
885
886     CHECK(compileAndRun<int32_t>(proc, a) == (a >> b));
887 }
888
889 static void testZShrArgs(uint64_t a, uint64_t b)
890 {
891     Procedure proc;
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))));
901
902     CHECK(compileAndRun<uint64_t>(proc, a, b) == (a >> b));
903 }
904
905 static void testZShrImms(uint64_t a, uint64_t b)
906 {
907     Procedure proc;
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)));
915
916     CHECK(compileAndRun<uint64_t>(proc) == (a >> b));
917 }
918
919 static void testZShrArgImm(uint64_t a, uint64_t b)
920 {
921     Procedure proc;
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)));
929
930     CHECK(compileAndRun<uint64_t>(proc, a) == (a >> b));
931 }
932
933 static void testZShrArg32(uint32_t a)
934 {
935     Procedure proc;
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));
943
944     CHECK(compileAndRun<uint32_t>(proc, a) == (a >> (a & 31)));
945 }
946
947 static void testZShrArgs32(uint32_t a, uint32_t b)
948 {
949     Procedure proc;
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))));
961
962     CHECK(compileAndRun<uint32_t>(proc, a, b) == (a >> b));
963 }
964
965 static void testZShrImms32(uint32_t a, uint32_t b)
966 {
967     Procedure proc;
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)));
975
976     CHECK(compileAndRun<uint32_t>(proc) == (a >> b));
977 }
978
979 static void testZShrArgImm32(uint32_t a, uint32_t b)
980 {
981     Procedure proc;
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)));
991
992     CHECK(compileAndRun<uint32_t>(proc, a) == (a >> b));
993 }
994
995 template<typename IntegerType>
996 static unsigned countLeadingZero(IntegerType value)
997 {
998     unsigned bitCount = sizeof(IntegerType) * 8;
999     if (!value)
1000         return bitCount;
1001
1002     unsigned counter = 0;
1003     while (!(static_cast<uint64_t>(value) & (1l << (bitCount - 1)))) {
1004         value <<= 1;
1005         ++counter;
1006     }
1007     return counter;
1008 }
1009
1010 void testClzArg64(int64_t a)
1011 {
1012     Procedure proc;
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));
1018 }
1019
1020 void testClzMem64(int64_t a)
1021 {
1022     Procedure proc;
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));
1029 }
1030
1031 void testClzArg32(int32_t a)
1032 {
1033     Procedure proc;
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));
1040 }
1041
1042 void testClzMem32(int32_t a)
1043 {
1044     Procedure proc;
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));
1051 }
1052
1053 void testAbsArg(double a)
1054 {
1055     Procedure proc;
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)));
1062
1063     CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
1064 }
1065
1066 void testAbsImm(double a)
1067 {
1068     Procedure proc;
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));
1074
1075     CHECK(isIdentical(compileAndRun<double>(proc), fabs(a)));
1076 }
1077
1078 void testAbsMem(double a)
1079 {
1080     Procedure proc;
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));
1087
1088     CHECK(isIdentical(compileAndRun<double>(proc, &a), fabs(a)));
1089 }
1090
1091 void testAbsAbsArg(double a)
1092 {
1093     Procedure proc;
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);
1099
1100     CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(fabs(a))));
1101 }
1102
1103 void testAbsNegArg(double a)
1104 {
1105     Procedure proc;
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);
1111
1112     CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(- a)));
1113 }
1114
1115 void testAbsBitwiseCastArg(double a)
1116 {
1117     Procedure proc;
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);
1123
1124     CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int64_t>(a)), fabs(a)));
1125 }
1126
1127 void testBitwiseCastAbsBitwiseCastArg(double a)
1128 {
1129     Procedure proc;
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);
1135
1136     root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
1137
1138     int64_t expectedResult = bitwise_cast<int64_t>(fabs(a));
1139     CHECK(isIdentical(compileAndRun<int64_t>(proc, bitwise_cast<int64_t>(a)), expectedResult));
1140 }
1141
1142 void testAbsArg(float a)
1143 {
1144     Procedure proc;
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);
1152
1153     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1154 }
1155
1156 void testAbsImm(float a)
1157 {
1158     Procedure proc;
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);
1164
1165     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1166 }
1167
1168 void testAbsMem(float a)
1169 {
1170     Procedure proc;
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);
1177
1178     CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1179 }
1180
1181 void testAbsAbsArg(float a)
1182 {
1183     Procedure proc;
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);
1191
1192     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(fabs(a)))));
1193 }
1194
1195 void testAbsNegArg(float a)
1196 {
1197     Procedure proc;
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);
1205
1206     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(- a))));
1207 }
1208
1209 void testAbsBitwiseCastArg(float a)
1210 {
1211     Procedure proc;
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);
1218
1219     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
1220 }
1221
1222 void testBitwiseCastAbsBitwiseCastArg(float a)
1223 {
1224     Procedure proc;
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);
1231
1232     root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
1233
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));
1236 }
1237
1238 void testAbsArgWithUselessDoubleConversion(float a)
1239 {
1240     Procedure proc;
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);
1250
1251     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1252 }
1253
1254 void testAbsArgWithEffectfulDoubleConversion(float a)
1255 {
1256     Procedure proc;
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);
1268
1269     double effect = 0;
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))));
1273 }
1274
1275 void testCeilArg(double a)
1276 {
1277     Procedure proc;
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)));
1284
1285     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
1286 }
1287
1288 void testCeilImm(double a)
1289 {
1290     Procedure proc;
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));
1296
1297     CHECK(isIdentical(compileAndRun<double>(proc), ceil(a)));
1298 }
1299
1300 void testCeilMem(double a)
1301 {
1302     Procedure proc;
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));
1309
1310     CHECK(isIdentical(compileAndRun<double>(proc, &a), ceil(a)));
1311 }
1312
1313 void testCeilCeilArg(double a)
1314 {
1315     Procedure proc;
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);
1321
1322     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
1323 }
1324
1325 void testFloorCeilArg(double a)
1326 {
1327     Procedure proc;
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);
1333
1334     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
1335 }
1336
1337 void testCeilIToD64(int64_t a)
1338 {
1339     Procedure proc;
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);
1343
1344     root->appendNewControlValue(
1345         proc, Return, Origin(),
1346         root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
1347
1348     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
1349 }
1350
1351 void testCeilIToD32(int64_t a)
1352 {
1353     Procedure proc;
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);
1358
1359     root->appendNewControlValue(
1360         proc, Return, Origin(),
1361         root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
1362
1363     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
1364 }
1365
1366 void testCeilArg(float a)
1367 {
1368     Procedure proc;
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);
1376
1377     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
1378 }
1379
1380 void testCeilImm(float a)
1381 {
1382     Procedure proc;
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);
1388
1389     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
1390 }
1391
1392 void testCeilMem(float a)
1393 {
1394     Procedure proc;
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);
1401
1402     CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(ceilf(a))));
1403 }
1404
1405 void testCeilCeilArg(float a)
1406 {
1407     Procedure proc;
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);
1415
1416     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
1417 }
1418
1419 void testFloorCeilArg(float a)
1420 {
1421     Procedure proc;
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);
1429
1430     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
1431 }
1432
1433 void testCeilArgWithUselessDoubleConversion(float a)
1434 {
1435     Procedure proc;
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);
1445
1446     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
1447 }
1448
1449 void testCeilArgWithEffectfulDoubleConversion(float a)
1450 {
1451     Procedure proc;
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);
1463
1464     double effect = 0;
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))));
1468 }
1469
1470 void testFloorArg(double a)
1471 {
1472     Procedure proc;
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)));
1479
1480     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
1481 }
1482
1483 void testFloorImm(double a)
1484 {
1485     Procedure proc;
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));
1491
1492     CHECK(isIdentical(compileAndRun<double>(proc), floor(a)));
1493 }
1494
1495 void testFloorMem(double a)
1496 {
1497     Procedure proc;
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));
1504
1505     CHECK(isIdentical(compileAndRun<double>(proc, &a), floor(a)));
1506 }
1507
1508 void testFloorFloorArg(double a)
1509 {
1510     Procedure proc;
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);
1516
1517     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
1518 }
1519
1520 void testCeilFloorArg(double a)
1521 {
1522     Procedure proc;
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);
1528
1529     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
1530 }
1531
1532 void testFloorIToD64(int64_t a)
1533 {
1534     Procedure proc;
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);
1538
1539     root->appendNewControlValue(
1540         proc, Return, Origin(),
1541         root->appendNew<Value>(proc, Floor, Origin(), argumentAsDouble));
1542
1543     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(static_cast<double>(a))));
1544 }
1545
1546 void testFloorIToD32(int64_t a)
1547 {
1548     Procedure proc;
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);
1553
1554     root->appendNewControlValue(
1555         proc, Return, Origin(),
1556         root->appendNew<Value>(proc, Floor, Origin(), argumentAsDouble));
1557
1558     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(static_cast<double>(a))));
1559 }
1560
1561 void testFloorArg(float a)
1562 {
1563     Procedure proc;
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);
1571
1572     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
1573 }
1574
1575 void testFloorImm(float a)
1576 {
1577     Procedure proc;
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);
1583
1584     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
1585 }
1586
1587 void testFloorMem(float a)
1588 {
1589     Procedure proc;
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);
1596
1597     CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(floorf(a))));
1598 }
1599
1600 void testFloorFloorArg(float a)
1601 {
1602     Procedure proc;
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);
1610
1611     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), floorf(a)));
1612 }
1613
1614 void testCeilFloorArg(float a)
1615 {
1616     Procedure proc;
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);
1624
1625     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), floorf(a)));
1626 }
1627
1628 void testFloorArgWithUselessDoubleConversion(float a)
1629 {
1630     Procedure proc;
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);
1640
1641     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
1642 }
1643
1644 void testFloorArgWithEffectfulDoubleConversion(float a)
1645 {
1646     Procedure proc;
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);
1658
1659     double effect = 0;
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))));
1663 }
1664
1665 double correctSqrt(double value)
1666 {
1667 #if CPU(X86) || CPU(X86_64)
1668     double result;
1669     asm ("sqrtsd %1, %0" : "=x"(result) : "x"(value));
1670     return result;
1671 #else    
1672     return sqrt(value);
1673 #endif
1674 }
1675
1676 void testSqrtArg(double a)
1677 {
1678     Procedure proc;
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)));
1685
1686     CHECK(isIdentical(compileAndRun<double>(proc, a), correctSqrt(a)));
1687 }
1688
1689 void testSqrtImm(double a)
1690 {
1691     Procedure proc;
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));
1697
1698     CHECK(isIdentical(compileAndRun<double>(proc), correctSqrt(a)));
1699 }
1700
1701 void testSqrtMem(double a)
1702 {
1703     Procedure proc;
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));
1710
1711     CHECK(isIdentical(compileAndRun<double>(proc, &a), correctSqrt(a)));
1712 }
1713
1714 void testSqrtArg(float a)
1715 {
1716     Procedure proc;
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);
1724
1725     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1726 }
1727
1728 void testSqrtImm(float a)
1729 {
1730     Procedure proc;
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);
1736
1737     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1738 }
1739
1740 void testSqrtMem(float a)
1741 {
1742     Procedure proc;
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);
1749
1750     CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1751 }
1752
1753 void testSqrtArgWithUselessDoubleConversion(float a)
1754 {
1755     Procedure proc;
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);
1765
1766     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1767 }
1768
1769 void testSqrtArgWithEffectfulDoubleConversion(float a)
1770 {
1771     Procedure proc;
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);
1783
1784     double effect = 0;
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));
1789 }
1790
1791 void testCompareTwoFloatToDouble(float a, float b)
1792 {
1793     Procedure proc;
1794     BasicBlock* root = proc.addBlock();
1795
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);
1800
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);
1806
1807     root->appendNewControlValue(proc, Return, Origin(), equal);
1808
1809     CHECK(compileAndRun<int64_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)) == (a == b));
1810 }
1811
1812 void testCompareOneFloatToDouble(float a, double b)
1813 {
1814     Procedure proc;
1815     BasicBlock* root = proc.addBlock();
1816
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);
1821
1822     Value* arg2AsDouble = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1823     Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg1AsDouble, arg2AsDouble);
1824
1825     root->appendNewControlValue(proc, Return, Origin(), equal);
1826
1827     CHECK(compileAndRun<int64_t>(proc, bitwise_cast<int32_t>(a), b) == (a == b));
1828 }
1829
1830 void testCompareFloatToDoubleThroughPhi(float a, float b)
1831 {
1832     Procedure proc;
1833     BasicBlock* root = proc.addBlock();
1834     BasicBlock* thenCase = proc.addBlock();
1835     BasicBlock* elseCase = proc.addBlock();
1836     BasicBlock* tail = proc.addBlock();
1837
1838     Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1839
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);
1844
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);
1848
1849     root->appendNewControlValue(
1850         proc, Branch, Origin(),
1851         condition,
1852         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1853
1854     UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), arg1AsDouble);
1855     thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1856
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));
1860
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);
1866
1867     auto code = compileProc(proc);
1868     int32_t integerA = bitwise_cast<int32_t>(a);
1869     double doubleB = b;
1870     CHECK(invoke<int64_t>(*code, 1, integerA, doubleB) == (a == b));
1871     CHECK(invoke<int64_t>(*code, 0, integerA, doubleB) == (b == 0));
1872 }
1873
1874 void testDoubleToFloatThroughPhi(float value)
1875 {
1876     // Simple case of:
1877     //     if (a) {
1878     //         x = DoubleAdd(a, b)
1879     //     else
1880     //         x = DoubleAdd(a, c)
1881     //     DoubleToFloat(x)
1882     //
1883     // Both Adds can be converted to float add.
1884     Procedure proc;
1885     BasicBlock* root = proc.addBlock();
1886     BasicBlock* thenCase = proc.addBlock();
1887     BasicBlock* elseCase = proc.addBlock();
1888     BasicBlock* tail = proc.addBlock();
1889
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);
1895
1896     root->appendNewControlValue(
1897         proc, Branch, Origin(),
1898         condition,
1899         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1900
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));
1905
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));
1909
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);
1915
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)));
1919 }
1920
1921 void testReduceFloatToDoubleValidates()
1922 {
1923     // Simple case of:
1924     //     f = DoubleToFloat(Bitcast(argGPR0))
1925     //     if (a) {
1926     //         x = FloatConst()
1927     //     else
1928     //         x = FloatConst()
1929     //     p = Phi(x)
1930     //     a = Mul(p, p)
1931     //     b = Add(a, f)
1932     //     c = Add(p, b)
1933     //     Return(c)
1934     //
1935     // This should not crash in the validator after ReduceFloatToDouble.
1936     Procedure proc;
1937     BasicBlock* root = proc.addBlock();
1938     BasicBlock* thenCase = proc.addBlock();
1939     BasicBlock* elseCase = proc.addBlock();
1940     BasicBlock* tail = proc.addBlock();
1941
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(),
1947         condition,
1948         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1949
1950     UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(),
1951         thenCase->appendNew<ConstFloatValue>(proc, Origin(), 11.5));
1952     thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1953
1954     UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), 
1955         elseCase->appendNew<ConstFloatValue>(proc, Origin(), 10.5));
1956     elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1957
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(), 
1962             phi, phi);
1963     result = tail->appendNew<Value>(proc, Add, Origin(), 
1964             result,
1965             thingy);
1966     result = tail->appendNew<Value>(proc, Add, Origin(), 
1967             phi,
1968             result);
1969     tail->appendNewControlValue(proc, Return, Origin(), result);
1970
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));
1974 }
1975
1976 void testDoubleProducerPhiToFloatConversion(float value)
1977 {
1978     Procedure proc;
1979     BasicBlock* root = proc.addBlock();
1980     BasicBlock* thenCase = proc.addBlock();
1981     BasicBlock* elseCase = proc.addBlock();
1982     BasicBlock* tail = proc.addBlock();
1983
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);
1988
1989     root->appendNewControlValue(
1990         proc, Branch, Origin(),
1991         condition,
1992         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1993
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));
1997
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));
2001
2002     Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
2003     thenValue->setPhi(doubleInput);
2004     elseValue->setPhi(doubleInput);
2005
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);
2010
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));
2014 }
2015
2016 void testDoubleProducerPhiToFloatConversionWithDoubleConsumer(float value)
2017 {
2018     // In this case, the Upsilon-Phi effectively contains a Float value, but it is used
2019     // as a Float and as a Double.
2020     Procedure proc;
2021     BasicBlock* root = proc.addBlock();
2022     BasicBlock* thenCase = proc.addBlock();
2023     BasicBlock* elseCase = proc.addBlock();
2024     BasicBlock* tail = proc.addBlock();
2025
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);
2030
2031     root->appendNewControlValue(
2032         proc, Branch, Origin(),
2033         condition,
2034         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2035
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));
2039
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));
2043
2044     Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
2045     thenValue->setPhi(doubleInput);
2046     elseValue->setPhi(doubleInput);
2047
2048     Value* argAsDoubleAgain = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2049     Value* floatAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, argAsDoubleAgain);
2050
2051     // FRound.
2052     Value* floatResult = tail->appendNew<Value>(proc, DoubleToFloat, Origin(), floatAdd);
2053     Value* doubleResult = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatResult);
2054
2055     // This one *cannot* be eliminated
2056     Value* doubleAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, doubleResult);
2057
2058     tail->appendNewControlValue(proc, Return, Origin(), doubleAdd);
2059
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)));
2063 }
2064
2065 void testDoubleProducerPhiWithNonFloatConst(float value, double constValue)
2066 {
2067     Procedure proc;
2068     BasicBlock* root = proc.addBlock();
2069     BasicBlock* thenCase = proc.addBlock();
2070     BasicBlock* elseCase = proc.addBlock();
2071     BasicBlock* tail = proc.addBlock();
2072
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);
2077
2078     root->appendNewControlValue(
2079         proc, Branch, Origin(),
2080         condition,
2081         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2082
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));
2086
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));
2090
2091     Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
2092     thenValue->setPhi(doubleInput);
2093     elseValue->setPhi(doubleInput);
2094
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);
2099
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)));
2103 }
2104
2105 void testDoubleArgToInt64BitwiseCast(double value)
2106 {
2107     Procedure proc;
2108     BasicBlock* root = proc.addBlock();
2109     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2110
2111     root->appendNewControlValue(
2112         proc, Return, Origin(),
2113         root->appendNew<Value>(
2114             proc, BitwiseCast, Origin(), argument));
2115
2116     CHECK(isIdentical(compileAndRun<int64_t>(proc, value), bitwise_cast<int64_t>(value)));
2117 }
2118
2119 void testDoubleImmToInt64BitwiseCast(double value)
2120 {
2121     Procedure proc;
2122     BasicBlock* root = proc.addBlock();
2123     Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
2124
2125     root->appendNewControlValue(
2126         proc, Return, Origin(),
2127         root->appendNew<Value>(
2128             proc, BitwiseCast, Origin(), argument));
2129
2130     CHECK(isIdentical(compileAndRun<int64_t>(proc), bitwise_cast<int64_t>(value)));
2131 }
2132
2133 void testTwoBitwiseCastOnDouble(double value)
2134 {
2135     Procedure proc;
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);
2141
2142     CHECK(isIdentical(compileAndRun<double>(proc, value), value));
2143 }
2144
2145 void testBitwiseCastOnDoubleInMemory(double value)
2146 {
2147     Procedure proc;
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);
2153
2154     CHECK(isIdentical(compileAndRun<int64_t>(proc, &value), bitwise_cast<int64_t>(value)));
2155 }
2156
2157 void testBitwiseCastOnDoubleInMemoryIndexed(double value)
2158 {
2159     Procedure proc;
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(),
2164         offset,
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);
2170
2171     CHECK(isIdentical(compileAndRun<int64_t>(proc, &value, 0), bitwise_cast<int64_t>(value)));
2172 }
2173
2174 void testInt64BArgToDoubleBitwiseCast(int64_t value)
2175 {
2176     Procedure proc;
2177     BasicBlock* root = proc.addBlock();
2178     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2179
2180     root->appendNewControlValue(
2181         proc, Return, Origin(),
2182         root->appendNew<Value>(
2183             proc, BitwiseCast, Origin(), argument));
2184
2185     CHECK(isIdentical(compileAndRun<double>(proc, value), bitwise_cast<double>(value)));
2186 }
2187
2188 void testInt64BImmToDoubleBitwiseCast(int64_t value)
2189 {
2190     Procedure proc;
2191     BasicBlock* root = proc.addBlock();
2192     Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
2193
2194     root->appendNewControlValue(
2195         proc, Return, Origin(),
2196         root->appendNew<Value>(
2197             proc, BitwiseCast, Origin(), argument));
2198
2199     CHECK(isIdentical(compileAndRun<double>(proc), bitwise_cast<double>(value)));
2200 }
2201
2202 void testTwoBitwiseCastOnInt64(int64_t value)
2203 {
2204     Procedure proc;
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);
2210
2211     CHECK(isIdentical(compileAndRun<int64_t>(proc, value), value));
2212 }
2213
2214 void testBitwiseCastOnInt64InMemory(int64_t value)
2215 {
2216     Procedure proc;
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);
2222
2223     CHECK(isIdentical(compileAndRun<double>(proc, &value), bitwise_cast<double>(value)));
2224 }
2225
2226 void testBitwiseCastOnInt64InMemoryIndexed(int64_t value)
2227 {
2228     Procedure proc;
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(),
2233         offset,
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);
2239
2240     CHECK(isIdentical(compileAndRun<double>(proc, &value, 0), bitwise_cast<double>(value)));
2241 }
2242
2243 void testFloatImmToInt32BitwiseCast(float value)
2244 {
2245     Procedure proc;
2246     BasicBlock* root = proc.addBlock();
2247     Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), value);
2248
2249     root->appendNewControlValue(
2250         proc, Return, Origin(),
2251         root->appendNew<Value>(
2252             proc, BitwiseCast, Origin(), argument));
2253
2254     CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(value)));
2255 }
2256
2257 void testBitwiseCastOnFloatInMemory(float value)
2258 {
2259     Procedure proc;
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);
2265
2266     CHECK(isIdentical(compileAndRun<int32_t>(proc, &value), bitwise_cast<int32_t>(value)));
2267 }
2268
2269 void testInt32BArgToFloatBitwiseCast(int32_t value)
2270 {
2271     Procedure proc;
2272     BasicBlock* root = proc.addBlock();
2273     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2274
2275     root->appendNewControlValue(
2276         proc, Return, Origin(),
2277         root->appendNew<Value>(
2278             proc, BitwiseCast, Origin(), argument));
2279
2280     CHECK(isIdentical(compileAndRun<float>(proc, value), bitwise_cast<float>(value)));
2281 }
2282
2283 void testInt32BImmToFloatBitwiseCast(int32_t value)
2284 {
2285     Procedure proc;
2286     BasicBlock* root = proc.addBlock();
2287     Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
2288
2289     root->appendNewControlValue(
2290         proc, Return, Origin(),
2291         root->appendNew<Value>(
2292             proc, BitwiseCast, Origin(), argument));
2293
2294     CHECK(isIdentical(compileAndRun<float>(proc), bitwise_cast<float>(value)));
2295 }
2296
2297 void testTwoBitwiseCastOnInt32(int32_t value)
2298 {
2299     Procedure proc;
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);
2305
2306     CHECK(isIdentical(compileAndRun<int32_t>(proc, value), value));
2307 }
2308
2309 void testBitwiseCastOnInt32InMemory(int32_t value)
2310 {
2311     Procedure proc;
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);
2317
2318     CHECK(isIdentical(compileAndRun<float>(proc, &value), bitwise_cast<float>(value)));
2319 }
2320
2321 void testConvertDoubleToFloatArg(double value)
2322 {
2323     Procedure proc;
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);
2328
2329     CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
2330 }
2331
2332 void testConvertDoubleToFloatImm(double value)
2333 {
2334     Procedure proc;
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);
2339
2340     CHECK(isIdentical(compileAndRun<float>(proc), static_cast<float>(value)));
2341 }
2342
2343 void testConvertDoubleToFloatMem(double value)
2344 {
2345     Procedure proc;
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);
2351
2352     CHECK(isIdentical(compileAndRun<float>(proc, &value), static_cast<float>(value)));
2353 }
2354
2355 void testConvertFloatToDoubleArg(float value)
2356 {
2357     Procedure proc;
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);
2364
2365     CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int32_t>(value)), static_cast<double>(value)));
2366 }
2367
2368 void testConvertFloatToDoubleImm(float value)
2369 {
2370     Procedure proc;
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);
2375
2376     CHECK(isIdentical(compileAndRun<double>(proc), static_cast<double>(value)));
2377 }
2378
2379 void testConvertFloatToDoubleMem(float value)
2380 {
2381     Procedure proc;
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);
2387
2388     CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(value)));
2389 }
2390
2391 void testConvertDoubleToFloatToDoubleToFloat(double value)
2392 {
2393     Procedure proc;
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);
2400
2401     CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
2402 }
2403
2404 void testLoadFloatConvertDoubleConvertFloatStoreFloat(float value)
2405 {
2406     Procedure proc;
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);
2414
2415     root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2416
2417     float input = value;
2418     float output = 0.;
2419     CHECK(!compileAndRun<int64_t>(proc, &input, &output));
2420     CHECK(isIdentical(input, output));
2421 }
2422
2423 void testFroundArg(double value)
2424 {
2425     Procedure proc;
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);
2431
2432     CHECK(isIdentical(compileAndRun<double>(proc, value), static_cast<double>(static_cast<float>(value))));
2433 }
2434
2435 void testFroundMem(double value)
2436 {
2437     Procedure proc;
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);
2444
2445     CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(static_cast<float>(value))));
2446 }
2447
2448 void testIToD64Arg()
2449 {
2450     Procedure proc;
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);
2455
2456     auto code = compileProc(proc);
2457     for (auto testValue : int64Operands())
2458         CHECK(isIdentical(invoke<double>(*code, testValue.value), static_cast<double>(testValue.value)));
2459 }
2460
2461 void testIToF64Arg()
2462 {
2463     Procedure proc;
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);
2468
2469     auto code = compileProc(proc);
2470     for (auto testValue : int64Operands())
2471         CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2472 }
2473
2474 void testIToD32Arg()
2475 {
2476     Procedure proc;
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);
2482
2483     auto code = compileProc(proc);
2484     for (auto testValue : int32Operands())
2485         CHECK(isIdentical(invoke<double>(*code, testValue.value), static_cast<double>(testValue.value)));
2486 }
2487
2488 void testIToF32Arg()
2489 {
2490     Procedure proc;
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);
2496
2497     auto code = compileProc(proc);
2498     for (auto testValue : int32Operands())
2499         CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2500 }
2501
2502 void testIToD64Mem()
2503 {
2504     Procedure proc;
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);
2510
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);
2517     }
2518 }
2519
2520 void testIToF64Mem()
2521 {
2522     Procedure proc;
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);
2528
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);
2535     }
2536 }
2537
2538 void testIToD32Mem()
2539 {
2540     Procedure proc;
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);
2546
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);
2553     }
2554 }
2555
2556 void testIToF32Mem()
2557 {
2558     Procedure proc;
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);
2564
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);
2571     }
2572 }
2573
2574 void testIToD64Imm(int64_t value)
2575 {
2576     Procedure proc;
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)));
2582 }
2583
2584 void testIToF64Imm(int64_t value)
2585 {
2586     Procedure proc;
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)));
2592 }
2593
2594 void testIToD32Imm(int32_t value)
2595 {
2596     Procedure proc;
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)));
2602 }
2603
2604 void testIToF32Imm(int32_t value)
2605 {
2606     Procedure proc;
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)));
2612 }
2613
2614 void testIToDReducedToIToF64Arg()
2615 {
2616     Procedure proc;
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);
2622
2623     auto code = compileProc(proc);
2624     for (auto testValue : int64Operands())
2625         CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2626 }
2627
2628 void testIToDReducedToIToF32Arg()
2629 {
2630     Procedure proc;
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);
2637
2638     auto code = compileProc(proc);
2639     for (auto testValue : int32Operands())
2640         CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2641 }
2642
2643 void testStore32(int value)
2644 {
2645     Procedure proc;
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));
2656
2657     CHECK(!compileAndRun<int>(proc, value));
2658     CHECK(slot == value);
2659 }
2660
2661 void testStoreConstant(int value)
2662 {
2663     Procedure proc;
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));
2672
2673     CHECK(!compileAndRun<int>(proc));
2674     CHECK(slot == value);
2675 }
2676
2677 void testStoreConstantPtr(intptr_t value)
2678 {
2679     Procedure proc;
2680     BasicBlock* root = proc.addBlock();
2681     intptr_t slot;
2682 #if CPU(ADDRESS64)
2683     slot = (static_cast<intptr_t>(0xbaadbeef) << 32) + static_cast<intptr_t>(0xbaadbeef);
2684 #else
2685     slot = 0xbaadbeef;
2686 #endif
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));
2693
2694     CHECK(!compileAndRun<int>(proc));
2695     CHECK(slot == value);
2696 }
2697
2698 void testStore8Arg()
2699 {
2700     { // Direct addressing.
2701         Procedure proc;
2702         BasicBlock* root = proc.addBlock();
2703
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);
2707
2708         root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2709         root->appendNewControlValue(proc, Return, Origin(), value);
2710
2711         int8_t storage = 0;
2712         CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
2713         CHECK(storage == 42);
2714     }
2715
2716     { // Indexed addressing.
2717         Procedure proc;
2718         BasicBlock* root = proc.addBlock();
2719
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);
2725
2726         Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2727         Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2728
2729         root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2730         root->appendNewControlValue(proc, Return, Origin(), value);
2731
2732         int8_t storage = 0;
2733         CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
2734         CHECK(storage == 42);
2735     }
2736 }
2737
2738 void testStore8Imm()
2739 {
2740     { // Direct addressing.
2741         Procedure proc;
2742         BasicBlock* root = proc.addBlock();
2743
2744         Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2745         Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2746
2747         root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2748         root->appendNewControlValue(proc, Return, Origin(), value);
2749
2750         int8_t storage = 0;
2751         CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
2752         CHECK(storage == 42);
2753     }
2754
2755     { // Indexed addressing.
2756         Procedure proc;
2757         BasicBlock* root = proc.addBlock();
2758
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);
2763
2764         Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2765         Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2766
2767         root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2768         root->appendNewControlValue(proc, Return, Origin(), value);
2769
2770         int8_t storage = 0;
2771         CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
2772         CHECK(storage == 42);
2773     }
2774 }
2775
2776 void testStorePartial8BitRegisterOnX86()
2777 {
2778     Procedure proc;
2779     BasicBlock* root = proc.addBlock();
2780
2781     // We want to have this in ECX.
2782     Value* returnValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2783
2784     // We want this suck in EDX.
2785     Value* whereToStore = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2786
2787     // The patch point is there to help us force the hand of the compiler.
2788     PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
2789
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)));
2794
2795     // We'll produce EDI.
2796     patchpoint->resultConstraints = { ValueRep::reg(GPRInfo::regT6) };
2797
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);
2806
2807     // Set EDI.
2808     patchpoint->setGenerator(
2809         [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2810             AllowMacroScratchRegisterUsage allowScratch(jit);
2811             jit.xor64(params[0].gpr(), params[0].gpr());
2812         });
2813
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);
2819
2820     root->appendNewControlValue(proc, Return, Origin(), returnValue);
2821
2822     int8_t storage = 0xff;
2823     CHECK(compileAndRun<int64_t>(proc, 0x12345678abcdef12, &storage) == 0x12345678abcdef12);
2824     CHECK(!storage);
2825 }
2826
2827 void testStore16Arg()
2828 {
2829     { // Direct addressing.
2830         Procedure proc;
2831         BasicBlock* root = proc.addBlock();
2832
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);
2836
2837         root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2838         root->appendNewControlValue(proc, Return, Origin(), value);
2839
2840         int16_t storage = -1;
2841         CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
2842         CHECK(storage == 42);
2843     }
2844
2845     { // Indexed addressing.
2846         Procedure proc;
2847         BasicBlock* root = proc.addBlock();
2848
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);
2854
2855         Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2856         Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2857
2858         root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2859         root->appendNewControlValue(proc, Return, Origin(), value);
2860
2861         int16_t storage = -1;
2862         CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
2863         CHECK(storage == 42);
2864     }
2865 }
2866
2867 void testStore16Imm()
2868 {
2869     { // Direct addressing.
2870         Procedure proc;
2871         BasicBlock* root = proc.addBlock();
2872
2873         Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2874         Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2875
2876         root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2877         root->appendNewControlValue(proc, Return, Origin(), value);
2878
2879         int16_t storage = -1;
2880         CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
2881         CHECK(storage == 42);
2882     }
2883
2884     { // Indexed addressing.
2885         Procedure proc;
2886         BasicBlock* root = proc.addBlock();
2887
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);
2892
2893         Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2894         Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2895
2896         root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2897         root->appendNewControlValue(proc, Return, Origin(), value);
2898
2899         int16_t storage = -1;
2900         CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
2901         CHECK(storage == 42);
2902     }
2903 }
2904
2905 void testTrunc(int64_t value)
2906 {
2907     Procedure proc;
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)));
2914
2915     CHECK(compileAndRun<int>(proc, value) == static_cast<int>(value));
2916 }
2917
2918 void testAdd1(int value)
2919 {
2920     Procedure proc;
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)));
2930
2931     CHECK(compileAndRun<int>(proc, value) == value + 1);
2932 }
2933
2934 void testAdd1Ptr(intptr_t value)
2935 {
2936     Procedure proc;
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)));
2944
2945     CHECK(compileAndRun<intptr_t>(proc, value) == value + 1);
2946 }
2947
2948 void testNeg32(int32_t value)
2949 {
2950     Procedure proc;
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))));
2960
2961     CHECK(compileAndRun<int32_t>(proc, value) == -value);
2962 }
2963
2964 void testNegPtr(intptr_t value)
2965 {
2966     Procedure proc;
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)));
2974
2975     CHECK(compileAndRun<intptr_t>(proc, value) == -value);
2976 }
2977
2978 void testStoreAddLoad32(int amount)
2979 {
2980     Procedure proc;
2981     BasicBlock* root = proc.addBlock();
2982     int slot = 37;
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))),
2992         slotPtr, 0);
2993     root->appendNewControlValue(
2994         proc, Return, Origin(),
2995         root->appendNew<Const32Value>(proc, Origin(), 0));
2996
2997     CHECK(!compileAndRun<int>(proc, amount));
2998     CHECK(slot == 37 + amount);
2999 }
3000
3001 // Make sure the compiler does not try to optimize anything out.
3002 static NEVER_INLINE double zero()
3003 {
3004     return 0.;
3005 }
3006
3007 static double negativeZero()
3008 {
3009     return -zero();
3010 }
3011
3012 void addArgTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3013 {
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());
3037     
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>());
3070     
3071     RUN(testMulArg(5));
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_BINARY(testMulImm32SignExtend, int32Operands(), int32Operands());
3108     RUN(testMulImm32SignExtend(0xFFFFFFFE, 0xFFFFFFFF));
3109     RUN(testMulImm32SignExtend(0xFFFFFFFF, 0xFFFFFFFE));
3110     RUN(testMulArgs32(1, 1));
3111     RUN(testMulArgs32(1, 2));
3112     RUN(testMulArgs32(0xFFFFFFFF, 0xFFFFFFFF));
3113     RUN(testMulArgs32(0xFFFFFFFE, 0xFFFFFFFF));
3114     RUN(testMulArgs32SignExtend(1, 1));
3115     RUN(testMulArgs32SignExtend(1, 2));
3116     RUN(testMulArgs32SignExtend(0xFFFFFFFF, 0xFFFFFFFF));
3117     RUN(testMulArgs32SignExtend(0xFFFFFFFE, 0xFFFFFFFF));
3118     RUN(testMulLoadTwice());
3119     RUN(testMulAddArgsLeft());
3120     RUN(testMulAddArgsRight());
3121     RUN(testMulAddArgsLeft32());
3122     RUN(testMulAddArgsRight32());
3123     RUN(testMulSubArgsLeft());
3124     RUN(testMulSubArgsRight());
3125     RUN(testMulSubArgsLeft32());
3126     RUN(testMulSubArgsRight32());
3127     RUN(testMulNegArgs());
3128     RUN(testMulNegArgs32());
3129     
3130     RUN_BINARY(testMulArgNegArg, int64Operands(), int64Operands())
3131     RUN_BINARY(testMulNegArgArg, int64Operands(), int64Operands())
3132     RUN_UNARY(testMulArgDouble, floatingPointOperands<double>());
3133     RUN_BINARY(testMulArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3134     RUN_BINARY(testMulArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3135     RUN_BINARY(testMulImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3136     RUN_BINARY(testMulImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3137     RUN_UNARY(testMulArgFloat, floatingPointOperands<float>());
3138     RUN_BINARY(testMulArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3139     RUN_BINARY(testMulArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3140     RUN_BINARY(testMulImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3141     RUN_BINARY(testMulImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3142     RUN_UNARY(testMulArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3143     RUN_BINARY(testMulArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3144     RUN_BINARY(testMulArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3145     
3146     RUN(testDivArgDouble(M_PI));
3147     RUN(testDivArgsDouble(M_PI, 1));
3148     RUN(testDivArgsDouble(M_PI, -M_PI));
3149     RUN(testDivArgImmDouble(M_PI, 1));
3150     RUN(testDivArgImmDouble(M_PI, 0));
3151     RUN(testDivArgImmDouble(M_PI, negativeZero()));
3152     RUN(testDivArgImmDouble(0, 0));
3153     RUN(testDivArgImmDouble(0, negativeZero()));
3154     RUN(testDivArgImmDouble(negativeZero(), 0));
3155     RUN(testDivArgImmDouble(negativeZero(), negativeZero()));
3156     RUN(testDivImmArgDouble(M_PI, 1));
3157     RUN(testDivImmArgDouble(M_PI, 0));
3158     RUN(testDivImmArgDouble(M_PI, negativeZero()));
3159     RUN(testDivImmArgDouble(0, 0));
3160     RUN(testDivImmArgDouble(0, negativeZero()));
3161     RUN(testDivImmArgDouble(negativeZero(), 0));
3162     RUN(testDivImmArgDouble(negativeZero(), negativeZero()));
3163     RUN(testDivImmsDouble(M_PI, 1));
3164     RUN(testDivImmsDouble(M_PI, 0));
3165     RUN(testDivImmsDouble(M_PI, negativeZero()));
3166     RUN(testDivImmsDouble(0, 0));
3167     RUN(testDivImmsDouble(0, negativeZero()));
3168     RUN(testDivImmsDouble(negativeZero(), negativeZero()));
3169     RUN_UNARY(testDivArgFloat, floatingPointOperands<float>());
3170     RUN_BINARY(testDivArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3171     RUN_BINARY(testDivArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3172     RUN_BINARY(testDivImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3173     RUN_BINARY(testDivImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3174     RUN_UNARY(testDivArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3175     RUN_BINARY(testDivArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3176     RUN_BINARY(testDivArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3177     
3178     RUN_BINARY(testUDivArgsInt32, int32Operands(), int32Operands());
3179     RUN_BINARY(testUDivArgsInt64, int64Operands(), int64Operands());
3180     
3181     RUN_UNARY(testModArgDouble, floatingPointOperands<double>());
3182     RUN_BINARY(testModArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3183     RUN_BINARY(testModArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3184     RUN_BINARY(testModImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3185     RUN_BINARY(testModImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3186     RUN_UNARY(testModArgFloat, floatingPointOperands<float>());
3187     RUN_BINARY(testModArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3188     RUN_BINARY(testModArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3189     RUN_BINARY(testModImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3190     RUN_BINARY(testModImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3191     
3192     RUN_BINARY(testUModArgsInt32, int32Operands(), int32Operands());
3193     RUN_BINARY(testUModArgsInt64, int64Operands(), int64Operands());
3194     
3195     RUN(testSubArg(24));
3196     RUN(testSubArgs(1, 1));
3197     RUN(testSubArgs(1, 2));
3198     RUN(testSubArgs(13, -42));
3199     RUN(testSubArgs(-13, 42));
3200     RUN(testSubArgImm(1, 1));
3201     RUN(testSubArgImm(1, 2));
3202     RUN(testSubArgImm(13, -42));
3203     RUN(testSubArgImm(-13, 42));
3204     RUN(testSubArgImm(42, 0));
3205     RUN(testSubImmArg(1, 1));
3206     RUN(testSubImmArg(1, 2));
3207     RUN(testSubImmArg(13, -42));
3208     RUN(testSubImmArg(-13, 42));
3209     RUN_BINARY(testSubArgMem, int64Operands(), int64Operands());
3210     RUN_BINARY(testSubMemArg, int64Operands(), int64Operands());
3211     RUN_BINARY(testSubImmMem, int32Operands(), int32Operands());
3212     RUN_BINARY(testSubMemImm, int32Operands(), int32Operands());
3213     RUN_BINARY(testSubNeg, int32Operands(), int32Operands());
3214     RUN_BINARY(testNegSub, int32Operands(), int32Operands());
3215     RUN_UNARY(testNegValueSubOne, int32Operands());
3216     RUN_BINARY(testNegMulArgImm, int64Operands(), int64Operands());
3217     RUN_TERNARY(testSubMulMulArgs, int64Operands(), int64Operands(), int64Operands());
3218     
3219     RUN_TERNARY(testSubSub, int32Operands(), int32Operands(), int32Operands());
3220     RUN_TERNARY(testSubSub2, int32Operands(), int32Operands(), int32Operands());
3221     RUN_TERNARY(testSubAdd, int32Operands(), int32Operands(), int32Operands());
3222     RUN_BINARY(testSubFirstNeg, int32Operands(), int32Operands());
3223     
3224     RUN(testSubArgs32(1, 1));
3225     RUN(testSubArgs32(1, 2));
3226     RUN(testSubArgs32(13, -42));
3227     RUN(testSubArgs32(-13, 42));
3228     RUN(testSubArgImm32(1, 1));
3229     RUN(testSubArgImm32(1, 2));
3230     RUN(testSubArgImm32(13, -42));
3231     RUN(testSubArgImm32(-13, 42));
3232     RUN(testSubImmArg32(1, 1));
3233     RUN(testSubImmArg32(1, 2));
3234     RUN(testSubImmArg32(13, -42));
3235     RUN(testSubImmArg32(-13, 42));
3236     RUN_BINARY(testSubArgMem32, int32Operands(), int32Operands());
3237     RUN_BINARY(testSubMemArg32, int32Operands(), int32Operands());
3238     RUN_BINARY(testSubImmMem32, int32Operands(), int32Operands());
3239     RUN_BINARY(testSubMemImm32, int32Operands(), int32Operands());
3240     RUN_UNARY(testNegValueSubOne32, int64Operands());
3241     
3242     RUN_UNARY(testSubArgDouble, floatingPointOperands<double>());
3243     RUN_BINARY(testSubArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3244     RUN_BINARY(testSubArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3245     RUN_BINARY(testSubImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3246     RUN_BINARY(testSubImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3247     RUN_UNARY(testSubArgFloat, floatingPointOperands<float>());
3248     RUN_BINARY(testSubArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3249     RUN_BINARY(testSubArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3250     RUN_BINARY(testSubImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3251     RUN_BINARY(testSubImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3252     RUN_UNARY(testSubArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3253     RUN_BINARY(testSubArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3254     RUN_BINARY(testSubArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3255 }
3256
3257 void addCallTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3258 {
3259     RUN(testCallSimple(1, 2));
3260     RUN(testCallRare(1, 2));
3261     RUN(testCallRareLive(1, 2, 3));
3262     RUN(testCallSimplePure(1, 2));
3263     RUN(testCallFunctionWithHellaArguments());
3264     RUN(testCallFunctionWithHellaArguments2());
3265     RUN(testCallFunctionWithHellaArguments3());
3266     
3267     RUN(testReturnDouble(0.0));
3268     RUN(testReturnDouble(negativeZero()));
3269     RUN(testReturnDouble(42.5));
3270     RUN_UNARY(testReturnFloat, floatingPointOperands<float>());
3271     
3272     RUN(testCallSimpleDouble(1, 2));
3273     RUN(testCallFunctionWithHellaDoubleArguments());
3274     RUN_BINARY(testCallSimpleFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3275     RUN(testCallFunctionWithHellaFloatArguments());
3276 }
3277
3278 void addShrTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3279 {
3280     RUN(testSShrArgs(1, 0));
3281     RUN(testSShrArgs(1, 1));
3282     RUN(testSShrArgs(1, 62));
3283     RUN(testSShrArgs(0xffffffffffffffff, 0));
3284     RUN(testSShrArgs(0xffffffffffffffff, 1));
3285     RUN(testSShrArgs(0xffffffffffffffff, 63));
3286     RUN(testSShrImms(1, 0));
3287     RUN(testSShrImms(1, 1));
3288     RUN(testSShrImms(1, 62));
3289     RUN(testSShrImms(1, 65));
3290     RUN(testSShrImms(0xffffffffffffffff, 0));
3291     RUN(testSShrImms(0xffffffffffffffff, 1));
3292     RUN(testSShrImms(0xffffffffffffffff, 63));
3293     RUN(testSShrArgImm(1, 0));
3294     RUN(testSShrArgImm(1, 1));
3295     RUN(testSShrArgImm(1, 62));
3296     RUN(testSShrArgImm(1, 65));
3297     RUN(testSShrArgImm(0xffffffffffffffff, 0));
3298     RUN(testSShrArgImm(0xffffffffffffffff, 1));
3299     RUN(testSShrArgImm(0xffffffffffffffff, 63));
3300     RUN(testSShrArg32(32));
3301     RUN(testSShrArgs32(1, 0));
3302     RUN(testSShrArgs32(1, 1));
3303     RUN(testSShrArgs32(1, 62));
3304     RUN(testSShrArgs32(1, 33));
3305     RUN(testSShrArgs32(0xffffffff, 0));
3306     RUN(testSShrArgs32(0xffffffff, 1));
3307     RUN(testSShrArgs32(0xffffffff, 63));
3308     RUN(testSShrImms32(1, 0));
3309     RUN(testSShrImms32(1, 1));
3310     RUN(testSShrImms32(1, 62));
3311     RUN(testSShrImms32(1, 33));
3312     RUN(testSShrImms32(0xffffffff, 0));
3313     RUN(testSShrImms32(0xffffffff, 1));
3314     RUN(testSShrImms32(0xffffffff, 63));
3315     RUN(testSShrArgImm32(1, 0));
3316     RUN(testSShrArgImm32(1, 1));
3317     RUN(testSShrArgImm32(1, 62));
3318     RUN(testSShrArgImm32(0xffffffff, 0));
3319     RUN(testSShrArgImm32(0xffffffff, 1));
3320     RUN(testSShrArgImm32(0xffffffff, 63));
3321     
3322     RUN(testZShrArgs(1, 0));
3323     RUN(testZShrArgs(1, 1));
3324     RUN(testZShrArgs(1, 62));
3325     RUN(testZShrArgs(0xffffffffffffffff, 0));
3326     RUN(testZShrArgs(0xffffffffffffffff, 1));
3327     RUN(testZShrArgs(0xffffffffffffffff, 63));
3328     RUN(testZShrImms(1, 0));
3329     RUN(testZShrImms(1, 1));
3330     RUN(testZShrImms(1, 62));
3331     RUN(testZShrImms(1, 65));
3332     RUN(testZShrImms(0xffffffffffffffff, 0));
3333     RUN(testZShrImms(0xffffffffffffffff, 1));
3334     RUN(testZShrImms(0xffffffffffffffff, 63));
3335     RUN(testZShrArgImm(1, 0));
3336     RUN(testZShrArgImm(1, 1));
3337     RUN(testZShrArgImm(1, 62));
3338     RUN(testZShrArgImm(1, 65));
3339     RUN(testZShrArgImm(0xffffffffffffffff, 0));
3340     RUN(testZShrArgImm(0xffffffffffffffff, 1));
3341     RUN(testZShrArgImm(0xffffffffffffffff, 63));
3342     RUN(testZShrArg32(32));
3343     RUN(testZShrArgs32(1, 0));
3344     RUN(testZShrArgs32(1, 1));
3345     RUN(testZShrArgs32(1, 62));
3346     RUN(testZShrArgs32(1, 33));
3347     RUN(testZShrArgs32(0xffffffff, 0));
3348     RUN(testZShrArgs32(0xffffffff, 1));
3349     RUN(testZShrArgs32(0xffffffff, 63));
3350     RUN(testZShrImms32(1, 0));
3351     RUN(testZShrImms32(1, 1));
3352     RUN(testZShrImms32(1, 62));
3353     RUN(testZShrImms32(1, 33));
3354     RUN(testZShrImms32(0xffffffff, 0));
3355     RUN(testZShrImms32(0xffffffff, 1));
3356     RUN(testZShrImms32(0xffffffff, 63));
3357     RUN(testZShrArgImm32(1, 0));
3358     RUN(testZShrArgImm32(1, 1));
3359     RUN(testZShrArgImm32(1, 62));
3360     RUN(testZShrArgImm32(0xffffffff, 0));
3361     RUN(testZShrArgImm32(0xffffffff, 1));
3362     RUN(testZShrArgImm32(0xffffffff, 63));
3363 }
3364
3365 #endif // ENABLE(B3_JIT)