1 /*
2  * Copyright (c) 2011 Hewlett-Packard Company. 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  *
23  */
24 
25 /**
26  * @test
27  * @bug 5091921
28  * @summary Sign flip issues in loop optimizer
29  *
30  * @run main/othervm -Xcomp -XX:MaxInlineSize=1
31  *    -XX:CompileCommand=compileonly,compiler.c2.Test5091921::*
32  *    compiler.c2.Test5091921
33  */
34 
35 package compiler.c2;
36 
37 public class Test5091921 {
38   private static int result = 0;
39 
40 
41   /* Test for the bug of transforming indx >= MININT to indx > MININT-1 */
test_ge1(int limit)42   public static int test_ge1(int limit) {
43     int indx;
44     int sum = 0;
45     for (indx = 500; indx >= limit; indx -= 2) {
46       sum += 2000 / indx;
47       result = sum;
48     }
49     return sum;
50   }
51 
52   /* Test for the bug of transforming indx <= MAXINT to indx < MAXINT+1 */
test_le1(int limit)53   public static int test_le1(int limit) {
54     int indx;
55     int sum = 0;
56     for (indx = -500; indx <= limit; indx += 2)
57     {
58       sum += 3000 / indx;
59       result = sum;
60     }
61     return sum;
62   }
63 
64   /* Run with -Xcomp -XX:CompileOnly=wrap1.test1 -XX:MaxInlineSize=1 */
65   /* limit reset to ((limit-init+stride-1)/stride)*stride+init */
66   /* Calculation may overflow */
67   public static volatile int c = 1;
test_wrap1(int limit)68   public static int test_wrap1(int limit)
69   {
70     int indx;
71     int sum = 0;
72     for (indx = 0xffffffff; indx < limit; indx += 0x20000000)
73     {
74       sum += c;
75     }
76     return sum;
77   }
78 
79   /* Test for range check elimination with bit flip issue for
80      scale*i+offset<limit where offset is not 0 */
81   static int[] box5 = {1,2,3,4,5,6,7,8,9};
test_rce5(int[] b, int limit)82   public static int test_rce5(int[] b, int limit)
83   {
84     int indx;
85     int sum = b[1];
86     result = sum;
87     for (indx = 0x80000000; indx < limit; ++indx)
88     {
89       if (indx > 0x80000000)
90       {
91         // this test is not issued in pre-loop but issued in main loop
92         // trick rce into thinking expression is false when indx >= 0
93         // in fact it is false when indx==0x80000001
94         if (indx - 9 < -9)
95         {
96           sum += indx;
97           result = sum;
98           sum ^= b[indx & 7];
99           result = sum;
100         }
101         else
102           break;
103       }
104       else
105       {
106         sum += b[indx & 3];
107         result = sum;
108       }
109     }
110     return sum;
111   }
112 
113   /* Test for range check elimination with bit flip issue for
114      scale*i<limit where scale > 1 */
115   static int[] box6 = {1,2,3,4,5,6,7,8,9};
test_rce6(int[] b, int limit)116   public static int test_rce6(int[] b, int limit)
117   {
118     int indx;
119     int sum = b[1];
120     result = sum;
121     for (indx = 0x80000000; indx < limit; ++indx)
122     {
123       if (indx > 0x80000000)
124       {
125         // harmless rce target
126         if (indx < 0)
127         {
128           sum += result;
129           result = sum;
130         }
131         else
132           break;
133         // this test is not issued in pre-loop but issued in main loop
134         // trick rce into thinking expression is false when indx >= 0
135         // in fact it is false when indx==0x80000001
136         // In compilers that transform mulI to shiftI may mask this issue.
137         if (indx * 28 + 1 < 0)
138         {
139           sum += indx;
140           result = sum;
141           sum ^= b[indx & 7];
142           result = sum;
143         }
144         else
145           break;
146       }
147       else
148       {
149         sum += b[indx & 3];
150         result = sum;
151       }
152     }
153     return sum;
154   }
155 
156   /* Test for range check elimination with i <= limit */
157   static int[] box7 = {1,2,3,4,5,6,7,8,9,0x7fffffff};
test_rce7(int[] b)158   public static int test_rce7(int[] b)
159   {
160     int indx;
161     int max = b[9];
162     int sum = b[7];
163     result = sum;
164     for (indx = 0; indx < b.length; ++indx)
165     {
166       if (indx <= max)
167       {
168         sum += (indx ^ 15) + ((result != 0) ? 0 : sum);
169         result = sum;
170       }
171       else
172         throw new RuntimeException();
173     }
174     for (indx = -7; indx < b.length; ++indx)
175     {
176       if (indx <= 9)
177       {
178         sum += (sum ^ 15) + ((result != 0) ? 0 : sum);
179         result = sum;
180       }
181       else
182         throw new RuntimeException();
183     }
184     return sum;
185   }
186 
187   /* Test for range check elimination with i >= limit */
188   static int[] box8 = {-1,0,1,2,3,4,5,6,7,8,0x80000000};
test_rce8(int[] b)189   public static int test_rce8(int[] b)
190   {
191     int indx;
192     int sum = b[5];
193     int min = b[10];
194     result = sum;
195     for (indx = b.length-1; indx >= 0; --indx)
196     {
197       if (indx >= min)
198       {
199         sum += (sum ^ 9) + ((result != 0) ? 0 :sum);
200         result = sum;
201       }
202       else
203         throw new RuntimeException();
204     }
205     return sum;
206   }
207 
main(String[] args)208   public static void main(String[] args)
209   {
210     result=1;
211     int r = 0;
212     try {
213       r = test_ge1(0x80000000);
214       System.out.println(result);
215       System.out.println("test_ge1 FAILED");
216       System.exit(1);
217     }
218     catch (ArithmeticException e1) {
219       System.out.println("test_ge1: Expected exception caught");
220       if (result != 5986) {
221         System.out.println(result);
222         System.out.println("test_ge1 FAILED");
223         System.exit(97);
224       }
225     }
226     System.out.println("test_ge1 WORKED");
227 
228     result=0;
229     try
230     {
231       r = test_le1(0x7fffffff);
232       System.out.println(result);
233       System.out.println("test_le1 FAILED");
234       System.exit(1);
235     }
236     catch (ArithmeticException e1)
237     {
238       System.out.println("test_le1: Expected exception caught");
239       if (result != -9039)
240       {
241         System.out.println(result);
242         System.out.println("test_le1 FAILED");
243         System.exit(97);
244       }
245     }
246     System.out.println("test_le1 WORKED");
247 
248     result=0;
249     r = test_wrap1(0x7fffffff);
250     if (r != 4)
251     {
252       System.out.println(result);
253       System.out.println("test_wrap1 FAILED");
254       System.exit(97);
255     }
256     else
257     {
258       System.out.println("test_wrap1 WORKED");
259     }
260 
261     result=0;
262     r = test_rce5(box5,0x80000100);
263     if (result != 3)
264     {
265       System.out.println(result);
266       System.out.println("test_rce5 FAILED");
267       System.exit(97);
268     }
269     else
270     {
271       System.out.println("test_rce5 WORKED");
272     }
273 
274     result=0;
275     r = test_rce6(box6,0x80000100);
276     if (result != 6)
277     {
278       System.out.println(result);
279       System.out.println("test_rce6 FAILED");
280       System.exit(97);
281     }
282     else
283     {
284       System.out.println("test_rce6 WORKED");
285     }
286 
287     result=0;
288     r = test_rce7(box7);
289     if (result != 14680079)
290     {
291       System.out.println(result);
292       System.out.println("test_rce7 FAILED");
293       System.exit(97);
294     }
295     else
296     {
297       System.out.println("test_rce7 WORKED");
298     }
299 
300     result=0;
301     r = test_rce8(box8);
302     if (result != 16393)
303     {
304       System.out.println(result);
305       System.out.println("test_rce8 FAILED");
306       System.exit(97);
307     }
308     else
309     {
310       System.out.println("test_rce8 WORKED");
311     }
312   }
313 }
314