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
35package compiler.c2;
36
37public class Test5091921 {
38  private static int result = 0;
39
40
41  /* Test for the bug of transforming indx >= MININT to indx > MININT-1 */
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 */
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;
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};
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};
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};
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};
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
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