[JSC] 32bit bitwide operation with all-one (-1) is wrong in B3
[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 testBitXorAndAndArgs32(int32_t a, int32_t b, int32_t c)
263 {
264     // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
265     // ((a & b) ^ (a & c))
266     // ((a & b) ^ (c & a))
267     // ((b & a) ^ (a & c))
268     // ((b & a) ^ (c & a))
269     for (int i = 0; i < 4; ++i) {
270         Procedure proc;
271         BasicBlock* root = proc.addBlock();
272         Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
273         Value* argB = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
274         Value* argC = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
275         Value* andAB = i & 2 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
276             : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
277         Value* andAC = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argC)
278             : root->appendNew<Value>(proc, BitAnd, Origin(), argC, argA);
279         root->appendNewControlValue(
280             proc, Return, Origin(),
281             root->appendNew<Value>(
282                 proc, BitXor, Origin(),
283                 andAB,
284                 andAC));
285
286         CHECK_EQ(compileAndRun<int32_t>(proc, a, b, c), ((a & b) ^ (a & c)));
287     }
288 }
289
290 void testBitXorAndSameArgs(int64_t a, int64_t b)
291 {
292     // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
293     // ((a & b) ^ a)
294     // ((b & a) ^ a)
295     // (a ^ (a & b))
296     // (a ^ (b & a))
297     for (int i = 0; i < 4; ++i) {
298         Procedure proc;
299         BasicBlock* root = proc.addBlock();
300         Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
301         Value* argB = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
302         Value* andAB = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
303             : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
304         Value* result = i & 2 ? root->appendNew<Value>(proc, BitXor, Origin(), andAB, argA)
305             : root->appendNew<Value>(proc, BitXor, Origin(), argA, andAB);
306         root->appendNewControlValue(proc, Return, Origin(), result);
307     
308         CHECK_EQ(compileAndRun<int64_t>(proc, a, b), ((a & b) ^ a));
309     }
310 }
311
312 void testBitXorAndSameArgs32(int32_t a, int32_t b)
313 {
314     // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
315     // ((a & b) ^ a)
316     // ((b & a) ^ a)
317     // (a ^ (a & b))
318     // (a ^ (b & a))
319     for (int i = 0; i < 4; ++i) {
320         Procedure proc;
321         BasicBlock* root = proc.addBlock();
322         Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
323         Value* argB = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
324         Value* andAB = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
325             : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
326         Value* result = i & 2 ? root->appendNew<Value>(proc, BitXor, Origin(), andAB, argA)
327             : root->appendNew<Value>(proc, BitXor, Origin(), argA, andAB);
328         root->appendNewControlValue(proc, Return, Origin(), result);
329
330         CHECK_EQ(compileAndRun<int32_t>(proc, a, b), ((a & b) ^ a));
331     }
332 }
333
334 void testBitXorImms(int64_t a, int64_t b)
335 {
336     Procedure proc;
337     BasicBlock* root = proc.addBlock();
338     root->appendNewControlValue(
339         proc, Return, Origin(),
340         root->appendNew<Value>(
341             proc, BitXor, Origin(),
342             root->appendNew<Const64Value>(proc, Origin(), a),
343             root->appendNew<Const64Value>(proc, Origin(), b)));
344
345     CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
346 }
347
348 void testBitXorArgImm(int64_t a, int64_t b)
349 {
350     Procedure proc;
351     BasicBlock* root = proc.addBlock();
352     root->appendNewControlValue(
353         proc, Return, Origin(),
354         root->appendNew<Value>(
355             proc, BitXor, Origin(),
356             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
357             root->appendNew<Const64Value>(proc, Origin(), b)));
358
359     CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
360 }
361
362 void testBitXorImmArg(int64_t a, int64_t 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<Const64Value>(proc, Origin(), a),
371             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
372
373     CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
374 }
375
376 void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
377 {
378     Procedure proc;
379     BasicBlock* root = proc.addBlock();
380     Value* innerBitXor = root->appendNew<Value>(
381         proc, BitXor, Origin(),
382         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
383         root->appendNew<Const64Value>(proc, Origin(), b));
384     root->appendNewControlValue(
385         proc, Return, Origin(),
386         root->appendNew<Value>(
387             proc, BitXor, Origin(),
388             innerBitXor,
389             root->appendNew<Const64Value>(proc, Origin(), c)));
390
391     CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
392 }
393
394 void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
395 {
396     Procedure proc;
397     BasicBlock* root = proc.addBlock();
398     Value* innerBitXor = root->appendNew<Value>(
399         proc, BitXor, Origin(),
400         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
401         root->appendNew<Const64Value>(proc, Origin(), c));
402     root->appendNewControlValue(
403         proc, Return, Origin(),
404         root->appendNew<Value>(
405             proc, BitXor, Origin(),
406             root->appendNew<Const64Value>(proc, Origin(), a),
407             innerBitXor));
408
409     CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
410 }
411
412 void testBitXorArgs32(int a, int b)
413 {
414     Procedure proc;
415     BasicBlock* root = proc.addBlock();
416     root->appendNewControlValue(
417         proc, Return, Origin(),
418         root->appendNew<Value>(
419             proc, BitXor, Origin(),
420             root->appendNew<Value>(
421                 proc, Trunc, Origin(),
422                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
423             root->appendNew<Value>(
424                 proc, Trunc, Origin(),
425                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
426
427     CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
428 }
429
430 void testBitXorSameArg32(int a)
431 {
432     Procedure proc;
433     BasicBlock* root = proc.addBlock();
434     Value* argument = root->appendNew<Value>(
435         proc, Trunc, Origin(),
436             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
437     root->appendNewControlValue(
438         proc, Return, Origin(),
439         root->appendNew<Value>(
440             proc, BitXor, Origin(),
441             argument,
442             argument));
443
444     CHECK(!compileAndRun<int>(proc, a));
445 }
446
447 void testBitXorImms32(int a, int b)
448 {
449     Procedure proc;
450     BasicBlock* root = proc.addBlock();
451     root->appendNewControlValue(
452         proc, Return, Origin(),
453         root->appendNew<Value>(
454             proc, BitXor, Origin(),
455             root->appendNew<Const32Value>(proc, Origin(), a),
456             root->appendNew<Const32Value>(proc, Origin(), b)));
457
458     CHECK(compileAndRun<int>(proc) == (a ^ b));
459 }
460
461 void testBitXorArgImm32(int a, int b)
462 {
463     Procedure proc;
464     BasicBlock* root = proc.addBlock();
465     root->appendNewControlValue(
466         proc, Return, Origin(),
467         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(), b)));
473
474     CHECK(compileAndRun<int>(proc, a) == (a ^ b));
475 }
476
477 void testBitXorImmArg32(int a, int b)
478 {
479     Procedure proc;
480     BasicBlock* root = proc.addBlock();
481     root->appendNewControlValue(
482         proc, Return, Origin(),
483         root->appendNew<Value>(
484             proc, BitXor, Origin(),
485             root->appendNew<Const32Value>(proc, Origin(), a),
486             root->appendNew<Value>(
487                 proc, Trunc, Origin(),
488                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
489
490     CHECK(compileAndRun<int>(proc, b) == (a ^ b));
491 }
492
493 void testBitXorBitXorArgImmImm32(int a, int b, int c)
494 {
495     Procedure proc;
496     BasicBlock* root = proc.addBlock();
497     Value* innerBitXor = root->appendNew<Value>(
498         proc, BitXor, Origin(),
499         root->appendNew<Value>(
500             proc, Trunc, Origin(),
501             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
502         root->appendNew<Const32Value>(proc, Origin(), b));
503     root->appendNewControlValue(
504         proc, Return, Origin(),
505         root->appendNew<Value>(
506             proc, BitXor, Origin(),
507             innerBitXor,
508             root->appendNew<Const32Value>(proc, Origin(), c)));
509
510     CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
511 }
512
513 void testBitXorImmBitXorArgImm32(int a, int b, int c)
514 {
515     Procedure proc;
516     BasicBlock* root = proc.addBlock();
517     Value* innerBitXor = root->appendNew<Value>(
518         proc, BitXor, Origin(),
519         root->appendNew<Value>(
520             proc, Trunc, Origin(),
521             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
522         root->appendNew<Const32Value>(proc, Origin(), c));
523     root->appendNewControlValue(
524         proc, Return, Origin(),
525         root->appendNew<Value>(
526             proc, BitXor, Origin(),
527             root->appendNew<Const32Value>(proc, Origin(), a),
528             innerBitXor));
529
530     CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
531 }
532
533 void testBitNotArg(int64_t a)
534 {
535     Procedure proc;
536     BasicBlock* root = proc.addBlock();
537     root->appendNewControlValue(
538         proc, Return, Origin(),
539         root->appendNew<Value>(
540             proc, BitXor, Origin(),
541             root->appendNew<Const64Value>(proc, Origin(), -1),
542             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
543
544     CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
545 }
546
547 void testBitNotImm(int64_t a)
548 {
549     Procedure proc;
550     BasicBlock* root = proc.addBlock();
551     root->appendNewControlValue(
552         proc, Return, Origin(),
553         root->appendNew<Value>(
554             proc, BitXor, Origin(),
555             root->appendNew<Const64Value>(proc, Origin(), -1),
556             root->appendNew<Const64Value>(proc, Origin(), a)));
557
558     CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
559 }
560
561 void testBitNotMem(int64_t a)
562 {
563     Procedure proc;
564     BasicBlock* root = proc.addBlock();
565     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
566     MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
567     Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
568         root->appendNew<Const64Value>(proc, Origin(), -1),
569         load);
570     root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
571     root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
572
573     int64_t input = a;
574     compileAndRun<int32_t>(proc, &input);
575     CHECK(isIdentical(input, static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
576 }
577
578 void testBitNotArg32(int32_t a)
579 {
580     Procedure proc;
581     BasicBlock* root = proc.addBlock();
582     Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
583         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
584     root->appendNewControlValue(
585         proc, Return, Origin(),
586         root->appendNew<Value>(proc, BitXor, Origin(),
587             root->appendNew<Const32Value>(proc, Origin(), -1),
588             argument));
589     CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
590 }
591
592 void testBitNotImm32(int32_t a)
593 {
594     Procedure proc;
595     BasicBlock* root = proc.addBlock();
596     root->appendNewControlValue(
597         proc, Return, Origin(),
598         root->appendNew<Value>(
599             proc, BitXor, Origin(),
600             root->appendNew<Const32Value>(proc, Origin(), -1),
601             root->appendNew<Const32Value>(proc, Origin(), a)));
602
603     CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
604 }
605
606 void testBitNotMem32(int32_t a)
607 {
608     Procedure proc;
609     BasicBlock* root = proc.addBlock();
610     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
611     MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
612     Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
613         root->appendNew<Const32Value>(proc, Origin(), -1),
614         load);
615     root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
616     root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
617
618     int32_t input = a;
619     compileAndRun<int32_t>(proc, &input);
620     CHECK(isIdentical(input, static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
621 }
622
623 void testNotOnBooleanAndBranch32(int64_t a, int64_t b)
624 {
625     Procedure proc;
626     BasicBlock* root = proc.addBlock();
627     BasicBlock* thenCase = proc.addBlock();
628     BasicBlock* elseCase = proc.addBlock();
629
630     Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
631         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
632     Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
633         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
634     Value* argsAreEqual = root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2);
635     Value* argsAreNotEqual = root->appendNew<Value>(proc, BitXor, Origin(),
636         root->appendNew<Const32Value>(proc, Origin(), 1),
637         argsAreEqual);
638
639     root->appendNewControlValue(
640         proc, Branch, Origin(),
641         argsAreNotEqual,
642         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
643
644     thenCase->appendNewControlValue(
645         proc, Return, Origin(),
646         thenCase->appendNew<Const32Value>(proc, Origin(), 42));
647
648     elseCase->appendNewControlValue(
649         proc, Return, Origin(),
650         elseCase->appendNew<Const32Value>(proc, Origin(), -42));
651
652     int32_t expectedValue = (a != b) ? 42 : -42;
653     CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
654 }
655
656 void testBitNotOnBooleanAndBranch32(int64_t a, int64_t b)
657 {
658     Procedure proc;
659     BasicBlock* root = proc.addBlock();
660     BasicBlock* thenCase = proc.addBlock();
661     BasicBlock* elseCase = proc.addBlock();
662
663     Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
664         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
665     Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
666         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
667     Value* argsAreEqual = root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2);
668     Value* bitNotArgsAreEqual = root->appendNew<Value>(proc, BitXor, Origin(),
669         root->appendNew<Const32Value>(proc, Origin(), -1),
670         argsAreEqual);
671
672     root->appendNewControlValue(proc, Branch, Origin(),
673         bitNotArgsAreEqual, FrequentedBlock(thenCase), FrequentedBlock(elseCase));
674
675     thenCase->appendNewControlValue(proc, Return, Origin(),
676         thenCase->appendNew<Const32Value>(proc, Origin(), 42));
677
678     elseCase->appendNewControlValue(proc, Return, Origin(),
679         elseCase->appendNew<Const32Value>(proc, Origin(), -42));
680
681     static constexpr int32_t expectedValue = 42;
682     CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
683 }
684
685 void testShlArgs(int64_t a, int64_t b)
686 {
687     Procedure proc;
688     BasicBlock* root = proc.addBlock();
689     root->appendNewControlValue(
690         proc, Return, Origin(),
691         root->appendNew<Value>(
692             proc, Shl, Origin(),
693             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
694             root->appendNew<Value>(
695                 proc, Trunc, Origin(),
696                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
697
698     CHECK(compileAndRun<int64_t>(proc, a, b) == (a << b));
699 }
700
701 void testShlImms(int64_t a, int64_t b)
702 {
703     Procedure proc;
704     BasicBlock* root = proc.addBlock();
705     root->appendNewControlValue(
706         proc, Return, Origin(),
707         root->appendNew<Value>(
708             proc, Shl, Origin(),
709             root->appendNew<Const64Value>(proc, Origin(), a),
710             root->appendNew<Const32Value>(proc, Origin(), b)));
711
712     b = b & 0x3f; // to avoid undefined behaviour below
713     CHECK(compileAndRun<int64_t>(proc) == (a << b));
714 }
715
716 void testShlArgImm(int64_t a, int64_t b)
717 {
718     Procedure proc;
719     BasicBlock* root = proc.addBlock();
720     root->appendNewControlValue(
721         proc, Return, Origin(),
722         root->appendNew<Value>(
723             proc, Shl, Origin(),
724             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
725             root->appendNew<Const32Value>(proc, Origin(), b)));
726
727     b = b & 0x3f; // to avoid undefined behaviour below
728     CHECK(compileAndRun<int64_t>(proc, a) == (a << b));
729 }
730
731 void testShlSShrArgImm(int64_t a, int64_t b)
732 {
733     Procedure proc;
734     BasicBlock* root = proc.addBlock();
735     Value* argA = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
736     Value* constB = root->appendNew<Const32Value>(proc, Origin(), b);
737     Value* innerShift = root->appendNew<Value>(proc, SShr, Origin(), argA, constB);
738     root->appendNewControlValue(
739         proc, Return, Origin(),
740         root->appendNew<Value>(
741             proc, Shl, Origin(),
742             innerShift,
743             constB));
744
745     b = b & 0x3f; // to avoid undefined behaviour below
746     CHECK(compileAndRun<int64_t>(proc, a) == ((a >> b) << b));
747 }
748
749 void testShlArg32(int32_t a)
750 {
751     Procedure proc;
752     BasicBlock* root = proc.addBlock();
753     Value* value = root->appendNew<Value>(
754         proc, Trunc, Origin(),
755         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
756     root->appendNewControlValue(
757         proc, Return, Origin(),
758         root->appendNew<Value>(proc, Shl, Origin(), value, value));
759
760     CHECK(compileAndRun<int32_t>(proc, a) == (a << a));
761 }
762
763 void testShlArgs32(int32_t a, int32_t b)
764 {
765     Procedure proc;
766     BasicBlock* root = proc.addBlock();
767     root->appendNewControlValue(
768         proc, Return, Origin(),
769         root->appendNew<Value>(
770             proc, Shl, Origin(),
771             root->appendNew<Value>(
772                 proc, Trunc, Origin(),
773                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
774             root->appendNew<Value>(
775                 proc, Trunc, Origin(),
776                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
777
778     CHECK(compileAndRun<int32_t>(proc, a, b) == (a << b));
779 }
780
781 void testShlImms32(int32_t a, int32_t b)
782 {
783     Procedure proc;
784     BasicBlock* root = proc.addBlock();
785     root->appendNewControlValue(
786         proc, Return, Origin(),
787         root->appendNew<Value>(
788             proc, Shl, Origin(),
789             root->appendNew<Const32Value>(proc, Origin(), a),
790             root->appendNew<Const32Value>(proc, Origin(), b)));
791
792     b = b & 0x1f; // to avoid undefined behaviour below
793     CHECK(compileAndRun<int32_t>(proc) == (a << b));
794 }
795
796 void testShlArgImm32(int32_t a, int32_t b)
797 {
798     Procedure proc;
799     BasicBlock* root = proc.addBlock();
800     root->appendNewControlValue(
801         proc, Return, Origin(),
802         root->appendNew<Value>(
803             proc, Shl, Origin(),
804             root->appendNew<Value>(
805                 proc, Trunc, Origin(),
806                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
807             root->appendNew<Const32Value>(proc, Origin(), b)));
808
809     b = b & 0x1f; // to avoid undefined behaviour below
810     CHECK(compileAndRun<int32_t>(proc, a) == (a << b));
811 }
812
813 void testShlZShrArgImm32(int32_t a, int32_t b)
814 {
815     Procedure proc;
816     BasicBlock* root = proc.addBlock();
817     Value* argA = root->appendNew<Value>(
818         proc, Trunc, Origin(),
819         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
820     Value* constB = root->appendNew<Const32Value>(proc, Origin(), b);
821     Value* innerShift = root->appendNew<Value>(proc, ZShr, Origin(), argA, constB);
822     root->appendNewControlValue(
823         proc, Return, Origin(),
824         root->appendNew<Value>(
825             proc, Shl, Origin(),
826             innerShift,
827             constB));
828
829     b = b & 0x1f; // to avoid undefined behaviour below
830     CHECK(compileAndRun<int32_t>(proc, a) == static_cast<int32_t>((static_cast<uint32_t>(a) >> b) << b));
831 }
832
833 static void testSShrArgs(int64_t a, int64_t b)
834 {
835     Procedure proc;
836     BasicBlock* root = proc.addBlock();
837     root->appendNewControlValue(
838         proc, Return, Origin(),
839         root->appendNew<Value>(
840             proc, SShr, Origin(),
841             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
842             root->appendNew<Value>(
843                 proc, Trunc, Origin(),
844                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
845
846     CHECK(compileAndRun<int64_t>(proc, a, b) == (a >> b));
847 }
848
849 static void testSShrImms(int64_t a, int64_t b)
850 {
851     Procedure proc;
852     BasicBlock* root = proc.addBlock();
853     root->appendNewControlValue(
854         proc, Return, Origin(),
855         root->appendNew<Value>(
856             proc, SShr, Origin(),
857             root->appendNew<Const64Value>(proc, Origin(), a),
858             root->appendNew<Const32Value>(proc, Origin(), b)));
859
860     CHECK(compileAndRun<int64_t>(proc) == (a >> b));
861 }
862
863 static void testSShrArgImm(int64_t a, int64_t b)
864 {
865     Procedure proc;
866     BasicBlock* root = proc.addBlock();
867     root->appendNewControlValue(
868         proc, Return, Origin(),
869         root->appendNew<Value>(
870             proc, SShr, Origin(),
871             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
872             root->appendNew<Const32Value>(proc, Origin(), b)));
873
874     CHECK(compileAndRun<int64_t>(proc, a) == (a >> b));
875 }
876
877 static void testSShrArg32(int32_t a)
878 {
879     Procedure proc;
880     BasicBlock* root = proc.addBlock();
881     Value* value = root->appendNew<Value>(
882         proc, Trunc, Origin(),
883         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
884     root->appendNewControlValue(
885         proc, Return, Origin(),
886         root->appendNew<Value>(proc, SShr, Origin(), value, value));
887
888     CHECK(compileAndRun<int32_t>(proc, a) == (a >> (a & 31)));
889 }
890
891 static void testSShrArgs32(int32_t a, int32_t b)
892 {
893     Procedure proc;
894     BasicBlock* root = proc.addBlock();
895     root->appendNewControlValue(
896         proc, Return, Origin(),
897         root->appendNew<Value>(
898             proc, SShr, Origin(),
899             root->appendNew<Value>(
900                 proc, Trunc, Origin(),
901                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
902             root->appendNew<Value>(
903                 proc, Trunc, Origin(),
904                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
905
906     CHECK(compileAndRun<int32_t>(proc, a, b) == (a >> b));
907 }
908
909 static void testSShrImms32(int32_t a, int32_t b)
910 {
911     Procedure proc;
912     BasicBlock* root = proc.addBlock();
913     root->appendNewControlValue(
914         proc, Return, Origin(),
915         root->appendNew<Value>(
916             proc, SShr, Origin(),
917             root->appendNew<Const32Value>(proc, Origin(), a),
918             root->appendNew<Const32Value>(proc, Origin(), b)));
919
920     CHECK(compileAndRun<int32_t>(proc) == (a >> b));
921 }
922
923 static void testSShrArgImm32(int32_t a, int32_t b)
924 {
925     Procedure proc;
926     BasicBlock* root = proc.addBlock();
927     root->appendNewControlValue(
928         proc, Return, Origin(),
929         root->appendNew<Value>(
930             proc, SShr, Origin(),
931             root->appendNew<Value>(
932                 proc, Trunc, Origin(),
933                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
934             root->appendNew<Const32Value>(proc, Origin(), b)));
935
936     CHECK(compileAndRun<int32_t>(proc, a) == (a >> b));
937 }
938
939 static void testZShrArgs(uint64_t a, uint64_t b)
940 {
941     Procedure proc;
942     BasicBlock* root = proc.addBlock();
943     root->appendNewControlValue(
944         proc, Return, Origin(),
945         root->appendNew<Value>(
946             proc, ZShr, Origin(),
947             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
948             root->appendNew<Value>(
949                 proc, Trunc, Origin(),
950                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
951
952     CHECK(compileAndRun<uint64_t>(proc, a, b) == (a >> b));
953 }
954
955 static void testZShrImms(uint64_t a, uint64_t b)
956 {
957     Procedure proc;
958     BasicBlock* root = proc.addBlock();
959     root->appendNewControlValue(
960         proc, Return, Origin(),
961         root->appendNew<Value>(
962             proc, ZShr, Origin(),
963             root->appendNew<Const64Value>(proc, Origin(), a),
964             root->appendNew<Const32Value>(proc, Origin(), b)));
965
966     CHECK(compileAndRun<uint64_t>(proc) == (a >> b));
967 }
968
969 static void testZShrArgImm(uint64_t a, uint64_t b)
970 {
971     Procedure proc;
972     BasicBlock* root = proc.addBlock();
973     root->appendNewControlValue(
974         proc, Return, Origin(),
975         root->appendNew<Value>(
976             proc, ZShr, Origin(),
977             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
978             root->appendNew<Const32Value>(proc, Origin(), b)));
979
980     CHECK(compileAndRun<uint64_t>(proc, a) == (a >> b));
981 }
982
983 static void testZShrArg32(uint32_t a)
984 {
985     Procedure proc;
986     BasicBlock* root = proc.addBlock();
987     Value* value = root->appendNew<Value>(
988         proc, Trunc, Origin(),
989         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
990     root->appendNewControlValue(
991         proc, Return, Origin(),
992         root->appendNew<Value>(proc, ZShr, Origin(), value, value));
993
994     CHECK(compileAndRun<uint32_t>(proc, a) == (a >> (a & 31)));
995 }
996
997 static void testZShrArgs32(uint32_t a, uint32_t b)
998 {
999     Procedure proc;
1000     BasicBlock* root = proc.addBlock();
1001     root->appendNewControlValue(
1002         proc, Return, Origin(),
1003         root->appendNew<Value>(
1004             proc, ZShr, Origin(),
1005             root->appendNew<Value>(
1006                 proc, Trunc, Origin(),
1007                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1008             root->appendNew<Value>(
1009                 proc, Trunc, Origin(),
1010                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1011
1012     CHECK(compileAndRun<uint32_t>(proc, a, b) == (a >> b));
1013 }
1014
1015 static void testZShrImms32(uint32_t a, uint32_t b)
1016 {
1017     Procedure proc;
1018     BasicBlock* root = proc.addBlock();
1019     root->appendNewControlValue(
1020         proc, Return, Origin(),
1021         root->appendNew<Value>(
1022             proc, ZShr, Origin(),
1023             root->appendNew<Const32Value>(proc, Origin(), a),
1024             root->appendNew<Const32Value>(proc, Origin(), b)));
1025
1026     CHECK(compileAndRun<uint32_t>(proc) == (a >> b));
1027 }
1028
1029 static void testZShrArgImm32(uint32_t a, uint32_t b)
1030 {
1031     Procedure proc;
1032     BasicBlock* root = proc.addBlock();
1033     root->appendNewControlValue(
1034         proc, Return, Origin(),
1035         root->appendNew<Value>(
1036             proc, ZShr, Origin(),
1037             root->appendNew<Value>(
1038                 proc, Trunc, Origin(),
1039                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1040             root->appendNew<Const32Value>(proc, Origin(), b)));
1041
1042     CHECK(compileAndRun<uint32_t>(proc, a) == (a >> b));
1043 }
1044
1045 template<typename IntegerType>
1046 static unsigned countLeadingZero(IntegerType value)
1047 {
1048     unsigned bitCount = sizeof(IntegerType) * 8;
1049     if (!value)
1050         return bitCount;
1051
1052     unsigned counter = 0;
1053     while (!(static_cast<uint64_t>(value) & (1l << (bitCount - 1)))) {
1054         value <<= 1;
1055         ++counter;
1056     }
1057     return counter;
1058 }
1059
1060 void testClzArg64(int64_t a)
1061 {
1062     Procedure proc;
1063     BasicBlock* root = proc.addBlock();
1064     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1065     Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
1066     root->appendNewControlValue(proc, Return, Origin(), clzValue);
1067     CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
1068 }
1069
1070 void testClzMem64(int64_t a)
1071 {
1072     Procedure proc;
1073     BasicBlock* root = proc.addBlock();
1074     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1075     MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1076     Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
1077     root->appendNewControlValue(proc, Return, Origin(), clzValue);
1078     CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
1079 }
1080
1081 void testClzArg32(int32_t a)
1082 {
1083     Procedure proc;
1084     BasicBlock* root = proc.addBlock();
1085     Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1086         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1087     Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
1088     root->appendNewControlValue(proc, Return, Origin(), clzValue);
1089     CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
1090 }
1091
1092 void testClzMem32(int32_t a)
1093 {
1094     Procedure proc;
1095     BasicBlock* root = proc.addBlock();
1096     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1097     MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1098     Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
1099     root->appendNewControlValue(proc, Return, Origin(), clzValue);
1100     CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
1101 }
1102
1103 void testAbsArg(double a)
1104 {
1105     Procedure proc;
1106     BasicBlock* root = proc.addBlock();
1107     root->appendNewControlValue(
1108         proc, Return, Origin(),
1109         root->appendNew<Value>(
1110             proc, Abs, Origin(),
1111                 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
1112
1113     CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
1114 }
1115
1116 void testAbsImm(double a)
1117 {
1118     Procedure proc;
1119     BasicBlock* root = proc.addBlock();
1120     Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1121     root->appendNewControlValue(
1122         proc, Return, Origin(),
1123         root->appendNew<Value>(proc, Abs, Origin(), argument));
1124
1125     CHECK(isIdentical(compileAndRun<double>(proc), fabs(a)));
1126 }
1127
1128 void testAbsMem(double a)
1129 {
1130     Procedure proc;
1131     BasicBlock* root = proc.addBlock();
1132     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1133     MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
1134     root->appendNewControlValue(
1135         proc, Return, Origin(),
1136         root->appendNew<Value>(proc, Abs, Origin(), loadDouble));
1137
1138     CHECK(isIdentical(compileAndRun<double>(proc, &a), fabs(a)));
1139 }
1140
1141 void testAbsAbsArg(double a)
1142 {
1143     Procedure proc;
1144     BasicBlock* root = proc.addBlock();
1145     Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(),
1146         root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1147     Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
1148     root->appendNewControlValue(proc, Return, Origin(), secondAbs);
1149
1150     CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(fabs(a))));
1151 }
1152
1153 void testAbsNegArg(double a)
1154 {
1155     Procedure proc;
1156     BasicBlock* root = proc.addBlock();
1157     Value* neg = root->appendNew<Value>(proc, Neg, Origin(),
1158         root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1159     Value* abs = root->appendNew<Value>(proc, Abs, Origin(), neg);
1160     root->appendNewControlValue(proc, Return, Origin(), abs);
1161
1162     CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(- a)));
1163 }
1164
1165 void testAbsBitwiseCastArg(double a)
1166 {
1167     Procedure proc;
1168     BasicBlock* root = proc.addBlock();
1169     Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1170     Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
1171     Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
1172     root->appendNewControlValue(proc, Return, Origin(), absValue);
1173
1174     CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int64_t>(a)), fabs(a)));
1175 }
1176
1177 void testBitwiseCastAbsBitwiseCastArg(double a)
1178 {
1179     Procedure proc;
1180     BasicBlock* root = proc.addBlock();
1181     Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1182     Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
1183     Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
1184     Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
1185
1186     root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
1187
1188     int64_t expectedResult = bitwise_cast<int64_t>(fabs(a));
1189     CHECK(isIdentical(compileAndRun<int64_t>(proc, bitwise_cast<int64_t>(a)), expectedResult));
1190 }
1191
1192 void testAbsArg(float a)
1193 {
1194     Procedure proc;
1195     BasicBlock* root = proc.addBlock();
1196     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1197         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1198     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1199     Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
1200     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1201     root->appendNewControlValue(proc, Return, Origin(), result32);
1202
1203     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1204 }
1205
1206 void testAbsImm(float a)
1207 {
1208     Procedure proc;
1209     BasicBlock* root = proc.addBlock();
1210     Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1211     Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
1212     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1213     root->appendNewControlValue(proc, Return, Origin(), result32);
1214
1215     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1216 }
1217
1218 void testAbsMem(float a)
1219 {
1220     Procedure proc;
1221     BasicBlock* root = proc.addBlock();
1222     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1223     MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
1224     Value* result = root->appendNew<Value>(proc, Abs, Origin(), loadFloat);
1225     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1226     root->appendNewControlValue(proc, Return, Origin(), result32);
1227
1228     CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1229 }
1230
1231 void testAbsAbsArg(float a)
1232 {
1233     Procedure proc;
1234     BasicBlock* root = proc.addBlock();
1235     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1236         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1237     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1238     Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(), argument);
1239     Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
1240     root->appendNewControlValue(proc, Return, Origin(), secondAbs);
1241
1242     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(fabs(a)))));
1243 }
1244
1245 void testAbsNegArg(float a)
1246 {
1247     Procedure proc;
1248     BasicBlock* root = proc.addBlock();
1249     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1250         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1251     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1252     Value* neg = root->appendNew<Value>(proc, Neg, Origin(), argument);
1253     Value* abs = root->appendNew<Value>(proc, Abs, Origin(), neg);
1254     root->appendNewControlValue(proc, Return, Origin(), abs);
1255
1256     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(- a))));
1257 }
1258
1259 void testAbsBitwiseCastArg(float a)
1260 {
1261     Procedure proc;
1262     BasicBlock* root = proc.addBlock();
1263     Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1264         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1265     Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
1266     Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
1267     root->appendNewControlValue(proc, Return, Origin(), absValue);
1268
1269     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
1270 }
1271
1272 void testBitwiseCastAbsBitwiseCastArg(float a)
1273 {
1274     Procedure proc;
1275     BasicBlock* root = proc.addBlock();
1276     Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1277         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1278     Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
1279     Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
1280     Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
1281
1282     root->appendNewControlValue(proc, Return, Origin(), resultAsInt64);
1283
1284     int32_t expectedResult = bitwise_cast<int32_t>(static_cast<float>(fabs(a)));
1285     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), expectedResult));
1286 }
1287
1288 void testAbsArgWithUselessDoubleConversion(float a)
1289 {
1290     Procedure proc;
1291     BasicBlock* root = proc.addBlock();
1292     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1293         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1294     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1295     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1296     Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
1297     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1298     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1299     root->appendNewControlValue(proc, Return, Origin(), result32);
1300
1301     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1302 }
1303
1304 void testAbsArgWithEffectfulDoubleConversion(float a)
1305 {
1306     Procedure proc;
1307     BasicBlock* root = proc.addBlock();
1308     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1309         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1310     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1311     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1312     Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
1313     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1314     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1315     Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1316     root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
1317     root->appendNewControlValue(proc, Return, Origin(), result32);
1318
1319     double effect = 0;
1320     int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
1321     CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
1322     CHECK(isIdentical(effect, static_cast<double>(fabs(a))));
1323 }
1324
1325 void testCeilArg(double a)
1326 {
1327     Procedure proc;
1328     BasicBlock* root = proc.addBlock();
1329     root->appendNewControlValue(
1330         proc, Return, Origin(),
1331         root->appendNew<Value>(
1332             proc, Ceil, Origin(),
1333                 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
1334
1335     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
1336 }
1337
1338 void testCeilImm(double a)
1339 {
1340     Procedure proc;
1341     BasicBlock* root = proc.addBlock();
1342     Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1343     root->appendNewControlValue(
1344         proc, Return, Origin(),
1345         root->appendNew<Value>(proc, Ceil, Origin(), argument));
1346
1347     CHECK(isIdentical(compileAndRun<double>(proc), ceil(a)));
1348 }
1349
1350 void testCeilMem(double a)
1351 {
1352     Procedure proc;
1353     BasicBlock* root = proc.addBlock();
1354     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1355     MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
1356     root->appendNewControlValue(
1357         proc, Return, Origin(),
1358         root->appendNew<Value>(proc, Ceil, Origin(), loadDouble));
1359
1360     CHECK(isIdentical(compileAndRun<double>(proc, &a), ceil(a)));
1361 }
1362
1363 void testCeilCeilArg(double a)
1364 {
1365     Procedure proc;
1366     BasicBlock* root = proc.addBlock();
1367     Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
1368         root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1369     Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
1370     root->appendNewControlValue(proc, Return, Origin(), secondCeil);
1371
1372     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
1373 }
1374
1375 void testFloorCeilArg(double a)
1376 {
1377     Procedure proc;
1378     BasicBlock* root = proc.addBlock();
1379     Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
1380         root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1381     Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
1382     root->appendNewControlValue(proc, Return, Origin(), wrappingFloor);
1383
1384     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
1385 }
1386
1387 void testCeilIToD64(int64_t a)
1388 {
1389     Procedure proc;
1390     BasicBlock* root = proc.addBlock();
1391     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1392     Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
1393
1394     root->appendNewControlValue(
1395         proc, Return, Origin(),
1396         root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
1397
1398     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
1399 }
1400
1401 void testCeilIToD32(int64_t a)
1402 {
1403     Procedure proc;
1404     BasicBlock* root = proc.addBlock();
1405     Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1406         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1407     Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
1408
1409     root->appendNewControlValue(
1410         proc, Return, Origin(),
1411         root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
1412
1413     CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
1414 }
1415
1416 void testCeilArg(float a)
1417 {
1418     Procedure proc;
1419     BasicBlock* root = proc.addBlock();
1420     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1421         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1422     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1423     Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
1424     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1425     root->appendNewControlValue(proc, Return, Origin(), result32);
1426
1427     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
1428 }
1429
1430 void testCeilImm(float a)
1431 {
1432     Procedure proc;
1433     BasicBlock* root = proc.addBlock();
1434     Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1435     Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
1436     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1437     root->appendNewControlValue(proc, Return, Origin(), result32);
1438
1439     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
1440 }
1441
1442 void testCeilMem(float a)
1443 {
1444     Procedure proc;
1445     BasicBlock* root = proc.addBlock();
1446     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1447     MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
1448     Value* result = root->appendNew<Value>(proc, Ceil, Origin(), loadFloat);
1449     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1450     root->appendNewControlValue(proc, Return, Origin(), result32);
1451
1452     CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(ceilf(a))));
1453 }
1454
1455 void testCeilCeilArg(float a)
1456 {
1457     Procedure proc;
1458     BasicBlock* root = proc.addBlock();
1459     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1460         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1461     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1462     Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
1463     Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
1464     root->appendNewControlValue(proc, Return, Origin(), secondCeil);
1465
1466     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
1467 }
1468
1469 void testFloorCeilArg(float a)
1470 {
1471     Procedure proc;
1472     BasicBlock* root = proc.addBlock();
1473     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1474         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1475     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1476     Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
1477     Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
1478     root->appendNewControlValue(proc, Return, Origin(), wrappingFloor);
1479
1480     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
1481 }
1482
1483 void testCeilArgWithUselessDoubleConversion(float a)
1484 {
1485     Procedure proc;
1486     BasicBlock* root = proc.addBlock();
1487     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1488         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1489     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1490     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1491     Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
1492     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1493     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1494     root->appendNewControlValue(proc, Return, Origin(), result32);
1495
1496     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
1497 }
1498
1499 void testCeilArgWithEffectfulDoubleConversion(float a)
1500 {
1501     Procedure proc;
1502     BasicBlock* root = proc.addBlock();
1503     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1504         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1505     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1506     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1507     Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
1508     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1509     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1510     Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1511     root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
1512     root->appendNewControlValue(proc, Return, Origin(), result32);
1513
1514     double effect = 0;
1515     int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
1516     CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(ceilf(a))));
1517     CHECK(isIdentical(effect, static_cast<double>(ceilf(a))));
1518 }
1519
1520 void testFloorArg(double a)
1521 {
1522     Procedure proc;
1523     BasicBlock* root = proc.addBlock();
1524     root->appendNewControlValue(
1525         proc, Return, Origin(),
1526         root->appendNew<Value>(
1527             proc, Floor, Origin(),
1528                 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
1529
1530     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
1531 }
1532
1533 void testFloorImm(double a)
1534 {
1535     Procedure proc;
1536     BasicBlock* root = proc.addBlock();
1537     Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1538     root->appendNewControlValue(
1539         proc, Return, Origin(),
1540         root->appendNew<Value>(proc, Floor, Origin(), argument));
1541
1542     CHECK(isIdentical(compileAndRun<double>(proc), floor(a)));
1543 }
1544
1545 void testFloorMem(double a)
1546 {
1547     Procedure proc;
1548     BasicBlock* root = proc.addBlock();
1549     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1550     MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
1551     root->appendNewControlValue(
1552         proc, Return, Origin(),
1553         root->appendNew<Value>(proc, Floor, Origin(), loadDouble));
1554
1555     CHECK(isIdentical(compileAndRun<double>(proc, &a), floor(a)));
1556 }
1557
1558 void testFloorFloorArg(double a)
1559 {
1560     Procedure proc;
1561     BasicBlock* root = proc.addBlock();
1562     Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(),
1563         root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1564     Value* secondFloor = root->appendNew<Value>(proc, Floor, Origin(), firstFloor);
1565     root->appendNewControlValue(proc, Return, Origin(), secondFloor);
1566
1567     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
1568 }
1569
1570 void testCeilFloorArg(double a)
1571 {
1572     Procedure proc;
1573     BasicBlock* root = proc.addBlock();
1574     Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(),
1575         root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
1576     Value* wrappingCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstFloor);
1577     root->appendNewControlValue(proc, Return, Origin(), wrappingCeil);
1578
1579     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
1580 }
1581
1582 void testFloorIToD64(int64_t a)
1583 {
1584     Procedure proc;
1585     BasicBlock* root = proc.addBlock();
1586     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1587     Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
1588
1589     root->appendNewControlValue(
1590         proc, Return, Origin(),
1591         root->appendNew<Value>(proc, Floor, Origin(), argumentAsDouble));
1592
1593     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(static_cast<double>(a))));
1594 }
1595
1596 void testFloorIToD32(int64_t a)
1597 {
1598     Procedure proc;
1599     BasicBlock* root = proc.addBlock();
1600     Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1601         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1602     Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
1603
1604     root->appendNewControlValue(
1605         proc, Return, Origin(),
1606         root->appendNew<Value>(proc, Floor, Origin(), argumentAsDouble));
1607
1608     CHECK(isIdentical(compileAndRun<double>(proc, a), floor(static_cast<double>(a))));
1609 }
1610
1611 void testFloorArg(float a)
1612 {
1613     Procedure proc;
1614     BasicBlock* root = proc.addBlock();
1615     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1616         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1617     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1618     Value* result = root->appendNew<Value>(proc, Floor, Origin(), argument);
1619     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1620     root->appendNewControlValue(proc, Return, Origin(), result32);
1621
1622     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
1623 }
1624
1625 void testFloorImm(float a)
1626 {
1627     Procedure proc;
1628     BasicBlock* root = proc.addBlock();
1629     Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1630     Value* result = root->appendNew<Value>(proc, Floor, Origin(), argument);
1631     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1632     root->appendNewControlValue(proc, Return, Origin(), result32);
1633
1634     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
1635 }
1636
1637 void testFloorMem(float a)
1638 {
1639     Procedure proc;
1640     BasicBlock* root = proc.addBlock();
1641     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1642     MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
1643     Value* result = root->appendNew<Value>(proc, Floor, Origin(), loadFloat);
1644     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1645     root->appendNewControlValue(proc, Return, Origin(), result32);
1646
1647     CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(floorf(a))));
1648 }
1649
1650 void testFloorFloorArg(float a)
1651 {
1652     Procedure proc;
1653     BasicBlock* root = proc.addBlock();
1654     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1655         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1656     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1657     Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(), argument);
1658     Value* secondFloor = root->appendNew<Value>(proc, Floor, Origin(), firstFloor);
1659     root->appendNewControlValue(proc, Return, Origin(), secondFloor);
1660
1661     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), floorf(a)));
1662 }
1663
1664 void testCeilFloorArg(float a)
1665 {
1666     Procedure proc;
1667     BasicBlock* root = proc.addBlock();
1668     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1669         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1670     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1671     Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(), argument);
1672     Value* wrappingCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstFloor);
1673     root->appendNewControlValue(proc, Return, Origin(), wrappingCeil);
1674
1675     CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), floorf(a)));
1676 }
1677
1678 void testFloorArgWithUselessDoubleConversion(float a)
1679 {
1680     Procedure proc;
1681     BasicBlock* root = proc.addBlock();
1682     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1683         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1684     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1685     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1686     Value* result = root->appendNew<Value>(proc, Floor, Origin(), asDouble);
1687     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1688     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1689     root->appendNewControlValue(proc, Return, Origin(), result32);
1690
1691     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
1692 }
1693
1694 void testFloorArgWithEffectfulDoubleConversion(float a)
1695 {
1696     Procedure proc;
1697     BasicBlock* root = proc.addBlock();
1698     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1699         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1700     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1701     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1702     Value* result = root->appendNew<Value>(proc, Floor, Origin(), asDouble);
1703     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1704     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1705     Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1706     root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
1707     root->appendNewControlValue(proc, Return, Origin(), result32);
1708
1709     double effect = 0;
1710     int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
1711     CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(floorf(a))));
1712     CHECK(isIdentical(effect, static_cast<double>(floorf(a))));
1713 }
1714
1715 double correctSqrt(double value)
1716 {
1717 #if CPU(X86) || CPU(X86_64)
1718     double result;
1719     asm ("sqrtsd %1, %0" : "=x"(result) : "x"(value));
1720     return result;
1721 #else    
1722     return sqrt(value);
1723 #endif
1724 }
1725
1726 void testSqrtArg(double a)
1727 {
1728     Procedure proc;
1729     BasicBlock* root = proc.addBlock();
1730     root->appendNewControlValue(
1731         proc, Return, Origin(),
1732         root->appendNew<Value>(
1733             proc, Sqrt, Origin(),
1734                 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
1735
1736     CHECK(isIdentical(compileAndRun<double>(proc, a), correctSqrt(a)));
1737 }
1738
1739 void testSqrtImm(double a)
1740 {
1741     Procedure proc;
1742     BasicBlock* root = proc.addBlock();
1743     Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1744     root->appendNewControlValue(
1745         proc, Return, Origin(),
1746         root->appendNew<Value>(proc, Sqrt, Origin(), argument));
1747
1748     CHECK(isIdentical(compileAndRun<double>(proc), correctSqrt(a)));
1749 }
1750
1751 void testSqrtMem(double a)
1752 {
1753     Procedure proc;
1754     BasicBlock* root = proc.addBlock();
1755     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1756     MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
1757     root->appendNewControlValue(
1758         proc, Return, Origin(),
1759         root->appendNew<Value>(proc, Sqrt, Origin(), loadDouble));
1760
1761     CHECK(isIdentical(compileAndRun<double>(proc, &a), correctSqrt(a)));
1762 }
1763
1764 void testSqrtArg(float a)
1765 {
1766     Procedure proc;
1767     BasicBlock* root = proc.addBlock();
1768     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1769         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1770     Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1771     Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), argument);
1772     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1773     root->appendNewControlValue(proc, Return, Origin(), result32);
1774
1775     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1776 }
1777
1778 void testSqrtImm(float a)
1779 {
1780     Procedure proc;
1781     BasicBlock* root = proc.addBlock();
1782     Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1783     Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), argument);
1784     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1785     root->appendNewControlValue(proc, Return, Origin(), result32);
1786
1787     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1788 }
1789
1790 void testSqrtMem(float a)
1791 {
1792     Procedure proc;
1793     BasicBlock* root = proc.addBlock();
1794     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1795     MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
1796     Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), loadFloat);
1797     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1798     root->appendNewControlValue(proc, Return, Origin(), result32);
1799
1800     CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1801 }
1802
1803 void testSqrtArgWithUselessDoubleConversion(float a)
1804 {
1805     Procedure proc;
1806     BasicBlock* root = proc.addBlock();
1807     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1808         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1809     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1810     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1811     Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), asDouble);
1812     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1813     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1814     root->appendNewControlValue(proc, Return, Origin(), result32);
1815
1816     CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1817 }
1818
1819 void testSqrtArgWithEffectfulDoubleConversion(float a)
1820 {
1821     Procedure proc;
1822     BasicBlock* root = proc.addBlock();
1823     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1824         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1825     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1826     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1827     Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), asDouble);
1828     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1829     Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1830     Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1831     root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
1832     root->appendNewControlValue(proc, Return, Origin(), result32);
1833
1834     double effect = 0;
1835     int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
1836     CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(correctSqrt(a)))));
1837     double expected = static_cast<double>(correctSqrt(a));
1838     CHECK(isIdentical(effect, expected));
1839 }
1840
1841 void testCompareTwoFloatToDouble(float a, float b)
1842 {
1843     Procedure proc;
1844     BasicBlock* root = proc.addBlock();
1845
1846     Value* arg1As32 = root->appendNew<Value>(proc, Trunc, Origin(),
1847         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1848     Value* arg1Float = root->appendNew<Value>(proc, BitwiseCast, Origin(), arg1As32);
1849     Value* arg1AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg1Float);
1850
1851     Value* arg2As32 = root->appendNew<Value>(proc, Trunc, Origin(),
1852         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1853     Value* arg2Float = root->appendNew<Value>(proc, BitwiseCast, Origin(), arg2As32);
1854     Value* arg2AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg2Float);
1855     Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg1AsDouble, arg2AsDouble);
1856
1857     root->appendNewControlValue(proc, Return, Origin(), equal);
1858
1859     CHECK(compileAndRun<int64_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)) == (a == b));
1860 }
1861
1862 void testCompareOneFloatToDouble(float a, double b)
1863 {
1864     Procedure proc;
1865     BasicBlock* root = proc.addBlock();
1866
1867     Value* arg1As32 = root->appendNew<Value>(proc, Trunc, Origin(),
1868         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1869     Value* arg1Float = root->appendNew<Value>(proc, BitwiseCast, Origin(), arg1As32);
1870     Value* arg1AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg1Float);
1871
1872     Value* arg2AsDouble = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1873     Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg1AsDouble, arg2AsDouble);
1874
1875     root->appendNewControlValue(proc, Return, Origin(), equal);
1876
1877     CHECK(compileAndRun<int64_t>(proc, bitwise_cast<int32_t>(a), b) == (a == b));
1878 }
1879
1880 void testCompareFloatToDoubleThroughPhi(float a, float b)
1881 {
1882     Procedure proc;
1883     BasicBlock* root = proc.addBlock();
1884     BasicBlock* thenCase = proc.addBlock();
1885     BasicBlock* elseCase = proc.addBlock();
1886     BasicBlock* tail = proc.addBlock();
1887
1888     Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1889
1890     Value* arg1As32 = root->appendNew<Value>(proc, Trunc, Origin(),
1891         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1892     Value* arg1Float = root->appendNew<Value>(proc, BitwiseCast, Origin(), arg1As32);
1893     Value* arg1AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg1Float);
1894
1895     Value* arg2AsDouble = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1896     Value* arg2AsFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), arg2AsDouble);
1897     Value* arg2AsFRoundedDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), arg2AsFloat);
1898
1899     root->appendNewControlValue(
1900         proc, Branch, Origin(),
1901         condition,
1902         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1903
1904     UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), arg1AsDouble);
1905     thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1906
1907     Value* elseConst = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), 0.);
1908     UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), elseConst);
1909     elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1910
1911     Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
1912     thenValue->setPhi(doubleInput);
1913     elseValue->setPhi(doubleInput);
1914     Value* equal = tail->appendNew<Value>(proc, Equal, Origin(), doubleInput, arg2AsFRoundedDouble);
1915     tail->appendNewControlValue(proc, Return, Origin(), equal);
1916
1917     auto code = compileProc(proc);
1918     int32_t integerA = bitwise_cast<int32_t>(a);
1919     double doubleB = b;
1920     CHECK(invoke<int64_t>(*code, 1, integerA, doubleB) == (a == b));
1921     CHECK(invoke<int64_t>(*code, 0, integerA, doubleB) == (b == 0));
1922 }
1923
1924 void testDoubleToFloatThroughPhi(float value)
1925 {
1926     // Simple case of:
1927     //     if (a) {
1928     //         x = DoubleAdd(a, b)
1929     //     else
1930     //         x = DoubleAdd(a, c)
1931     //     DoubleToFloat(x)
1932     //
1933     // Both Adds can be converted to float add.
1934     Procedure proc;
1935     BasicBlock* root = proc.addBlock();
1936     BasicBlock* thenCase = proc.addBlock();
1937     BasicBlock* elseCase = proc.addBlock();
1938     BasicBlock* tail = proc.addBlock();
1939
1940     Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1941     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1942         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1943     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1944     Value* argAsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1945
1946     root->appendNewControlValue(
1947         proc, Branch, Origin(),
1948         condition,
1949         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1950
1951     Value* postitiveConst = thenCase->appendNew<ConstDoubleValue>(proc, Origin(), 42.5f);
1952     Value* thenAdd = thenCase->appendNew<Value>(proc, Add, Origin(), argAsDouble, postitiveConst);
1953     UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), thenAdd);
1954     thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1955
1956     Value* elseConst = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), M_PI);
1957     UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), elseConst);
1958     elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
1959
1960     Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
1961     thenValue->setPhi(doubleInput);
1962     elseValue->setPhi(doubleInput);
1963     Value* floatResult = tail->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleInput);
1964     tail->appendNewControlValue(proc, Return, Origin(), floatResult);
1965
1966     auto code = compileProc(proc);
1967     CHECK(isIdentical(invoke<float>(*code, 1, bitwise_cast<int32_t>(value)), value + 42.5f));
1968     CHECK(isIdentical(invoke<float>(*code, 0, bitwise_cast<int32_t>(value)), static_cast<float>(M_PI)));
1969 }
1970
1971 void testReduceFloatToDoubleValidates()
1972 {
1973     // Simple case of:
1974     //     f = DoubleToFloat(Bitcast(argGPR0))
1975     //     if (a) {
1976     //         x = FloatConst()
1977     //     else
1978     //         x = FloatConst()
1979     //     p = Phi(x)
1980     //     a = Mul(p, p)
1981     //     b = Add(a, f)
1982     //     c = Add(p, b)
1983     //     Return(c)
1984     //
1985     // This should not crash in the validator after ReduceFloatToDouble.
1986     Procedure proc;
1987     BasicBlock* root = proc.addBlock();
1988     BasicBlock* thenCase = proc.addBlock();
1989     BasicBlock* elseCase = proc.addBlock();
1990     BasicBlock* tail = proc.addBlock();
1991
1992     Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1993     Value* thingy = root->appendNew<Value>(proc, BitwiseCast, Origin(), condition);
1994     thingy = root->appendNew<Value>(proc, DoubleToFloat, Origin(), thingy); // Make the phase think it has work to do.
1995     root->appendNewControlValue(
1996         proc, Branch, Origin(),
1997         condition,
1998         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1999
2000     UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(),
2001         thenCase->appendNew<ConstFloatValue>(proc, Origin(), 11.5));
2002     thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2003
2004     UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), 
2005         elseCase->appendNew<ConstFloatValue>(proc, Origin(), 10.5));
2006     elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2007
2008     Value* phi =  tail->appendNew<Value>(proc, Phi, Float, Origin());
2009     thenValue->setPhi(phi);
2010     elseValue->setPhi(phi);
2011     Value* result = tail->appendNew<Value>(proc, Mul, Origin(), 
2012             phi, phi);
2013     result = tail->appendNew<Value>(proc, Add, Origin(), 
2014             result,
2015             thingy);
2016     result = tail->appendNew<Value>(proc, Add, Origin(), 
2017             phi,
2018             result);
2019     tail->appendNewControlValue(proc, Return, Origin(), result);
2020
2021     auto code = compileProc(proc);
2022     CHECK(isIdentical(invoke<float>(*code, 1), 11.5f * 11.5f + static_cast<float>(bitwise_cast<double>(static_cast<uint64_t>(1))) + 11.5f));
2023     CHECK(isIdentical(invoke<float>(*code, 0), 10.5f * 10.5f + static_cast<float>(bitwise_cast<double>(static_cast<uint64_t>(0))) + 10.5f));
2024 }
2025
2026 void testDoubleProducerPhiToFloatConversion(float value)
2027 {
2028     Procedure proc;
2029     BasicBlock* root = proc.addBlock();
2030     BasicBlock* thenCase = proc.addBlock();
2031     BasicBlock* elseCase = proc.addBlock();
2032     BasicBlock* tail = proc.addBlock();
2033
2034     Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2035     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2036         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2037     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2038
2039     root->appendNewControlValue(
2040         proc, Branch, Origin(),
2041         condition,
2042         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2043
2044     Value* asDouble = thenCase->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2045     UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), asDouble);
2046     thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2047
2048     Value* constDouble = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), 42.5);
2049     UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), constDouble);
2050     elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2051
2052     Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
2053     thenValue->setPhi(doubleInput);
2054     elseValue->setPhi(doubleInput);
2055
2056     Value* argAsDoubleAgain = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2057     Value* finalAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, argAsDoubleAgain);
2058     Value* floatResult = tail->appendNew<Value>(proc, DoubleToFloat, Origin(), finalAdd);
2059     tail->appendNewControlValue(proc, Return, Origin(), floatResult);
2060
2061     auto code = compileProc(proc);
2062     CHECK(isIdentical(invoke<float>(*code, 1, bitwise_cast<int32_t>(value)), value + value));
2063     CHECK(isIdentical(invoke<float>(*code, 0, bitwise_cast<int32_t>(value)), 42.5f + value));
2064 }
2065
2066 void testDoubleProducerPhiToFloatConversionWithDoubleConsumer(float value)
2067 {
2068     // In this case, the Upsilon-Phi effectively contains a Float value, but it is used
2069     // as a Float and as a Double.
2070     Procedure proc;
2071     BasicBlock* root = proc.addBlock();
2072     BasicBlock* thenCase = proc.addBlock();
2073     BasicBlock* elseCase = proc.addBlock();
2074     BasicBlock* tail = proc.addBlock();
2075
2076     Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2077     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2078         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2079     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2080
2081     root->appendNewControlValue(
2082         proc, Branch, Origin(),
2083         condition,
2084         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2085
2086     Value* asDouble = thenCase->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2087     UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), asDouble);
2088     thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2089
2090     Value* constDouble = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), 42.5);
2091     UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), constDouble);
2092     elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2093
2094     Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
2095     thenValue->setPhi(doubleInput);
2096     elseValue->setPhi(doubleInput);
2097
2098     Value* argAsDoubleAgain = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2099     Value* floatAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, argAsDoubleAgain);
2100
2101     // FRound.
2102     Value* floatResult = tail->appendNew<Value>(proc, DoubleToFloat, Origin(), floatAdd);
2103     Value* doubleResult = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatResult);
2104
2105     // This one *cannot* be eliminated
2106     Value* doubleAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, doubleResult);
2107
2108     tail->appendNewControlValue(proc, Return, Origin(), doubleAdd);
2109
2110     auto code = compileProc(proc);
2111     CHECK(isIdentical(invoke<double>(*code, 1, bitwise_cast<int32_t>(value)), (value + value) + static_cast<double>(value)));
2112     CHECK(isIdentical(invoke<double>(*code, 0, bitwise_cast<int32_t>(value)), static_cast<double>((42.5f + value) + 42.5f)));
2113 }
2114
2115 void testDoubleProducerPhiWithNonFloatConst(float value, double constValue)
2116 {
2117     Procedure proc;
2118     BasicBlock* root = proc.addBlock();
2119     BasicBlock* thenCase = proc.addBlock();
2120     BasicBlock* elseCase = proc.addBlock();
2121     BasicBlock* tail = proc.addBlock();
2122
2123     Value* condition = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2124     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2125         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2126     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2127
2128     root->appendNewControlValue(
2129         proc, Branch, Origin(),
2130         condition,
2131         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2132
2133     Value* asDouble = thenCase->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2134     UpsilonValue* thenValue = thenCase->appendNew<UpsilonValue>(proc, Origin(), asDouble);
2135     thenCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2136
2137     Value* constDouble = elseCase->appendNew<ConstDoubleValue>(proc, Origin(), constValue);
2138     UpsilonValue* elseValue = elseCase->appendNew<UpsilonValue>(proc, Origin(), constDouble);
2139     elseCase->appendNewControlValue(proc, Jump, Origin(), FrequentedBlock(tail));
2140
2141     Value* doubleInput = tail->appendNew<Value>(proc, Phi, Double, Origin());
2142     thenValue->setPhi(doubleInput);
2143     elseValue->setPhi(doubleInput);
2144
2145     Value* argAsDoubleAgain = tail->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2146     Value* finalAdd = tail->appendNew<Value>(proc, Add, Origin(), doubleInput, argAsDoubleAgain);
2147     Value* floatResult = tail->appendNew<Value>(proc, DoubleToFloat, Origin(), finalAdd);
2148     tail->appendNewControlValue(proc, Return, Origin(), floatResult);
2149
2150     auto code = compileProc(proc);
2151     CHECK(isIdentical(invoke<float>(*code, 1, bitwise_cast<int32_t>(value)), value + value));
2152     CHECK(isIdentical(invoke<float>(*code, 0, bitwise_cast<int32_t>(value)), static_cast<float>(constValue + value)));
2153 }
2154
2155 void testDoubleArgToInt64BitwiseCast(double value)
2156 {
2157     Procedure proc;
2158     BasicBlock* root = proc.addBlock();
2159     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2160
2161     root->appendNewControlValue(
2162         proc, Return, Origin(),
2163         root->appendNew<Value>(
2164             proc, BitwiseCast, Origin(), argument));
2165
2166     CHECK(isIdentical(compileAndRun<int64_t>(proc, value), bitwise_cast<int64_t>(value)));
2167 }
2168
2169 void testDoubleImmToInt64BitwiseCast(double value)
2170 {
2171     Procedure proc;
2172     BasicBlock* root = proc.addBlock();
2173     Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
2174
2175     root->appendNewControlValue(
2176         proc, Return, Origin(),
2177         root->appendNew<Value>(
2178             proc, BitwiseCast, Origin(), argument));
2179
2180     CHECK(isIdentical(compileAndRun<int64_t>(proc), bitwise_cast<int64_t>(value)));
2181 }
2182
2183 void testTwoBitwiseCastOnDouble(double value)
2184 {
2185     Procedure proc;
2186     BasicBlock* root = proc.addBlock();
2187     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2188     Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
2189     Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
2190     root->appendNewControlValue(proc, Return, Origin(), second);
2191
2192     CHECK(isIdentical(compileAndRun<double>(proc, value), value));
2193 }
2194
2195 void testBitwiseCastOnDoubleInMemory(double value)
2196 {
2197     Procedure proc;
2198     BasicBlock* root = proc.addBlock();
2199     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2200     MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
2201     Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
2202     root->appendNewControlValue(proc, Return, Origin(), cast);
2203
2204     CHECK(isIdentical(compileAndRun<int64_t>(proc, &value), bitwise_cast<int64_t>(value)));
2205 }
2206
2207 void testBitwiseCastOnDoubleInMemoryIndexed(double value)
2208 {
2209     Procedure proc;
2210     BasicBlock* root = proc.addBlock();
2211     Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2212     Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2213     Value* scaledOffset = root->appendNew<Value>(proc, Shl, Origin(),
2214         offset,
2215         root->appendNew<Const32Value>(proc, Origin(), 3));
2216     Value* address = root->appendNew<Value>(proc, Add, Origin(), base, scaledOffset);
2217     MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
2218     Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
2219     root->appendNewControlValue(proc, Return, Origin(), cast);
2220
2221     CHECK(isIdentical(compileAndRun<int64_t>(proc, &value, 0), bitwise_cast<int64_t>(value)));
2222 }
2223
2224 void testInt64BArgToDoubleBitwiseCast(int64_t value)
2225 {
2226     Procedure proc;
2227     BasicBlock* root = proc.addBlock();
2228     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2229
2230     root->appendNewControlValue(
2231         proc, Return, Origin(),
2232         root->appendNew<Value>(
2233             proc, BitwiseCast, Origin(), argument));
2234
2235     CHECK(isIdentical(compileAndRun<double>(proc, value), bitwise_cast<double>(value)));
2236 }
2237
2238 void testInt64BImmToDoubleBitwiseCast(int64_t value)
2239 {
2240     Procedure proc;
2241     BasicBlock* root = proc.addBlock();
2242     Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
2243
2244     root->appendNewControlValue(
2245         proc, Return, Origin(),
2246         root->appendNew<Value>(
2247             proc, BitwiseCast, Origin(), argument));
2248
2249     CHECK(isIdentical(compileAndRun<double>(proc), bitwise_cast<double>(value)));
2250 }
2251
2252 void testTwoBitwiseCastOnInt64(int64_t value)
2253 {
2254     Procedure proc;
2255     BasicBlock* root = proc.addBlock();
2256     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2257     Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
2258     Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
2259     root->appendNewControlValue(proc, Return, Origin(), second);
2260
2261     CHECK(isIdentical(compileAndRun<int64_t>(proc, value), value));
2262 }
2263
2264 void testBitwiseCastOnInt64InMemory(int64_t value)
2265 {
2266     Procedure proc;
2267     BasicBlock* root = proc.addBlock();
2268     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2269     MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2270     Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
2271     root->appendNewControlValue(proc, Return, Origin(), cast);
2272
2273     CHECK(isIdentical(compileAndRun<double>(proc, &value), bitwise_cast<double>(value)));
2274 }
2275
2276 void testBitwiseCastOnInt64InMemoryIndexed(int64_t value)
2277 {
2278     Procedure proc;
2279     BasicBlock* root = proc.addBlock();
2280     Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2281     Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2282     Value* scaledOffset = root->appendNew<Value>(proc, Shl, Origin(),
2283         offset,
2284         root->appendNew<Const32Value>(proc, Origin(), 3));
2285     Value* address = root->appendNew<Value>(proc, Add, Origin(), base, scaledOffset);
2286     MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2287     Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
2288     root->appendNewControlValue(proc, Return, Origin(), cast);
2289
2290     CHECK(isIdentical(compileAndRun<double>(proc, &value, 0), bitwise_cast<double>(value)));
2291 }
2292
2293 void testFloatImmToInt32BitwiseCast(float value)
2294 {
2295     Procedure proc;
2296     BasicBlock* root = proc.addBlock();
2297     Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), value);
2298
2299     root->appendNewControlValue(
2300         proc, Return, Origin(),
2301         root->appendNew<Value>(
2302             proc, BitwiseCast, Origin(), argument));
2303
2304     CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(value)));
2305 }
2306
2307 void testBitwiseCastOnFloatInMemory(float value)
2308 {
2309     Procedure proc;
2310     BasicBlock* root = proc.addBlock();
2311     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2312     MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
2313     Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadFloat);
2314     root->appendNewControlValue(proc, Return, Origin(), cast);
2315
2316     CHECK(isIdentical(compileAndRun<int32_t>(proc, &value), bitwise_cast<int32_t>(value)));
2317 }
2318
2319 void testInt32BArgToFloatBitwiseCast(int32_t value)
2320 {
2321     Procedure proc;
2322     BasicBlock* root = proc.addBlock();
2323     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2324
2325     root->appendNewControlValue(
2326         proc, Return, Origin(),
2327         root->appendNew<Value>(
2328             proc, BitwiseCast, Origin(), argument));
2329
2330     CHECK(isIdentical(compileAndRun<float>(proc, value), bitwise_cast<float>(value)));
2331 }
2332
2333 void testInt32BImmToFloatBitwiseCast(int32_t value)
2334 {
2335     Procedure proc;
2336     BasicBlock* root = proc.addBlock();
2337     Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
2338
2339     root->appendNewControlValue(
2340         proc, Return, Origin(),
2341         root->appendNew<Value>(
2342             proc, BitwiseCast, Origin(), argument));
2343
2344     CHECK(isIdentical(compileAndRun<float>(proc), bitwise_cast<float>(value)));
2345 }
2346
2347 void testTwoBitwiseCastOnInt32(int32_t value)
2348 {
2349     Procedure proc;
2350     BasicBlock* root = proc.addBlock();
2351     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2352     Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
2353     Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
2354     root->appendNewControlValue(proc, Return, Origin(), second);
2355
2356     CHECK(isIdentical(compileAndRun<int32_t>(proc, value), value));
2357 }
2358
2359 void testBitwiseCastOnInt32InMemory(int32_t value)
2360 {
2361     Procedure proc;
2362     BasicBlock* root = proc.addBlock();
2363     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2364     MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2365     Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadFloat);
2366     root->appendNewControlValue(proc, Return, Origin(), cast);
2367
2368     CHECK(isIdentical(compileAndRun<float>(proc, &value), bitwise_cast<float>(value)));
2369 }
2370
2371 void testConvertDoubleToFloatArg(double value)
2372 {
2373     Procedure proc;
2374     BasicBlock* root = proc.addBlock();
2375     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2376     Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
2377     root->appendNewControlValue(proc, Return, Origin(), asFloat);
2378
2379     CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
2380 }
2381
2382 void testConvertDoubleToFloatImm(double value)
2383 {
2384     Procedure proc;
2385     BasicBlock* root = proc.addBlock();
2386     Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
2387     Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
2388     root->appendNewControlValue(proc, Return, Origin(), asFloat);
2389
2390     CHECK(isIdentical(compileAndRun<float>(proc), static_cast<float>(value)));
2391 }
2392
2393 void testConvertDoubleToFloatMem(double value)
2394 {
2395     Procedure proc;
2396     BasicBlock* root = proc.addBlock();
2397     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2398     MemoryValue* loadedDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
2399     Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), loadedDouble);
2400     root->appendNewControlValue(proc, Return, Origin(), asFloat);
2401
2402     CHECK(isIdentical(compileAndRun<float>(proc, &value), static_cast<float>(value)));
2403 }
2404
2405 void testConvertFloatToDoubleArg(float value)
2406 {
2407     Procedure proc;
2408     BasicBlock* root = proc.addBlock();
2409     Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
2410         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2411     Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
2412     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
2413     root->appendNewControlValue(proc, Return, Origin(), asDouble);
2414
2415     CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int32_t>(value)), static_cast<double>(value)));
2416 }
2417
2418 void testConvertFloatToDoubleImm(float value)
2419 {
2420     Procedure proc;
2421     BasicBlock* root = proc.addBlock();
2422     Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), value);
2423     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argument);
2424     root->appendNewControlValue(proc, Return, Origin(), asDouble);
2425
2426     CHECK(isIdentical(compileAndRun<double>(proc), static_cast<double>(value)));
2427 }
2428
2429 void testConvertFloatToDoubleMem(float value)
2430 {
2431     Procedure proc;
2432     BasicBlock* root = proc.addBlock();
2433     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2434     MemoryValue* loadedFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
2435     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), loadedFloat);
2436     root->appendNewControlValue(proc, Return, Origin(), asDouble);
2437
2438     CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(value)));
2439 }
2440
2441 void testConvertDoubleToFloatToDoubleToFloat(double value)
2442 {
2443     Procedure proc;
2444     BasicBlock* root = proc.addBlock();
2445     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2446     Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
2447     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
2448     Value* asFloatAgain = root->appendNew<Value>(proc, DoubleToFloat, Origin(), asDouble);
2449     root->appendNewControlValue(proc, Return, Origin(), asFloatAgain);
2450
2451     CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
2452 }
2453
2454 void testLoadFloatConvertDoubleConvertFloatStoreFloat(float value)
2455 {
2456     Procedure proc;
2457     BasicBlock* root = proc.addBlock();
2458     Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2459     Value* dst = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2460     MemoryValue* loadedFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), src);
2461     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), loadedFloat);
2462     Value* asFloatAgain = root->appendNew<Value>(proc, DoubleToFloat, Origin(), asDouble);
2463     root->appendNew<MemoryValue>(proc, Store, Origin(), asFloatAgain, dst);
2464
2465     root->appendNewControlValue(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2466
2467     float input = value;
2468     float output = 0.;
2469     CHECK(!compileAndRun<int64_t>(proc, &input, &output));
2470     CHECK(isIdentical(input, output));
2471 }
2472
2473 void testFroundArg(double value)
2474 {
2475     Procedure proc;
2476     BasicBlock* root = proc.addBlock();
2477     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2478     Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
2479     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
2480     root->appendNewControlValue(proc, Return, Origin(), asDouble);
2481
2482     CHECK(isIdentical(compileAndRun<double>(proc, value), static_cast<double>(static_cast<float>(value))));
2483 }
2484
2485 void testFroundMem(double value)
2486 {
2487     Procedure proc;
2488     BasicBlock* root = proc.addBlock();
2489     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2490     MemoryValue* loadedDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
2491     Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), loadedDouble);
2492     Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
2493     root->appendNewControlValue(proc, Return, Origin(), asDouble);
2494
2495     CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(static_cast<float>(value))));
2496 }
2497
2498 void testIToD64Arg()
2499 {
2500     Procedure proc;
2501     BasicBlock* root = proc.addBlock();
2502     Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2503     Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), src);
2504     root->appendNewControlValue(proc, Return, Origin(), srcAsDouble);
2505
2506     auto code = compileProc(proc);
2507     for (auto testValue : int64Operands())
2508         CHECK(isIdentical(invoke<double>(*code, testValue.value), static_cast<double>(testValue.value)));
2509 }
2510
2511 void testIToF64Arg()
2512 {
2513     Procedure proc;
2514     BasicBlock* root = proc.addBlock();
2515     Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2516     Value* srcAsFloat = root->appendNew<Value>(proc, IToF, Origin(), src);
2517     root->appendNewControlValue(proc, Return, Origin(), srcAsFloat);
2518
2519     auto code = compileProc(proc);
2520     for (auto testValue : int64Operands())
2521         CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2522 }
2523
2524 void testIToD32Arg()
2525 {
2526     Procedure proc;
2527     BasicBlock* root = proc.addBlock();
2528     Value* src = root->appendNew<Value>(proc, Trunc, Origin(),
2529         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2530     Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), src);
2531     root->appendNewControlValue(proc, Return, Origin(), srcAsDouble);
2532
2533     auto code = compileProc(proc);
2534     for (auto testValue : int32Operands())
2535         CHECK(isIdentical(invoke<double>(*code, testValue.value), static_cast<double>(testValue.value)));
2536 }
2537
2538 void testIToF32Arg()
2539 {
2540     Procedure proc;
2541     BasicBlock* root = proc.addBlock();
2542     Value* src = root->appendNew<Value>(proc, Trunc, Origin(),
2543         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2544     Value* srcAsFloat = root->appendNew<Value>(proc, IToF, Origin(), src);
2545     root->appendNewControlValue(proc, Return, Origin(), srcAsFloat);
2546
2547     auto code = compileProc(proc);
2548     for (auto testValue : int32Operands())
2549         CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2550 }
2551
2552 void testIToD64Mem()
2553 {
2554     Procedure proc;
2555     BasicBlock* root = proc.addBlock();
2556     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2557     MemoryValue* loadedSrc = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2558     Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), loadedSrc);
2559     root->appendNewControlValue(proc, Return, Origin(), srcAsDouble);
2560
2561     auto code = compileProc(proc);
2562     int64_t inMemoryValue;
2563     for (auto testValue : int64Operands()) {
2564         inMemoryValue = testValue.value;
2565         CHECK(isIdentical(invoke<double>(*code, &inMemoryValue), static_cast<double>(testValue.value)));
2566         CHECK(inMemoryValue == testValue.value);
2567     }
2568 }
2569
2570 void testIToF64Mem()
2571 {
2572     Procedure proc;
2573     BasicBlock* root = proc.addBlock();
2574     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2575     MemoryValue* loadedSrc = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2576     Value* srcAsFloat = root->appendNew<Value>(proc, IToF, Origin(), loadedSrc);
2577     root->appendNewControlValue(proc, Return, Origin(), srcAsFloat);
2578
2579     auto code = compileProc(proc);
2580     int64_t inMemoryValue;
2581     for (auto testValue : int64Operands()) {
2582         inMemoryValue = testValue.value;
2583         CHECK(isIdentical(invoke<float>(*code, &inMemoryValue), static_cast<float>(testValue.value)));
2584         CHECK(inMemoryValue == testValue.value);
2585     }
2586 }
2587
2588 void testIToD32Mem()
2589 {
2590     Procedure proc;
2591     BasicBlock* root = proc.addBlock();
2592     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2593     MemoryValue* loadedSrc = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2594     Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), loadedSrc);
2595     root->appendNewControlValue(proc, Return, Origin(), srcAsDouble);
2596
2597     auto code = compileProc(proc);
2598     int32_t inMemoryValue;
2599     for (auto testValue : int32Operands()) {
2600         inMemoryValue = testValue.value;
2601         CHECK(isIdentical(invoke<double>(*code, &inMemoryValue), static_cast<double>(testValue.value)));
2602         CHECK(inMemoryValue == testValue.value);
2603     }
2604 }
2605
2606 void testIToF32Mem()
2607 {
2608     Procedure proc;
2609     BasicBlock* root = proc.addBlock();
2610     Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2611     MemoryValue* loadedSrc = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2612     Value* srcAsFloat = root->appendNew<Value>(proc, IToF, Origin(), loadedSrc);
2613     root->appendNewControlValue(proc, Return, Origin(), srcAsFloat);
2614
2615     auto code = compileProc(proc);
2616     int32_t inMemoryValue;
2617     for (auto testValue : int32Operands()) {
2618         inMemoryValue = testValue.value;
2619         CHECK(isIdentical(invoke<float>(*code, &inMemoryValue), static_cast<float>(testValue.value)));
2620         CHECK(inMemoryValue == testValue.value);
2621     }
2622 }
2623
2624 void testIToD64Imm(int64_t value)
2625 {
2626     Procedure proc;
2627     BasicBlock* root = proc.addBlock();
2628     Value* src = root->appendNew<Const64Value>(proc, Origin(), value);
2629     Value* srcAsFloatingPoint = root->appendNew<Value>(proc, IToD, Origin(), src);
2630     root->appendNewControlValue(proc, Return, Origin(), srcAsFloatingPoint);
2631     CHECK(isIdentical(compileAndRun<double>(proc), static_cast<double>(value)));
2632 }
2633
2634 void testIToF64Imm(int64_t value)
2635 {
2636     Procedure proc;
2637     BasicBlock* root = proc.addBlock();
2638     Value* src = root->appendNew<Const64Value>(proc, Origin(), value);
2639     Value* srcAsFloatingPoint = root->appendNew<Value>(proc, IToF, Origin(), src);
2640     root->appendNewControlValue(proc, Return, Origin(), srcAsFloatingPoint);
2641     CHECK(isIdentical(compileAndRun<float>(proc), static_cast<float>(value)));
2642 }
2643
2644 void testIToD32Imm(int32_t value)
2645 {
2646     Procedure proc;
2647     BasicBlock* root = proc.addBlock();
2648     Value* src = root->appendNew<Const32Value>(proc, Origin(), value);
2649     Value* srcAsFloatingPoint = root->appendNew<Value>(proc, IToD, Origin(), src);
2650     root->appendNewControlValue(proc, Return, Origin(), srcAsFloatingPoint);
2651     CHECK(isIdentical(compileAndRun<double>(proc), static_cast<double>(value)));
2652 }
2653
2654 void testIToF32Imm(int32_t value)
2655 {
2656     Procedure proc;
2657     BasicBlock* root = proc.addBlock();
2658     Value* src = root->appendNew<Const32Value>(proc, Origin(), value);
2659     Value* srcAsFloatingPoint = root->appendNew<Value>(proc, IToF, Origin(), src);
2660     root->appendNewControlValue(proc, Return, Origin(), srcAsFloatingPoint);
2661     CHECK(isIdentical(compileAndRun<float>(proc), static_cast<float>(value)));
2662 }
2663
2664 void testIToDReducedToIToF64Arg()
2665 {
2666     Procedure proc;
2667     BasicBlock* root = proc.addBlock();
2668     Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2669     Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), src);
2670     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), srcAsDouble);
2671     root->appendNewControlValue(proc, Return, Origin(), floatResult);
2672
2673     auto code = compileProc(proc);
2674     for (auto testValue : int64Operands())
2675         CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2676 }
2677
2678 void testIToDReducedToIToF32Arg()
2679 {
2680     Procedure proc;
2681     BasicBlock* root = proc.addBlock();
2682     Value* src = root->appendNew<Value>(proc, Trunc, Origin(),
2683         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2684     Value* srcAsDouble = root->appendNew<Value>(proc, IToD, Origin(), src);
2685     Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), srcAsDouble);
2686     root->appendNewControlValue(proc, Return, Origin(), floatResult);
2687
2688     auto code = compileProc(proc);
2689     for (auto testValue : int32Operands())
2690         CHECK(isIdentical(invoke<float>(*code, testValue.value), static_cast<float>(testValue.value)));
2691 }
2692
2693 void testStore32(int value)
2694 {
2695     Procedure proc;
2696     BasicBlock* root = proc.addBlock();
2697     int slot = 0xbaadbeef;
2698     root->appendNew<MemoryValue>(
2699         proc, Store, Origin(),
2700         root->appendNew<Value>(
2701             proc, Trunc, Origin(),
2702             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2703         root->appendNew<ConstPtrValue>(proc, Origin(), &slot), 0);
2704     root->appendNewControlValue(
2705         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2706
2707     CHECK(!compileAndRun<int>(proc, value));
2708     CHECK(slot == value);
2709 }
2710
2711 void testStoreConstant(int value)
2712 {
2713     Procedure proc;
2714     BasicBlock* root = proc.addBlock();
2715     int slot = 0xbaadbeef;
2716     root->appendNew<MemoryValue>(
2717         proc, Store, Origin(),
2718         root->appendNew<Const32Value>(proc, Origin(), value),
2719         root->appendNew<ConstPtrValue>(proc, Origin(), &slot), 0);
2720     root->appendNewControlValue(
2721         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2722
2723     CHECK(!compileAndRun<int>(proc));
2724     CHECK(slot == value);
2725 }
2726
2727 void testStoreConstantPtr(intptr_t value)
2728 {
2729     Procedure proc;
2730     BasicBlock* root = proc.addBlock();
2731     intptr_t slot;
2732 #if CPU(ADDRESS64)
2733     slot = (static_cast<intptr_t>(0xbaadbeef) << 32) + static_cast<intptr_t>(0xbaadbeef);
2734 #else
2735     slot = 0xbaadbeef;
2736 #endif
2737     root->appendNew<MemoryValue>(
2738         proc, Store, Origin(),
2739         root->appendNew<ConstPtrValue>(proc, Origin(), value),
2740         root->appendNew<ConstPtrValue>(proc, Origin(), &slot), 0);
2741     root->appendNewControlValue(
2742         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2743
2744     CHECK(!compileAndRun<int>(proc));
2745     CHECK(slot == value);
2746 }
2747
2748 void testStore8Arg()
2749 {
2750     { // Direct addressing.
2751         Procedure proc;
2752         BasicBlock* root = proc.addBlock();
2753
2754         Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
2755             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2756         Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2757
2758         root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2759         root->appendNewControlValue(proc, Return, Origin(), value);
2760
2761         int8_t storage = 0;
2762         CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
2763         CHECK(storage == 42);
2764     }
2765
2766     { // Indexed addressing.
2767         Procedure proc;
2768         BasicBlock* root = proc.addBlock();
2769
2770         Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
2771             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2772         Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2773         Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2774         Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
2775
2776         Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2777         Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2778
2779         root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2780         root->appendNewControlValue(proc, Return, Origin(), value);
2781
2782         int8_t storage = 0;
2783         CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
2784         CHECK(storage == 42);
2785     }
2786 }
2787
2788 void testStore8Imm()
2789 {
2790     { // Direct addressing.
2791         Procedure proc;
2792         BasicBlock* root = proc.addBlock();
2793
2794         Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2795         Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2796
2797         root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2798         root->appendNewControlValue(proc, Return, Origin(), value);
2799
2800         int8_t storage = 0;
2801         CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
2802         CHECK(storage == 42);
2803     }
2804
2805     { // Indexed addressing.
2806         Procedure proc;
2807         BasicBlock* root = proc.addBlock();
2808
2809         Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2810         Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2811         Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2812         Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
2813
2814         Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2815         Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2816
2817         root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
2818         root->appendNewControlValue(proc, Return, Origin(), value);
2819
2820         int8_t storage = 0;
2821         CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
2822         CHECK(storage == 42);
2823     }
2824 }
2825
2826 void testStorePartial8BitRegisterOnX86()
2827 {
2828     Procedure proc;
2829     BasicBlock* root = proc.addBlock();
2830
2831     // We want to have this in ECX.
2832     Value* returnValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2833
2834     // We want this suck in EDX.
2835     Value* whereToStore = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2836
2837     // The patch point is there to help us force the hand of the compiler.
2838     PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
2839
2840     // For the value above to be materialized and give the allocator
2841     // a stronger insentive to name those register the way we need.
2842     patchpoint->append(ConstrainedValue(returnValue, ValueRep(GPRInfo::regT3)));
2843     patchpoint->append(ConstrainedValue(whereToStore, ValueRep(GPRInfo::regT2)));
2844
2845     // We'll produce EDI.
2846     patchpoint->resultConstraints = { ValueRep::reg(GPRInfo::regT6) };
2847
2848     // Give the allocator a good reason not to use any other register.
2849     RegisterSet clobberSet = RegisterSet::allGPRs();
2850     clobberSet.exclude(RegisterSet::stackRegisters());
2851     clobberSet.exclude(RegisterSet::reservedHardwareRegisters());
2852     clobberSet.clear(GPRInfo::regT3);
2853     clobberSet.clear(GPRInfo::regT2);
2854     clobberSet.clear(GPRInfo::regT6);
2855     patchpoint->clobberLate(clobberSet);
2856
2857     // Set EDI.
2858     patchpoint->setGenerator(
2859         [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2860             AllowMacroScratchRegisterUsage allowScratch(jit);
2861             jit.xor64(params[0].gpr(), params[0].gpr());
2862         });
2863
2864     // If everything went well, we should have the big number in eax,
2865     // patchpoint == EDI and whereToStore = EDX.
2866     // Since EDI == 5, and AH = 5 on 8 bit store, this would go wrong
2867     // if we use X86 partial registers.
2868     root->appendNew<MemoryValue>(proc, Store8, Origin(), patchpoint, whereToStore);
2869
2870     root->appendNewControlValue(proc, Return, Origin(), returnValue);
2871
2872     int8_t storage = 0xff;
2873     CHECK(compileAndRun<int64_t>(proc, 0x12345678abcdef12, &storage) == 0x12345678abcdef12);
2874     CHECK(!storage);
2875 }
2876
2877 void testStore16Arg()
2878 {
2879     { // Direct addressing.
2880         Procedure proc;
2881         BasicBlock* root = proc.addBlock();
2882
2883         Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
2884             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2885         Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2886
2887         root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2888         root->appendNewControlValue(proc, Return, Origin(), value);
2889
2890         int16_t storage = -1;
2891         CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
2892         CHECK(storage == 42);
2893     }
2894
2895     { // Indexed addressing.
2896         Procedure proc;
2897         BasicBlock* root = proc.addBlock();
2898
2899         Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
2900             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2901         Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2902         Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
2903         Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
2904
2905         Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2906         Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2907
2908         root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2909         root->appendNewControlValue(proc, Return, Origin(), value);
2910
2911         int16_t storage = -1;
2912         CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
2913         CHECK(storage == 42);
2914     }
2915 }
2916
2917 void testStore16Imm()
2918 {
2919     { // Direct addressing.
2920         Procedure proc;
2921         BasicBlock* root = proc.addBlock();
2922
2923         Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2924         Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2925
2926         root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2927         root->appendNewControlValue(proc, Return, Origin(), value);
2928
2929         int16_t storage = -1;
2930         CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
2931         CHECK(storage == 42);
2932     }
2933
2934     { // Indexed addressing.
2935         Procedure proc;
2936         BasicBlock* root = proc.addBlock();
2937
2938         Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
2939         Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2940         Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2941         Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
2942
2943         Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
2944         Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
2945
2946         root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
2947         root->appendNewControlValue(proc, Return, Origin(), value);
2948
2949         int16_t storage = -1;
2950         CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
2951         CHECK(storage == 42);
2952     }
2953 }
2954
2955 void testTrunc(int64_t value)
2956 {
2957     Procedure proc;
2958     BasicBlock* root = proc.addBlock();
2959     root->appendNewControlValue(
2960         proc, Return, Origin(),
2961         root->appendNew<Value>(
2962             proc, Trunc, Origin(),
2963             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2964
2965     CHECK(compileAndRun<int>(proc, value) == static_cast<int>(value));
2966 }
2967
2968 void testAdd1(int value)
2969 {
2970     Procedure proc;
2971     BasicBlock* root = proc.addBlock();
2972     root->appendNewControlValue(
2973         proc, Return, Origin(),
2974         root->appendNew<Value>(
2975             proc, Add, Origin(),
2976             root->appendNew<Value>(
2977                 proc, Trunc, Origin(),
2978                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2979             root->appendNew<Const32Value>(proc, Origin(), 1)));
2980
2981     CHECK(compileAndRun<int>(proc, value) == value + 1);
2982 }
2983
2984 void testAdd1Ptr(intptr_t value)
2985 {
2986     Procedure proc;
2987     BasicBlock* root = proc.addBlock();
2988     root->appendNewControlValue(
2989         proc, Return, Origin(),
2990         root->appendNew<Value>(
2991             proc, Add, Origin(),
2992             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2993             root->appendNew<ConstPtrValue>(proc, Origin(), 1)));
2994
2995     CHECK(compileAndRun<intptr_t>(proc, value) == value + 1);
2996 }
2997
2998 void testNeg32(int32_t value)
2999 {
3000     Procedure proc;
3001     BasicBlock* root = proc.addBlock();
3002     root->appendNewControlValue(
3003         proc, Return, Origin(),
3004         root->appendNew<Value>(
3005             proc, Sub, Origin(),
3006             root->appendNew<Const32Value>(proc, Origin(), 0),
3007             root->appendNew<Value>(
3008                 proc, Trunc, Origin(),
3009                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
3010
3011     CHECK(compileAndRun<int32_t>(proc, value) == -value);
3012 }
3013
3014 void testNegPtr(intptr_t value)
3015 {
3016     Procedure proc;
3017     BasicBlock* root = proc.addBlock();
3018     root->appendNewControlValue(
3019         proc, Return, Origin(),
3020         root->appendNew<Value>(
3021             proc, Sub, Origin(),
3022             root->appendNew<ConstPtrValue>(proc, Origin(), 0),
3023             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
3024
3025     CHECK(compileAndRun<intptr_t>(proc, value) == -value);
3026 }
3027
3028 void testStoreAddLoad32(int amount)
3029 {
3030     Procedure proc;
3031     BasicBlock* root = proc.addBlock();
3032     int slot = 37;
3033     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
3034     root->appendNew<MemoryValue>(
3035         proc, Store, Origin(),
3036         root->appendNew<Value>(
3037             proc, Add, Origin(),
3038             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
3039             root->appendNew<Value>(
3040                 proc, Trunc, Origin(),
3041                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
3042         slotPtr, 0);
3043     root->appendNewControlValue(
3044         proc, Return, Origin(),
3045         root->appendNew<Const32Value>(proc, Origin(), 0));
3046
3047     CHECK(!compileAndRun<int>(proc, amount));
3048     CHECK(slot == 37 + amount);
3049 }
3050
3051 // Make sure the compiler does not try to optimize anything out.
3052 static NEVER_INLINE double zero()
3053 {
3054     return 0.;
3055 }
3056
3057 static double negativeZero()
3058 {
3059     return -zero();
3060 }
3061
3062 void addArgTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3063 {
3064     RUN(testAddArg(111));
3065     RUN(testAddArgs(1, 1));
3066     RUN(testAddArgs(1, 2));
3067     RUN(testAddArgImm(1, 2));
3068     RUN(testAddArgImm(0, 2));
3069     RUN(testAddArgImm(1, 0));
3070     RUN(testAddImmArg(1, 2));
3071     RUN(testAddImmArg(0, 2));
3072     RUN(testAddImmArg(1, 0));
3073     RUN_BINARY(testAddArgMem, int64Operands(), int64Operands());
3074     RUN_BINARY(testAddMemArg, int64Operands(), int64Operands());
3075     RUN_BINARY(testAddImmMem, int64Operands(), int64Operands());
3076     RUN_UNARY(testAddArg32, int32Operands());
3077     RUN(testAddArgs32(1, 1));
3078     RUN(testAddArgs32(1, 2));
3079     RUN_BINARY(testAddArgMem32, int32Operands(), int32Operands());
3080     RUN_BINARY(testAddMemArg32, int32Operands(), int32Operands());
3081     RUN_BINARY(testAddImmMem32, int32Operands(), int32Operands());
3082     RUN_BINARY(testAddNeg1, int32Operands(), int32Operands());
3083     RUN_BINARY(testAddNeg2, int32Operands(), int32Operands());
3084     RUN(testAddArgZeroImmZDef());
3085     RUN(testAddLoadTwice());
3086     RUN_TERNARY(testAddMulMulArgs, int64Operands(), int64Operands(), int64Operands());
3087     
3088     RUN(testAddArgDouble(M_PI));
3089     RUN(testAddArgsDouble(M_PI, 1));
3090     RUN(testAddArgsDouble(M_PI, -M_PI));
3091     RUN(testAddArgImmDouble(M_PI, 1));
3092     RUN(testAddArgImmDouble(M_PI, 0));
3093     RUN(testAddArgImmDouble(M_PI, negativeZero()));
3094     RUN(testAddArgImmDouble(0, 0));
3095     RUN(testAddArgImmDouble(0, negativeZero()));
3096     RUN(testAddArgImmDouble(negativeZero(), 0));
3097     RUN(testAddArgImmDouble(negativeZero(), negativeZero()));
3098     RUN(testAddImmArgDouble(M_PI, 1));
3099     RUN(testAddImmArgDouble(M_PI, 0));
3100     RUN(testAddImmArgDouble(M_PI, negativeZero()));
3101     RUN(testAddImmArgDouble(0, 0));
3102     RUN(testAddImmArgDouble(0, negativeZero()));
3103     RUN(testAddImmArgDouble(negativeZero(), 0));
3104     RUN(testAddImmArgDouble(negativeZero(), negativeZero()));
3105     RUN(testAddImmsDouble(M_PI, 1));
3106     RUN(testAddImmsDouble(M_PI, 0));
3107     RUN(testAddImmsDouble(M_PI, negativeZero()));
3108     RUN(testAddImmsDouble(0, 0));
3109     RUN(testAddImmsDouble(0, negativeZero()));
3110     RUN(testAddImmsDouble(negativeZero(), negativeZero()));
3111     RUN_UNARY(testAddArgFloat, floatingPointOperands<float>());
3112     RUN_BINARY(testAddArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3113     RUN_BINARY(testAddFPRArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3114     RUN_BINARY(testAddArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3115     RUN_BINARY(testAddImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3116     RUN_BINARY(testAddImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3117     RUN_UNARY(testAddArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3118     RUN_BINARY(testAddArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3119     RUN_BINARY(testAddArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3120     
3121     RUN(testMulArg(5));
3122     RUN(testMulAddArg(5));
3123     RUN(testMulAddArg(85));
3124     RUN(testMulArgStore(5));
3125     RUN(testMulArgStore(85));
3126     RUN(testMulArgs(1, 1));
3127     RUN(testMulArgs(1, 2));
3128     RUN(testMulArgs(3, 3));
3129     RUN(testMulArgImm(1, 2));
3130     RUN(testMulArgImm(1, 4));
3131     RUN(testMulArgImm(1, 8));
3132     RUN(testMulArgImm(1, 16));
3133     RUN(testMulArgImm(1, 0x80000000llu));
3134     RUN(testMulArgImm(1, 0x800000000000llu));
3135     RUN(testMulArgImm(7, 2));
3136     RUN(testMulArgImm(7, 4));
3137     RUN(testMulArgImm(7, 8));
3138     RUN(testMulArgImm(7, 16));
3139     RUN(testMulArgImm(7, 0x80000000llu));
3140     RUN(testMulArgImm(7, 0x800000000000llu));
3141     RUN(testMulArgImm(-42, 2));
3142     RUN(testMulArgImm(-42, 4));
3143     RUN(testMulArgImm(-42, 8));
3144     RUN(testMulArgImm(-42, 16));
3145     RUN(testMulArgImm(-42, 0x80000000llu));
3146     RUN(testMulArgImm(-42, 0x800000000000llu));
3147     RUN(testMulArgImm(0, 2));
3148     RUN(testMulArgImm(1, 0));
3149     RUN(testMulArgImm(3, 3));
3150     RUN(testMulArgImm(3, -1));
3151     RUN(testMulArgImm(-3, -1));
3152     RUN(testMulArgImm(0, -1));
3153     RUN(testMulImmArg(1, 2));
3154     RUN(testMulImmArg(0, 2));
3155     RUN(testMulImmArg(1, 0));
3156     RUN(testMulImmArg(3, 3));
3157     RUN_BINARY(testMulImm32SignExtend, int32Operands(), int32Operands());
3158     RUN(testMulImm32SignExtend(0xFFFFFFFE, 0xFFFFFFFF));
3159     RUN(testMulImm32SignExtend(0xFFFFFFFF, 0xFFFFFFFE));
3160     RUN(testMulArgs32(1, 1));
3161     RUN(testMulArgs32(1, 2));
3162     RUN(testMulArgs32(0xFFFFFFFF, 0xFFFFFFFF));
3163     RUN(testMulArgs32(0xFFFFFFFE, 0xFFFFFFFF));
3164     RUN(testMulArgs32SignExtend(1, 1));
3165     RUN(testMulArgs32SignExtend(1, 2));
3166     RUN(testMulArgs32SignExtend(0xFFFFFFFF, 0xFFFFFFFF));
3167     RUN(testMulArgs32SignExtend(0xFFFFFFFE, 0xFFFFFFFF));
3168     RUN(testMulLoadTwice());
3169     RUN(testMulAddArgsLeft());
3170     RUN(testMulAddArgsRight());
3171     RUN(testMulAddArgsLeft32());
3172     RUN(testMulAddArgsRight32());
3173     RUN(testMulSubArgsLeft());
3174     RUN(testMulSubArgsRight());
3175     RUN(testMulSubArgsLeft32());
3176     RUN(testMulSubArgsRight32());
3177     RUN(testMulNegArgs());
3178     RUN(testMulNegArgs32());
3179     
3180     RUN_BINARY(testMulArgNegArg, int64Operands(), int64Operands())
3181     RUN_BINARY(testMulNegArgArg, int64Operands(), int64Operands())
3182     RUN_UNARY(testMulArgDouble, floatingPointOperands<double>());
3183     RUN_BINARY(testMulArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3184     RUN_BINARY(testMulArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3185     RUN_BINARY(testMulImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3186     RUN_BINARY(testMulImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3187     RUN_UNARY(testMulArgFloat, floatingPointOperands<float>());
3188     RUN_BINARY(testMulArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3189     RUN_BINARY(testMulArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3190     RUN_BINARY(testMulImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3191     RUN_BINARY(testMulImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3192     RUN_UNARY(testMulArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3193     RUN_BINARY(testMulArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3194     RUN_BINARY(testMulArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3195     
3196     RUN(testDivArgDouble(M_PI));
3197     RUN(testDivArgsDouble(M_PI, 1));
3198     RUN(testDivArgsDouble(M_PI, -M_PI));
3199     RUN(testDivArgImmDouble(M_PI, 1));
3200     RUN(testDivArgImmDouble(M_PI, 0));
3201     RUN(testDivArgImmDouble(M_PI, negativeZero()));
3202     RUN(testDivArgImmDouble(0, 0));
3203     RUN(testDivArgImmDouble(0, negativeZero()));
3204     RUN(testDivArgImmDouble(negativeZero(), 0));
3205     RUN(testDivArgImmDouble(negativeZero(), negativeZero()));
3206     RUN(testDivImmArgDouble(M_PI, 1));
3207     RUN(testDivImmArgDouble(M_PI, 0));
3208     RUN(testDivImmArgDouble(M_PI, negativeZero()));
3209     RUN(testDivImmArgDouble(0, 0));
3210     RUN(testDivImmArgDouble(0, negativeZero()));
3211     RUN(testDivImmArgDouble(negativeZero(), 0));
3212     RUN(testDivImmArgDouble(negativeZero(), negativeZero()));
3213     RUN(testDivImmsDouble(M_PI, 1));
3214     RUN(testDivImmsDouble(M_PI, 0));
3215     RUN(testDivImmsDouble(M_PI, negativeZero()));
3216     RUN(testDivImmsDouble(0, 0));
3217     RUN(testDivImmsDouble(0, negativeZero()));
3218     RUN(testDivImmsDouble(negativeZero(), negativeZero()));
3219     RUN_UNARY(testDivArgFloat, floatingPointOperands<float>());
3220     RUN_BINARY(testDivArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3221     RUN_BINARY(testDivArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3222     RUN_BINARY(testDivImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3223     RUN_BINARY(testDivImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3224     RUN_UNARY(testDivArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3225     RUN_BINARY(testDivArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3226     RUN_BINARY(testDivArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3227     
3228     RUN_BINARY(testUDivArgsInt32, int32Operands(), int32Operands());
3229     RUN_BINARY(testUDivArgsInt64, int64Operands(), int64Operands());
3230     
3231     RUN_UNARY(testModArgDouble, floatingPointOperands<double>());
3232     RUN_BINARY(testModArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3233     RUN_BINARY(testModArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3234     RUN_BINARY(testModImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3235     RUN_BINARY(testModImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3236     RUN_UNARY(testModArgFloat, floatingPointOperands<float>());
3237     RUN_BINARY(testModArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3238     RUN_BINARY(testModArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3239     RUN_BINARY(testModImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3240     RUN_BINARY(testModImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3241     
3242     RUN_BINARY(testUModArgsInt32, int32Operands(), int32Operands());
3243     RUN_BINARY(testUModArgsInt64, int64Operands(), int64Operands());
3244     
3245     RUN(testSubArg(24));
3246     RUN(testSubArgs(1, 1));
3247     RUN(testSubArgs(1, 2));
3248     RUN(testSubArgs(13, -42));
3249     RUN(testSubArgs(-13, 42));
3250     RUN(testSubArgImm(1, 1));
3251     RUN(testSubArgImm(1, 2));
3252     RUN(testSubArgImm(13, -42));
3253     RUN(testSubArgImm(-13, 42));
3254     RUN(testSubArgImm(42, 0));
3255     RUN(testSubImmArg(1, 1));
3256     RUN(testSubImmArg(1, 2));
3257     RUN(testSubImmArg(13, -42));
3258     RUN(testSubImmArg(-13, 42));
3259     RUN_BINARY(testSubArgMem, int64Operands(), int64Operands());
3260     RUN_BINARY(testSubMemArg, int64Operands(), int64Operands());
3261     RUN_BINARY(testSubImmMem, int32Operands(), int32Operands());
3262     RUN_BINARY(testSubMemImm, int32Operands(), int32Operands());
3263     RUN_BINARY(testSubNeg, int32Operands(), int32Operands());
3264     RUN_BINARY(testNegSub, int32Operands(), int32Operands());
3265     RUN_UNARY(testNegValueSubOne, int32Operands());
3266     RUN_BINARY(testNegMulArgImm, int64Operands(), int64Operands());
3267     RUN_TERNARY(testSubMulMulArgs, int64Operands(), int64Operands(), int64Operands());
3268     
3269     RUN_TERNARY(testSubSub, int32Operands(), int32Operands(), int32Operands());
3270     RUN_TERNARY(testSubSub2, int32Operands(), int32Operands(), int32Operands());
3271     RUN_TERNARY(testSubAdd, int32Operands(), int32Operands(), int32Operands());
3272     RUN_BINARY(testSubFirstNeg, int32Operands(), int32Operands());
3273     
3274     RUN(testSubArgs32(1, 1));
3275     RUN(testSubArgs32(1, 2));
3276     RUN(testSubArgs32(13, -42));
3277     RUN(testSubArgs32(-13, 42));
3278     RUN(testSubArgImm32(1, 1));
3279     RUN(testSubArgImm32(1, 2));
3280     RUN(testSubArgImm32(13, -42));
3281     RUN(testSubArgImm32(-13, 42));
3282     RUN(testSubImmArg32(1, 1));
3283     RUN(testSubImmArg32(1, 2));
3284     RUN(testSubImmArg32(13, -42));
3285     RUN(testSubImmArg32(-13, 42));
3286     RUN_BINARY(testSubArgMem32, int32Operands(), int32Operands());
3287     RUN_BINARY(testSubMemArg32, int32Operands(), int32Operands());
3288     RUN_BINARY(testSubImmMem32, int32Operands(), int32Operands());
3289     RUN_BINARY(testSubMemImm32, int32Operands(), int32Operands());
3290     RUN_UNARY(testNegValueSubOne32, int64Operands());
3291     
3292     RUN_UNARY(testSubArgDouble, floatingPointOperands<double>());
3293     RUN_BINARY(testSubArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3294     RUN_BINARY(testSubArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3295     RUN_BINARY(testSubImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3296     RUN_BINARY(testSubImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
3297     RUN_UNARY(testSubArgFloat, floatingPointOperands<float>());
3298     RUN_BINARY(testSubArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3299     RUN_BINARY(testSubArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3300     RUN_BINARY(testSubImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3301     RUN_BINARY(testSubImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3302     RUN_UNARY(testSubArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
3303     RUN_BINARY(testSubArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3304     RUN_BINARY(testSubArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
3305 }
3306
3307 void addCallTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3308 {
3309     RUN(testCallSimple(1, 2));
3310     RUN(testCallRare(1, 2));
3311     RUN(testCallRareLive(1, 2, 3));
3312     RUN(testCallSimplePure(1, 2));
3313     RUN(testCallFunctionWithHellaArguments());
3314     RUN(testCallFunctionWithHellaArguments2());
3315     RUN(testCallFunctionWithHellaArguments3());
3316     
3317     RUN(testReturnDouble(0.0));
3318     RUN(testReturnDouble(negativeZero()));
3319     RUN(testReturnDouble(42.5));
3320     RUN_UNARY(testReturnFloat, floatingPointOperands<float>());
3321     
3322     RUN(testCallSimpleDouble(1, 2));
3323     RUN(testCallFunctionWithHellaDoubleArguments());
3324     RUN_BINARY(testCallSimpleFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
3325     RUN(testCallFunctionWithHellaFloatArguments());
3326 }
3327
3328 void addShrTests(const char* filter, Deque<RefPtr<SharedTask<void()>>>& tasks)
3329 {
3330     RUN(testSShrArgs(1, 0));
3331     RUN(testSShrArgs(1, 1));
3332     RUN(testSShrArgs(1, 62));
3333     RUN(testSShrArgs(0xffffffffffffffff, 0));
3334     RUN(testSShrArgs(0xffffffffffffffff, 1));
3335     RUN(testSShrArgs(0xffffffffffffffff, 63));
3336     RUN(testSShrImms(1, 0));
3337     RUN(testSShrImms(1, 1));
3338     RUN(testSShrImms(1, 62));
3339     RUN(testSShrImms(1, 65));
3340     RUN(testSShrImms(0xffffffffffffffff, 0));
3341     RUN(testSShrImms(0xffffffffffffffff, 1));
3342     RUN(testSShrImms(0xffffffffffffffff, 63));
3343     RUN(testSShrArgImm(1, 0));
3344     RUN(testSShrArgImm(1, 1));
3345     RUN(testSShrArgImm(1, 62));
3346     RUN(testSShrArgImm(1, 65));
3347     RUN(testSShrArgImm(0xffffffffffffffff, 0));
3348     RUN(testSShrArgImm(0xffffffffffffffff, 1));
3349     RUN(testSShrArgImm(0xffffffffffffffff, 63));
3350     RUN(testSShrArg32(32));
3351     RUN(testSShrArgs32(1, 0));
3352     RUN(testSShrArgs32(1, 1));
3353     RUN(testSShrArgs32(1, 62));
3354     RUN(testSShrArgs32(1, 33));
3355     RUN(testSShrArgs32(0xffffffff, 0));
3356     RUN(testSShrArgs32(0xffffffff, 1));
3357     RUN(testSShrArgs32(0xffffffff, 63));
3358     RUN(testSShrImms32(1, 0));
3359     RUN(testSShrImms32(1, 1));
3360     RUN(testSShrImms32(1, 62));
3361     RUN(testSShrImms32(1, 33));
3362     RUN(testSShrImms32(0xffffffff, 0));
3363     RUN(testSShrImms32(0xffffffff, 1));
3364     RUN(testSShrImms32(0xffffffff, 63));
3365     RUN(testSShrArgImm32(1, 0));
3366     RUN(testSShrArgImm32(1, 1));
3367     RUN(testSShrArgImm32(1, 62));
3368     RUN(testSShrArgImm32(0xffffffff, 0));
3369     RUN(testSShrArgImm32(0xffffffff, 1));
3370     RUN(testSShrArgImm32(0xffffffff, 63));
3371     
3372     RUN(testZShrArgs(1, 0));
3373     RUN(testZShrArgs(1, 1));
3374     RUN(testZShrArgs(1, 62));
3375     RUN(testZShrArgs(0xffffffffffffffff, 0));
3376     RUN(testZShrArgs(0xffffffffffffffff, 1));
3377     RUN(testZShrArgs(0xffffffffffffffff, 63));
3378     RUN(testZShrImms(1, 0));
3379     RUN(testZShrImms(1, 1));
3380     RUN(testZShrImms(1, 62));
3381     RUN(testZShrImms(1, 65));
3382     RUN(testZShrImms(0xffffffffffffffff, 0));
3383     RUN(testZShrImms(0xffffffffffffffff, 1));
3384     RUN(testZShrImms(0xffffffffffffffff, 63));
3385     RUN(testZShrArgImm(1, 0));
3386     RUN(testZShrArgImm(1, 1));
3387     RUN(testZShrArgImm(1, 62));
3388     RUN(testZShrArgImm(1, 65));
3389     RUN(testZShrArgImm(0xffffffffffffffff, 0));
3390     RUN(testZShrArgImm(0xffffffffffffffff, 1));
3391     RUN(testZShrArgImm(0xffffffffffffffff, 63));
3392     RUN(testZShrArg32(32));
3393     RUN(testZShrArgs32(1, 0));
3394     RUN(testZShrArgs32(1, 1));
3395     RUN(testZShrArgs32(1, 62));
3396     RUN(testZShrArgs32(1, 33));
3397     RUN(testZShrArgs32(0xffffffff, 0));
3398     RUN(testZShrArgs32(0xffffffff, 1));
3399     RUN(testZShrArgs32(0xffffffff, 63));
3400     RUN(testZShrImms32(1, 0));
3401     RUN(testZShrImms32(1, 1));
3402     RUN(testZShrImms32(1, 62));
3403     RUN(testZShrImms32(1, 33));
3404     RUN(testZShrImms32(0xffffffff, 0));
3405     RUN(testZShrImms32(0xffffffff, 1));
3406     RUN(testZShrImms32(0xffffffff, 63));
3407     RUN(testZShrArgImm32(1, 0));
3408     RUN(testZShrArgImm32(1, 1));
3409     RUN(testZShrArgImm32(1, 62));
3410     RUN(testZShrArgImm32(0xffffffff, 0));
3411     RUN(testZShrArgImm32(0xffffffff, 1));
3412     RUN(testZShrArgImm32(0xffffffff, 63));
3413 }
3414
3415 #endif // ENABLE(B3_JIT)