1/*
2 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.jtt.optimize;
24
25import java.util.HashMap;
26import java.util.HashSet;
27import java.util.LinkedList;
28
29import org.junit.Test;
30
31import org.graalvm.compiler.jtt.JTTTest;
32
33/*
34 * Tests optimization of switches.
35 */
36public class Switch02 extends JTTTest {
37    private static char staticCharVal = 0;
38    private static short staticShortVal = 0;
39    private static byte staticByteVal = 0;
40
41    public static int test(int arg) {
42        switch (arg) {
43            case 1:
44                return 2;
45            default:
46                return 1;
47        }
48    }
49
50    public static int test2char(char arg) {
51        int result = 392123;
52        Object x = null;
53        char val = staticCharVal != 0 ? staticCharVal : arg;
54        switch (val) {
55            case (char) 0xFFFF:
56                result = 23212 / val;
57                break;
58            case (char) 0xFFFF - 3:
59                result = 932991439 / val;
60                break;
61            case (char) 0xFFFF - 6:
62                result = 47329561 / val;
63                break;
64            case (char) 0xFFFF - 9:
65                result = 1950976984 / val;
66                break;
67            case (char) 0xFFFF - 10:
68                result = 97105581 / val;
69                switch (result) {
70                    case 1:
71                        result = 321;
72                        break;
73                    default:
74                        result = 2391;
75                        break;
76                }
77                break;
78            case (char) 0xFFFF - 12:
79                result = 99757362 / val;
80                break;
81            case (char) 0xFFFF - 15:
82                result = 912573 / val;
83                x = new LinkedList<>();
84                break;
85            case (char) 0xFFFF - 18:
86                x = new HashSet<>();
87                result = 876765 / val;
88                break;
89            case (char) 0xFFFF - 19:
90                result = 75442917 / val;
91                break;
92            case (char) 0xFFFF - 21:
93                result = 858112498 / val;
94                x = new HashMap<>();
95                break;
96            default:
97                result = 34324341 / val;
98        }
99        result = result + (x == null ? 0 : x.hashCode());
100        return result;
101    }
102
103    public static int test2short(short arg) {
104        int result = 392123;
105        Object x = null;
106        short val = staticShortVal != 0 ? staticShortVal : arg;
107        switch (val) {
108            case (short) -0x7FFF:
109                result = 23212 / val;
110                break;
111            case (short) -0x7FFF + 3:
112                result = 932991439 / val;
113                break;
114            case (short) -0x7FFF + 6:
115                result = 47329561 / val;
116                break;
117            case (short) -0x7FFF + 9:
118                result = 1950976984 / val;
119                break;
120            case (short) -0x7FFF + 10:
121                result = 97105581 / val;
122                switch (result) {
123                    case 1:
124                        result = 321;
125                        break;
126                    default:
127                        result = 2391;
128                        break;
129                }
130                break;
131            case (short) -0x7FFF + 12:
132                result = 99757362 / val;
133                break;
134            case (short) -0x7FFF + 15:
135                result = 912573 / val;
136                x = new LinkedList<>();
137                break;
138            case (short) -0x7FFF + 18:
139                x = new HashSet<>();
140                result = 876765 / val;
141                break;
142            case (short) -0x7FFF + 19:
143                result = 75442917 / val;
144                break;
145            case (short) -0x7FFF + 21:
146                result = 858112498 / val;
147                x = new HashMap<>();
148                break;
149            default:
150                result = 34324341 / val;
151        }
152        result = result + (x == null ? 0 : x.hashCode());
153        return result;
154    }
155
156    public static int test2byte(byte arg) {
157        int result = 392123;
158        Object x = null;
159        byte val = staticByteVal != 0 ? staticByteVal : arg;
160        switch (val) {
161            case (byte) -0x7F:
162                result = 23212 / val;
163                break;
164            case (byte) -0x7F + 3:
165                result = 932991439 / val;
166                break;
167            case (byte) -0x7F + 6:
168                result = 47329561 / val;
169                break;
170            case (byte) -0x7F + 9:
171                result = 1950976984 / val;
172                break;
173            case (byte) -0x7F + 10:
174                result = 97105581 / val;
175                switch (result) {
176                    case 1:
177                        result = 321;
178                        break;
179                    default:
180                        result = 2391;
181                        break;
182                }
183                break;
184            case (byte) -0x7F + 12:
185                result = 99757362 / val;
186                break;
187            case (byte) -0x7F + 15:
188                result = 912573 / val;
189                x = new LinkedList<>();
190                break;
191            case (byte) -0x7F + 18:
192                x = new HashSet<>();
193                result = 876765 / val;
194                break;
195            case (byte) -0x7F + 19:
196                result = 75442917 / val;
197                break;
198            case (byte) -0x7F + 20:
199                result = 856261268 / val;
200                break;
201            case (byte) -0x7F + 21:
202                result = 858112498 / val;
203                x = new HashMap<>();
204                break;
205            default:
206                result = 34324341 / val;
207        }
208        result = result + (x == null ? 0 : x.hashCode());
209        return result;
210    }
211
212    @Test
213    public void run0() throws Throwable {
214        runTest("test", 0);
215    }
216
217    @Test
218    public void run1() throws Throwable {
219        runTest("test", 1);
220    }
221
222    @Test
223    public void run2() throws Throwable {
224        runTest("test2char", (char) (0x0));
225        runTest("test2char", (char) (0xFFFF));
226        runTest("test2char", (char) (0xFFFF - 21)); // miss
227        runTest("test2char", (char) (0xFFFF - 22)); // hit
228        runTest("test2char", (char) (0xFFFF - 23)); // miss (out of bound)
229
230        staticCharVal = (char) 0xFFFF;
231        runTest("test2char", (char) 0);
232        staticCharVal = (char) (0xFFFF - 21);
233        runTest("test2char", (char) 0xFFFF);
234        staticCharVal = (char) (0xFFFF - 22);
235        runTest("test2char", (char) 0xFFFF);
236        staticCharVal = (char) (0xFFFF - 23);
237        runTest("test2char", (char) 0xFFFF);
238    }
239
240    @Test
241    public void run3() throws Throwable {
242        runTest("test2short", (short) 0x0);
243        runTest("test2short", (short) -0x7FFF);
244        runTest("test2short", (short) (-0x7FFF + 21)); // Miss
245        runTest("test2short", (short) (-0x7FFF + 22)); // hit
246        runTest("test2short", (short) (-0x7FFF + 23)); // miss (out of bound)
247        runTest("test2short", (short) 0x7FFF);         // miss (out of bound)
248
249        staticShortVal = (short) -0x7FFF;
250        runTest("test2short", (short) 0);
251        staticShortVal = (short) (-0x7FFF + 21);
252        runTest("test2short", (short) 0);
253        staticShortVal = (short) (-0x7FFF + 22);
254        runTest("test2short", (short) 0);
255        staticShortVal = (short) (-0x7FFF + 23);
256        runTest("test2short", (short) 0);
257        staticShortVal = (short) 0x7FFF;
258        runTest("test2short", (short) 0);
259    }
260
261    @Test
262    public void run4() throws Throwable {
263        runTest("test2byte", (byte) 0);
264        runTest("test2byte", (byte) -0x7F);
265        runTest("test2byte", (byte) (-0x7F + 21)); // Miss
266        runTest("test2byte", (byte) (-0x7F + 22)); // hit
267        runTest("test2byte", (byte) (-0x7F + 23)); // miss (out of bound)
268        runTest("test2byte", (byte) 0x7F);         // miss (out of bound)
269
270        staticByteVal = (byte) -0x7F;
271        runTest("test2short", (short) 0);
272        staticByteVal = (byte) (-0x7F + 21);
273        runTest("test2short", (short) 0);
274        staticByteVal = (byte) (-0x7F + 22);
275        runTest("test2short", (short) 0);
276        staticByteVal = (byte) (-0x7F + 23);
277        runTest("test2short", (short) 0);
278        staticByteVal = (byte) 0x7F;
279        runTest("test2short", (short) 0);
280    }
281}
282