[JSC] Do not use asArrayModes() with Structures because it discards TypedArray inform...
[WebKit-https.git] / JSTests / stress / arith-sinh-on-various-types.js
1 //@ skip if not $jitTests
2 //@ defaultNoEagerRun
3 "use strict";
4
5 let sinhOfFour = Math.sinh(4);
6
7 let validInputTestCases = [
8     // input as string, expected result as string.
9     ["undefined", "NaN"],
10     ["null", "0"],
11     ["0", "0"],
12     ["-0.", "-0"],
13     ["4", "" + sinhOfFour],
14     ["Math.PI", "" + Math.sinh(Math.PI)],
15     ["Infinity", "Infinity"],
16     ["-Infinity", "-Infinity"],
17     ["NaN", "NaN"],
18     ["\"WebKit\"", "NaN"],
19     ["\"4\"", "" + sinhOfFour],
20     ["{ valueOf: () => { return 4; } }", "" + sinhOfFour],
21 ];
22
23 let validInputTypedTestCases = validInputTestCases.map((element) => { return [eval("(" + element[0] + ")"), eval(element[1])] });
24
25 function isIdentical(result, expected)
26 {
27     if (expected === expected) {
28         if (result !== expected)
29             return false;
30         if (!expected)
31             return (1 / expected) === (1 / result);
32
33         return true;
34     }
35     return result !== result;
36 }
37
38
39 // Test Math.sinh() without arguments.
40 function opaqueSinhNoArgument() {
41     return Math.sinh();
42 }
43 noInline(opaqueSinhNoArgument);
44 noOSRExitFuzzing(opaqueSinhNoArgument);
45
46 function testNoArgument() {
47     for (let i = 0; i < 1e4; ++i) {
48         let output = opaqueSinhNoArgument();
49         if (output === output) {
50             throw "Failed opaqueSinhNoArgument";
51         }
52     }
53     if (numberOfDFGCompiles(opaqueSinhNoArgument) > 1)
54         throw "The call without arguments should never exit.";
55 }
56 testNoArgument();
57
58
59 // Test Math.sinh() with a very polymorphic input. All test cases are seen at each iteration.
60 function opaqueAllTypesSinh(argument) {
61     return Math.sinh(argument);
62 }
63 noInline(opaqueAllTypesSinh);
64 noOSRExitFuzzing(opaqueAllTypesSinh);
65
66 function testAllTypesCall() {
67     for (let i = 0; i < 1e3; ++i) {
68         for (let testCaseInput of validInputTypedTestCases) {
69             let output = opaqueAllTypesSinh(testCaseInput[0]);
70             if (!isIdentical(output, testCaseInput[1]))
71                 throw "Failed testAllTypesCall for input " + testCaseInput[0] + " expected " + testCaseInput[1] + " got " + output;
72         }
73     }
74     if (numberOfDFGCompiles(opaqueAllTypesSinh) > 2)
75         throw "We should have detected sinh() was polymorphic and generated a generic version.";
76 }
77 testAllTypesCall();
78
79
80 // Test Math.sinh() on a completely typed input. Every call see only one type.
81 function testSingleTypeCall() {
82     for (let testCaseInput of validInputTestCases) {
83         eval(`
84             function opaqueSinh(argument) {
85                 return Math.sinh(argument);
86             }
87             noInline(opaqueSinh);
88             noOSRExitFuzzing(opaqueSinh);
89
90             for (let i = 0; i < 1e4; ++i) {
91                 if (!isIdentical(opaqueSinh(${testCaseInput[0]}), ${testCaseInput[1]})) {
92                     throw "Failed testSingleTypeCall()";
93                 }
94             }
95             if (numberOfDFGCompiles(opaqueSinh) > 1)
96                 throw "We should have compiled a single sinh for the expected type.";
97         `);
98     }
99 }
100 testSingleTypeCall();
101
102
103 // Test Math.sinh() on constants
104 function testConstant() {
105     for (let testCaseInput of validInputTestCases) {
106         eval(`
107             function opaqueSinhOnConstant() {
108                 return Math.sinh(${testCaseInput[0]});
109             }
110             noInline(opaqueSinhOnConstant);
111             noOSRExitFuzzing(opaqueSinhOnConstant);
112
113             for (let i = 0; i < 1e4; ++i) {
114                 if (!isIdentical(opaqueSinhOnConstant(), ${testCaseInput[1]})) {
115                     throw "Failed testConstant()";
116                 }
117             }
118             if (numberOfDFGCompiles(opaqueSinhOnConstant) > 1)
119                 throw "We should have compiled a single sinh for the expected type.";
120         `);
121     }
122 }
123 testConstant();
124
125
126 // Verify we call valueOf() exactly once per call.
127 function opaqueSinhForSideEffects(argument) {
128     return Math.sinh(argument);
129 }
130 noInline(opaqueSinhForSideEffects);
131 noOSRExitFuzzing(opaqueSinhForSideEffects);
132
133 function testSideEffect() {
134     let testObject = {
135         counter: 0,
136         valueOf: function() { ++this.counter; return 16; }
137     };
138     let sinh16 = Math.sinh(16);
139     for (let i = 0; i < 1e4; ++i) {
140         if (opaqueSinhForSideEffects(testObject) !== sinh16)
141             throw "Incorrect result in testSideEffect()";
142     }
143     if (testObject.counter !== 1e4)
144         throw "Failed testSideEffect()";
145     if (numberOfDFGCompiles(opaqueSinhForSideEffects) > 1)
146         throw "opaqueSinhForSideEffects() is predictable, it should only be compiled once.";
147 }
148 testSideEffect();
149
150
151 // Verify sinh() is not subject to CSE if the argument has side effects.
152 function opaqueSinhForCSE(argument) {
153     return Math.sinh(argument) + Math.sinh(argument) + Math.sinh(argument);
154 }
155 noInline(opaqueSinhForCSE);
156 noOSRExitFuzzing(opaqueSinhForCSE);
157
158 function testCSE() {
159     let testObject = {
160         counter: 0,
161         valueOf: function() { ++this.counter; return 16; }
162     };
163     let sinh16 = Math.sinh(16);
164     let threeSinh16 = sinh16 + sinh16 + sinh16;
165     for (let i = 0; i < 1e4; ++i) {
166         if (opaqueSinhForCSE(testObject) !== threeSinh16)
167             throw "Incorrect result in testCSE()";
168     }
169     if (testObject.counter !== 3e4)
170         throw "Failed testCSE()";
171     if (numberOfDFGCompiles(opaqueSinhForCSE) > 1)
172         throw "opaqueSinhForCSE() is predictable, it should only be compiled once.";
173 }
174 testCSE();
175
176
177 // Verify sinh() is not subject to DCE if the argument has side effects.
178 function opaqueSinhForDCE(argument) {
179     Math.sinh(argument);
180 }
181 noInline(opaqueSinhForDCE);
182 noOSRExitFuzzing(opaqueSinhForDCE);
183
184 function testDCE() {
185     let testObject = {
186         counter: 0,
187         valueOf: function() { ++this.counter; return 16; }
188     };
189     for (let i = 0; i < 1e4; ++i) {
190         opaqueSinhForDCE(testObject);
191     }
192     if (testObject.counter !== 1e4)
193         throw "Failed testDCE()";
194     if (numberOfDFGCompiles(opaqueSinhForDCE) > 1)
195         throw "opaqueSinhForDCE() is predictable, it should only be compiled once.";
196 }
197 testDCE();
198
199
200 // Test exceptions in the argument.
201 function testException() {
202     let counter = 0;
203     function opaqueSinhWithException(argument) {
204         let result = Math.sinh(argument);
205         ++counter;
206         return result;
207     }
208     noInline(opaqueSinhWithException);
209
210     let testObject = { valueOf: () => {  return 64; } };
211     let sinh64 = Math.sinh(64);
212
213     // Warm up without exception.
214     for (let i = 0; i < 1e3; ++i) {
215         if (opaqueSinhWithException(testObject) !== sinh64)
216             throw "Incorrect result in opaqueSinhWithException()";
217     }
218
219     let testThrowObject = { valueOf: () => { throw testObject; return 64; } };
220
221     for (let i = 0; i < 1e2; ++i) {
222         try {
223             if (opaqueSinhWithException(testThrowObject) !== 8)
224                 throw "This code should not be reached!!";
225         } catch (e) {
226             if (e !== testObject) {
227                 throw "Wrong object thrown from opaqueSinhWithException."
228             }
229         }
230     }
231
232     if (counter !== 1e3) {
233         throw "Invalid count in testException()";
234     }
235 }
236 testException();