[JSC] Do not use asArrayModes() with Structures because it discards TypedArray inform...
[WebKit-https.git] / JSTests / stress / double-to-float.js
1 function upsilonReferencingItsPhi(index, input)
2 {
3     // All uses of "outputDouble" are converted to float.
4     // Inside the loop, the Upsilon is referencing its own Phi. This should
5     // not prevent the conversion.
6     let outputDouble = input;
7     while (index) {
8         if (index & 0x4)
9             outputDouble = Math.fround(outputDouble) + Math.PI;
10         index = index >>> 1;
11     }
12     return Math.fround(outputDouble);
13 }
14 noInline(upsilonReferencingItsPhi);
15
16 let expectedNotTaken = Math.fround(Math.LN2);
17 let expectedTaken = Math.fround(Math.fround(Math.LN2) + Math.PI);
18 for (let i = 0; i < 1e6; ++i) {
19     let branchNotTakenResult = upsilonReferencingItsPhi(3, Math.LN2);
20     if (branchNotTakenResult !== expectedNotTaken)
21         throw "Failed upsilonReferencingItsPhi(3, Math.LN2) at i = " + i + " result = " + branchNotTakenResult;
22
23     let branchTakenResult = upsilonReferencingItsPhi(7, Math.LN2);
24     if (branchTakenResult !== expectedTaken)
25         throw "Failed upsilonReferencingItsPhi(7, Math.LN2) at i = " + i + " result = " + branchTakenResult;
26 }
27
28 // Same as above, but this time it is always better to convert the outside Phi-Upsilon.
29 function upsilonReferencingItsPhiAllFloat(index, input)
30 {
31     let outputDouble = Math.fround(input);
32     while (index) {
33         if (index & 0x4)
34             outputDouble = Math.fround(outputDouble) + Math.PI;
35         index = index >>> 1;
36     }
37     return Math.fround(outputDouble);
38 }
39 noInline(upsilonReferencingItsPhiAllFloat);
40
41 for (let i = 0; i < 1e6; ++i) {
42     let branchNotTakenResult = upsilonReferencingItsPhiAllFloat(3, Math.LN2);
43     if (branchNotTakenResult !== expectedNotTaken)
44         throw "Failed upsilonReferencingItsPhiAllFloat(3, Math.LN2) at i = " + i + " result = " + branchNotTakenResult;
45
46     let branchTakenResult = upsilonReferencingItsPhiAllFloat(7, Math.LN2);
47     if (branchTakenResult !== expectedTaken)
48         throw "Failed upsilonReferencingItsPhiAllFloat(7, Math.LN2) at i = " + i + " result = " + branchTakenResult;
49 }
50
51 // This time, converting to float would be a mistake because one of the Phi
52 // is not converted.
53 function upsilonReferencingItsPhiWithoutConversion(index, input)
54 {
55     let outputDouble = input;
56     while (index) {
57         if (index & 0x4)
58             outputDouble = Math.fround(outputDouble) + Math.PI;
59         index = index >>> 1;
60     }
61     return outputDouble;
62 }
63 noInline(upsilonReferencingItsPhiWithoutConversion);
64
65 let expectedNotTakenWithoutConversion = Math.LN2;
66 let expectedTakenWithoutConversion = Math.fround(Math.LN2) + Math.PI;
67 for (let i = 0; i < 1e6; ++i) {
68     let branchNotTakenResult = upsilonReferencingItsPhiWithoutConversion(3, Math.LN2);
69     if (branchNotTakenResult !== expectedNotTakenWithoutConversion)
70         throw "Failed upsilonReferencingItsPhiWithoutConversion(3, Math.LN2) at i = " + i + " result = " + branchNotTakenResult;
71
72     let branchTakenResult = upsilonReferencingItsPhiWithoutConversion(7, Math.LN2);
73     if (branchTakenResult !== expectedTakenWithoutConversion)
74         throw "Failed upsilonReferencingItsPhiWithoutConversion(7, Math.LN2) at i = " + i + " result = " + branchTakenResult;
75 }
76
77 function conversionPropagages(flags, a, b)
78 {
79     let result = 0.5;
80     if (flags & 0x1) {
81         if (flags & 0x2) {
82             if (flags & 0x4) {
83                 if (flags & 0x8) {
84                     result = Math.fround(a) + Math.fround(b);
85                 } else {
86                     result = 6.5;
87                 }
88             } else {
89                 result = 4.5;
90             }
91         } else {
92             result = 2.5;
93         }
94     } else {
95         result = 1.5;
96     }
97     return Math.fround(result);
98 }
99 noInline(conversionPropagages);
100
101 let conversionPropagageExpectedResult = Math.fround(Math.fround(Math.LN2) + Math.fround(Math.PI));
102 for (let i = 0; i < 1e6; ++i) {
103     let result = conversionPropagages(0xf, Math.LN2, Math.PI);
104     if (result !== conversionPropagageExpectedResult)
105         throw "Failed conversionPropagages(0xf, Math.LN2, Math.PI)";
106 }
107
108
109 function chainedUpsilonBothConvert(condition1, condition2, a, b)
110 {
111     let firstPhi;
112     if (condition1)
113         firstPhi = Math.fround(a);
114     else
115         firstPhi = Math.fround(b);
116
117     let secondPhi;
118     if (condition2)
119         secondPhi = firstPhi + 2;
120     else
121         secondPhi = firstPhi + 1;
122     return Math.fround(secondPhi);
123 }
124 noInline(chainedUpsilonBothConvert);
125
126 let expectedChainedUpsilonBothConvert = Math.fround(Math.fround(Math.PI) + Math.fround(1));
127 for (let i = 0; i < 1e6; ++i) {
128     if (chainedUpsilonBothConvert(1, 0, Math.PI, Math.LN2) !== expectedChainedUpsilonBothConvert)
129         throw "Failed chainedUpsilonBothConvert(1, 0, Math.PI, Math.LN2)";
130 }
131
132 function chainedUpsilonFirstConvert(condition1, condition2, a, b)
133 {
134     // This first phi is trivially simplified by the fround()
135     // of the second if-else.
136     let firstPhi;
137     if (condition1)
138         firstPhi = Math.fround(a);
139     else
140         firstPhi = Math.fround(b);
141
142     // This second one cannot ever be converted because the
143     // result is not rounded to float.
144     let secondPhi;
145     if (condition2)
146         secondPhi = Math.fround(firstPhi) + Math.fround(1/3);
147     else
148         secondPhi = Math.fround(firstPhi) - Math.fround(1/3);
149     return secondPhi;
150 }
151 noInline(chainedUpsilonFirstConvert);
152
153 let expectedChainedUpsilonFirstConvert = Math.fround(Math.PI) - Math.fround(1/3);
154 for (let i = 0; i < 1e6; ++i) {
155     if (chainedUpsilonFirstConvert(1, 0, Math.PI, Math.LN2) !== expectedChainedUpsilonFirstConvert)
156         throw "Failed chainedUpsilonFirstConvert(1, 0, Math.PI, Math.LN2)";
157 }