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