1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * Tests on bounds check elimination in loops that use intrinsics. 19 * All bounds checks below should be statically eliminated. 20 */ 21 public class Main { 22 23 /// CHECK-START: int Main.oneArray(int[]) BCE (before) 24 /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none 25 // 26 /// CHECK-START: int Main.oneArray(int[]) BCE (after) 27 /// CHECK-NOT: BoundsCheck 28 /// CHECK-NOT: Deoptimize oneArray(int[] a)29 static int oneArray(int[] a) { 30 int x = 0; 31 for (int i = 0; i < a.length; i++) { 32 x += a[i]; 33 } 34 return x; 35 } 36 37 /// CHECK-START: int Main.oneArrayAbs(int[], int[]) BCE (before) 38 /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none 39 // 40 /// CHECK-START: int Main.oneArrayAbs(int[], int[]) BCE (after) 41 /// CHECK-NOT: BoundsCheck 42 /// CHECK-NOT: Deoptimize oneArrayAbs(int[] a, int[] b)43 static int oneArrayAbs(int[] a, int[] b) { 44 int x = 0; 45 for (int i = Math.abs(b.length); i < a.length; i++) { 46 x += a[i]; 47 } 48 return x; 49 } 50 51 52 /// CHECK-START: int Main.twoArrays(int[], int[]) BCE (before) 53 /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none 54 /// CHECK-DAG: BoundsCheck loop:<<Loop>> outer_loop:none 55 // 56 /// CHECK-START: int Main.twoArrays(int[], int[]) BCE (after) 57 /// CHECK-NOT: BoundsCheck 58 /// CHECK-NOT: Deoptimize twoArrays(int[] a, int[] b)59 static int twoArrays(int[] a, int[] b) { 60 int x = 0; 61 for (int i = 0; i < Math.min(a.length, b.length); i++) { 62 x += a[i] + b[i]; 63 } 64 return x; 65 } 66 67 /// CHECK-START: int Main.threeArrays(int[], int[], int[]) BCE (before) 68 /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none 69 /// CHECK-DAG: BoundsCheck loop:<<Loop>> outer_loop:none 70 /// CHECK-DAG: BoundsCheck loop:<<Loop>> outer_loop:none 71 // 72 /// CHECK-START: int Main.threeArrays(int[], int[], int[]) BCE (after) 73 /// CHECK-NOT: BoundsCheck 74 /// CHECK-NOT: Deoptimize threeArrays(int[] a, int[] b, int[] c)75 static int threeArrays(int[] a, int[] b, int[] c) { 76 int x = 0; 77 for (int i = 0; i < Math.min(Math.min(a.length, b.length), c.length); i++) { 78 x += a[i] + b[i] + c[i]; 79 } 80 return x; 81 } 82 83 /// CHECK-START: int Main.fourArrays(int[], int[], int[], int[]) BCE (before) 84 /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none 85 /// CHECK-DAG: BoundsCheck loop:<<Loop>> outer_loop:none 86 /// CHECK-DAG: BoundsCheck loop:<<Loop>> outer_loop:none 87 /// CHECK-DAG: BoundsCheck loop:<<Loop>> outer_loop:none 88 // 89 /// CHECK-START: int Main.fourArrays(int[], int[], int[], int[]) BCE (after) 90 /// CHECK-NOT: BoundsCheck 91 /// CHECK-NOT: Deoptimize fourArrays(int[] a, int[] b, int[] c, int[] d)92 static int fourArrays(int[] a, int[] b, int[] c, int[] d) { 93 int x = 0; 94 for (int i = 0; i < Math.min(Math.min(a.length, b.length), Math.min(c.length, d.length)); i++) { 95 x += a[i] + b[i] + c[i] + d[i]; 96 } 97 return x; 98 } 99 100 /// CHECK-START: int Main.oneArrayWithCleanup(int[]) BCE (before) 101 /// CHECK-DAG: BoundsCheck loop:<<Loop1:B\d+>> outer_loop:none 102 /// CHECK-DAG: BoundsCheck loop:<<Loop2:B\d+>> outer_loop:none 103 // 104 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" 105 // 106 /// CHECK-START: int Main.oneArrayWithCleanup(int[]) BCE (after) 107 /// CHECK-NOT: BoundsCheck 108 /// CHECK-NOT: Deoptimize oneArrayWithCleanup(int[] a)109 static int oneArrayWithCleanup(int[] a) { 110 int x = 0; 111 int n = Math.min(4, a.length); 112 for (int i = 0; i < n; i++) { 113 x += a[i]; 114 } 115 for (int i = n; i < a.length; i++) { 116 x += a[i] * 10; 117 } 118 return x; 119 } 120 121 /// CHECK-START: int Main.twoArraysWithCleanup(int[], int[]) BCE (before) 122 /// CHECK-DAG: BoundsCheck loop:<<Loop1:B\d+>> outer_loop:none 123 /// CHECK-DAG: BoundsCheck loop:<<Loop1>> outer_loop:none 124 /// CHECK-DAG: BoundsCheck loop:<<Loop2:B\d+>> outer_loop:none 125 // 126 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" 127 // 128 /// CHECK-START: int Main.twoArraysWithCleanup(int[], int[]) BCE (after) 129 /// CHECK-NOT: BoundsCheck 130 /// CHECK-NOT: Deoptimize twoArraysWithCleanup(int[] a, int[] b)131 static int twoArraysWithCleanup(int[] a, int[] b) { 132 int x = 0; 133 int n = Math.min(a.length, b.length); 134 for (int i = n - 1; i >= 0; i--) { 135 x += a[i] + b[i]; 136 } 137 for (int i = n; i < a.length; i++) { 138 x += a[i]; 139 } 140 return x; 141 } 142 143 /// CHECK-START: int Main.threeArraysWithCleanup(int[], int[], int[]) BCE (before) 144 /// CHECK-DAG: BoundsCheck loop:<<Loop1:B\d+>> outer_loop:none 145 /// CHECK-DAG: BoundsCheck loop:<<Loop1>> outer_loop:none 146 /// CHECK-DAG: BoundsCheck loop:<<Loop1>> outer_loop:none 147 /// CHECK-DAG: BoundsCheck loop:<<Loop2:B\d+>> outer_loop:none 148 // 149 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" 150 // 151 /// CHECK-START: int Main.threeArraysWithCleanup(int[], int[], int[]) BCE (after) 152 /// CHECK-NOT: BoundsCheck 153 /// CHECK-NOT: Deoptimize threeArraysWithCleanup(int[] a, int[] b, int[] c)154 static int threeArraysWithCleanup(int[] a, int[] b, int[] c) { 155 int x = 0; 156 int n = Math.min(a.length, Math.min(b.length, c.length)); 157 for (int i = n - 1; i >= 0; i--) { 158 x += a[i] + b[i] + c[i]; 159 } 160 for (int i = n; i < a.length; i++) { 161 x += a[i]; 162 } 163 return x; 164 } 165 166 /// CHECK-START: int Main.altLoopLogic(int[], int[]) BCE (before) 167 /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none 168 /// CHECK-DAG: BoundsCheck loop:<<Loop>> outer_loop:none 169 // 170 /// CHECK-START: int Main.altLoopLogic(int[], int[]) BCE (after) 171 /// CHECK-NOT: BoundsCheck 172 /// CHECK-NOT: Deoptimize altLoopLogic(int[] a, int[] b)173 static int altLoopLogic(int[] a, int[] b) { 174 int x = 0; 175 int n = Math.min(a.length, b.length); 176 for (int i = n; i-- > 0;) { 177 x += a[i] + b[i]; 178 } 179 return x; 180 } 181 182 /// CHECK-START: int Main.hiddenMin(int[], int[]) BCE (before) 183 /// CHECK-DAG: BoundsCheck loop:<<Loop:B\d+>> outer_loop:none 184 /// CHECK-DAG: BoundsCheck loop:<<Loop>> outer_loop:none 185 // 186 /// CHECK-START: int Main.hiddenMin(int[], int[]) BCE (after) 187 // 188 // TODO: make this so hiddenMin(int[] a, int[] b)189 static int hiddenMin(int[] a, int[] b) { 190 int x = 0; 191 for (int i = 0; i < a.length && i < b.length; i++) { 192 x += a[i] + b[i]; 193 } 194 return x; 195 } 196 197 /// CHECK-START: int Main.hiddenMinWithCleanup(int[], int[]) BCE (before) 198 /// CHECK-DAG: BoundsCheck loop:<<Loop1:B\d+>> outer_loop:none 199 /// CHECK-DAG: BoundsCheck loop:<<Loop1>> outer_loop:none 200 /// CHECK-DAG: BoundsCheck loop:<<Loop2:B\d+>> outer_loop:none 201 // 202 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" 203 // 204 /// CHECK-START: int Main.hiddenMinWithCleanup(int[], int[]) BCE (after) 205 // 206 // TODO: make this so hiddenMinWithCleanup(int[] a, int[] b)207 static int hiddenMinWithCleanup(int[] a, int[] b) { 208 int x = 0; 209 int i = 0; 210 for (; i < a.length && i < b.length; i++) { 211 x += a[i] + b[i]; 212 } 213 for (; i < a.length; i++) { 214 x += a[i]; 215 } 216 return x; 217 } 218 main(String[] args)219 public static void main(String[] args) { 220 int[] a = { 1, 2, 3, 4, 5 }; 221 int[] b = { 6, 7, 8, 9, 4, 2 }; 222 int[] c = { 1, 2, 3 }; 223 int[] d = { 8, 5, 3, 2 }; 224 int[] e = { }; 225 226 expectEquals(15, oneArray(a)); 227 expectEquals(36, oneArray(b)); 228 expectEquals(6, oneArray(c)); 229 expectEquals(18, oneArray(d)); 230 231 expectEquals(15, oneArrayAbs(a, e)); 232 expectEquals(5, oneArrayAbs(a, d)); 233 234 expectEquals(30, twoArrays(a, a)); 235 expectEquals(49, twoArrays(a, b)); 236 expectEquals(12, twoArrays(a, c)); 237 expectEquals(28, twoArrays(a, d)); 238 239 expectEquals(45, threeArrays(a, a, a)); 240 expectEquals(33, threeArrays(a, b, c)); 241 expectEquals(58, threeArrays(a, b, d)); 242 expectEquals(28, threeArrays(a, c, d)); 243 244 expectEquals(60, fourArrays(a, a, a, a)); 245 expectEquals(49, fourArrays(a, b, c, d)); 246 247 expectEquals(60, oneArrayWithCleanup(a)); 248 expectEquals(90, oneArrayWithCleanup(b)); 249 expectEquals(6, oneArrayWithCleanup(c)); 250 expectEquals(18, oneArrayWithCleanup(d)); 251 252 expectEquals(30, twoArraysWithCleanup(a, a)); 253 expectEquals(49, twoArraysWithCleanup(a, b)); 254 expectEquals(21, twoArraysWithCleanup(a, c)); 255 expectEquals(33, twoArraysWithCleanup(a, d)); 256 257 expectEquals(45, threeArraysWithCleanup(a, a, a)); 258 expectEquals(42, threeArraysWithCleanup(a, b, c)); 259 expectEquals(63, threeArraysWithCleanup(a, b, d)); 260 expectEquals(37, threeArraysWithCleanup(a, c, d)); 261 262 expectEquals(30, altLoopLogic(a, a)); 263 expectEquals(49, altLoopLogic(a, b)); 264 expectEquals(12, altLoopLogic(a, c)); 265 expectEquals(28, altLoopLogic(a, d)); 266 267 expectEquals(30, hiddenMin(a, a)); 268 expectEquals(49, hiddenMin(a, b)); 269 expectEquals(12, hiddenMin(a, c)); 270 expectEquals(28, hiddenMin(a, d)); 271 272 expectEquals(30, hiddenMinWithCleanup(a, a)); 273 expectEquals(49, hiddenMinWithCleanup(a, b)); 274 expectEquals(21, hiddenMinWithCleanup(a, c)); 275 expectEquals(33, hiddenMinWithCleanup(a, d)); 276 277 System.out.println("passed"); 278 } 279 expectEquals(int expected, int result)280 private static void expectEquals(int expected, int result) { 281 if (expected != result) { 282 throw new Error("Expected: " + expected + ", found: " + result); 283 } 284 } 285 } 286