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 */
  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 }