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