1 /* 2 * Copyright (C) 2023 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 public class Main { main(String[] args)18 public static void main(String[] args) { 19 assertEquals(1, $noinline$testEqualBool(true)); 20 assertEquals(0, $noinline$testNotEqualBool(true)); 21 // Other comparisons e.g. `<` don't exists for boolean values. 22 23 assertEquals(1, $noinline$testEqualInt(0)); 24 assertEquals(0, $noinline$testNotEqualInt(0)); 25 assertEquals(0, $noinline$testGreaterThanInt(0)); 26 assertEquals(1, $noinline$testGreaterThanOrEqualInt(0)); 27 assertEquals(0, $noinline$testLessThanInt(0)); 28 assertEquals(1, $noinline$testLessThanOrEqualInt(0)); 29 30 assertEquals(1, $noinline$testEqualLong(0L)); 31 assertEquals(0, $noinline$testNotEqualLong(0L)); 32 assertEquals(0, $noinline$testGreaterThanLong(0L)); 33 assertEquals(1, $noinline$testGreaterThanOrEqualLong(0L)); 34 assertEquals(0, $noinline$testLessThanLong(0L)); 35 assertEquals(1, $noinline$testLessThanOrEqualLong(0L)); 36 37 // We cannot perform the optimization on unknown float/doubles since equality for NaN 38 // returns the opposite as for normal numbers. 39 assertEquals(1, $noinline$testEqualFloat(0f)); 40 assertEquals(0, $noinline$testEqualFloat(Float.NaN)); 41 assertEquals(1, $noinline$testEqualFloat(Float.NEGATIVE_INFINITY)); 42 assertEquals(1, $noinline$testEqualFloat(Float.POSITIVE_INFINITY)); 43 assertEquals(0, $noinline$testNotEqualFloat(0f)); 44 assertEquals(1, $noinline$testNotEqualFloat(Float.NaN)); 45 assertEquals(0, $noinline$testNotEqualFloat(Float.NEGATIVE_INFINITY)); 46 assertEquals(0, $noinline$testNotEqualFloat(Float.POSITIVE_INFINITY)); 47 assertEquals(0, $noinline$testGreaterThanFloat(0f)); 48 assertEquals(0, $noinline$testGreaterThanFloat(Float.NaN)); 49 assertEquals(0, $noinline$testGreaterThanFloat(Float.NEGATIVE_INFINITY)); 50 assertEquals(0, $noinline$testGreaterThanFloat(Float.POSITIVE_INFINITY)); 51 assertEquals(1, $noinline$testGreaterThanOrEqualFloat(0f)); 52 assertEquals(0, $noinline$testGreaterThanOrEqualFloat(Float.NaN)); 53 assertEquals(1, $noinline$testGreaterThanOrEqualFloat(Float.NEGATIVE_INFINITY)); 54 assertEquals(1, $noinline$testGreaterThanOrEqualFloat(Float.POSITIVE_INFINITY)); 55 assertEquals(0, $noinline$testLessThanFloat(0f)); 56 assertEquals(0, $noinline$testLessThanFloat(Float.NaN)); 57 assertEquals(0, $noinline$testLessThanFloat(Float.NEGATIVE_INFINITY)); 58 assertEquals(0, $noinline$testLessThanFloat(Float.POSITIVE_INFINITY)); 59 assertEquals(1, $noinline$testLessThanOrEqualFloat(0f)); 60 assertEquals(0, $noinline$testLessThanOrEqualFloat(Float.NaN)); 61 assertEquals(1, $noinline$testLessThanOrEqualFloat(Float.NEGATIVE_INFINITY)); 62 assertEquals(1, $noinline$testLessThanOrEqualFloat(Float.POSITIVE_INFINITY)); 63 64 assertEquals(1, $noinline$testEqualDouble(0d)); 65 assertEquals(0, $noinline$testEqualDouble(Double.NaN)); 66 assertEquals(1, $noinline$testEqualDouble(Double.NEGATIVE_INFINITY)); 67 assertEquals(1, $noinline$testEqualDouble(Double.POSITIVE_INFINITY)); 68 assertEquals(0, $noinline$testNotEqualDouble(0d)); 69 assertEquals(1, $noinline$testNotEqualDouble(Double.NaN)); 70 assertEquals(0, $noinline$testNotEqualDouble(Double.NEGATIVE_INFINITY)); 71 assertEquals(0, $noinline$testNotEqualDouble(Double.POSITIVE_INFINITY)); 72 assertEquals(0, $noinline$testGreaterThanDouble(0d)); 73 assertEquals(0, $noinline$testGreaterThanDouble(Double.NaN)); 74 assertEquals(0, $noinline$testGreaterThanDouble(Double.NEGATIVE_INFINITY)); 75 assertEquals(0, $noinline$testGreaterThanDouble(Double.POSITIVE_INFINITY)); 76 assertEquals(1, $noinline$testGreaterThanOrEqualDouble(0d)); 77 assertEquals(0, $noinline$testGreaterThanOrEqualDouble(Double.NaN)); 78 assertEquals(1, $noinline$testGreaterThanOrEqualDouble(Double.NEGATIVE_INFINITY)); 79 assertEquals(1, $noinline$testGreaterThanOrEqualDouble(Double.POSITIVE_INFINITY)); 80 assertEquals(0, $noinline$testLessThanDouble(0d)); 81 assertEquals(0, $noinline$testLessThanDouble(Double.NaN)); 82 assertEquals(0, $noinline$testLessThanDouble(Double.NEGATIVE_INFINITY)); 83 assertEquals(0, $noinline$testLessThanDouble(Double.POSITIVE_INFINITY)); 84 assertEquals(1, $noinline$testLessThanOrEqualDouble(0d)); 85 assertEquals(0, $noinline$testLessThanOrEqualDouble(Double.NaN)); 86 assertEquals(1, $noinline$testLessThanOrEqualDouble(Double.NEGATIVE_INFINITY)); 87 assertEquals(1, $noinline$testLessThanOrEqualDouble(Double.POSITIVE_INFINITY)); 88 89 assertEquals(1, $noinline$testEqualObject(null)); 90 assertEquals(1, $noinline$testEqualObject(new Object())); 91 assertEquals(0, $noinline$testNotEqualObject(null)); 92 assertEquals(0, $noinline$testNotEqualObject(new Object())); 93 // Other comparisons e.g. `<` don't exists for references. 94 } 95 96 /// CHECK-START: int Main.$noinline$testEqualBool(boolean) register (after) 97 /// CHECK: <<Const1:i\d+>> IntConstant 1 98 /// CHECK: Return [<<Const1>>] $noinline$testEqualBool(boolean a)99 private static int $noinline$testEqualBool(boolean a) { 100 if (a == $inline$returnValueBool(a)) { 101 return 1; 102 } else { 103 return 0; 104 } 105 } 106 107 /// CHECK-START: int Main.$noinline$testNotEqualBool(boolean) register (after) 108 /// CHECK: <<Const0:i\d+>> IntConstant 0 109 /// CHECK: Return [<<Const0>>] $noinline$testNotEqualBool(boolean a)110 private static int $noinline$testNotEqualBool(boolean a) { 111 if (a != $inline$returnValueBool(a)) { 112 return 1; 113 } else { 114 return 0; 115 } 116 } 117 $inline$returnValueBool(boolean a)118 private static boolean $inline$returnValueBool(boolean a) { 119 return a; 120 } 121 122 /// CHECK-START: int Main.$noinline$testEqualInt(int) register (after) 123 /// CHECK: <<Const1:i\d+>> IntConstant 1 124 /// CHECK: Return [<<Const1>>] $noinline$testEqualInt(int a)125 private static int $noinline$testEqualInt(int a) { 126 if (a == $inline$returnValueInt(a)) { 127 return 1; 128 } else { 129 return 0; 130 } 131 } 132 133 /// CHECK-START: int Main.$noinline$testNotEqualInt(int) register (after) 134 /// CHECK: <<Const0:i\d+>> IntConstant 0 135 /// CHECK: Return [<<Const0>>] $noinline$testNotEqualInt(int a)136 private static int $noinline$testNotEqualInt(int a) { 137 if (a != $inline$returnValueInt(a)) { 138 return 1; 139 } else { 140 return 0; 141 } 142 } 143 144 /// CHECK-START: int Main.$noinline$testGreaterThanInt(int) register (after) 145 /// CHECK: <<Const0:i\d+>> IntConstant 0 146 /// CHECK: Return [<<Const0>>] $noinline$testGreaterThanInt(int a)147 private static int $noinline$testGreaterThanInt(int a) { 148 if (a > $inline$returnValueInt(a)) { 149 return 1; 150 } else { 151 return 0; 152 } 153 } 154 155 /// CHECK-START: int Main.$noinline$testGreaterThanOrEqualInt(int) register (after) 156 /// CHECK: <<Const1:i\d+>> IntConstant 1 157 /// CHECK: Return [<<Const1>>] $noinline$testGreaterThanOrEqualInt(int a)158 private static int $noinline$testGreaterThanOrEqualInt(int a) { 159 if (a >= $inline$returnValueInt(a)) { 160 return 1; 161 } else { 162 return 0; 163 } 164 } 165 166 /// CHECK-START: int Main.$noinline$testLessThanInt(int) register (after) 167 /// CHECK: <<Const0:i\d+>> IntConstant 0 168 /// CHECK: Return [<<Const0>>] $noinline$testLessThanInt(int a)169 private static int $noinline$testLessThanInt(int a) { 170 if (a < $inline$returnValueInt(a)) { 171 return 1; 172 } else { 173 return 0; 174 } 175 } 176 177 /// CHECK-START: int Main.$noinline$testLessThanOrEqualInt(int) register (after) 178 /// CHECK: <<Const1:i\d+>> IntConstant 1 179 /// CHECK: Return [<<Const1>>] $noinline$testLessThanOrEqualInt(int a)180 private static int $noinline$testLessThanOrEqualInt(int a) { 181 if (a <= $inline$returnValueInt(a)) { 182 return 1; 183 } else { 184 return 0; 185 } 186 } 187 $inline$returnValueInt(int a)188 private static int $inline$returnValueInt(int a) { 189 return a; 190 } 191 192 /// CHECK-START: int Main.$noinline$testEqualLong(long) register (after) 193 /// CHECK: <<Const1:i\d+>> IntConstant 1 194 /// CHECK: Return [<<Const1>>] $noinline$testEqualLong(long a)195 private static int $noinline$testEqualLong(long a) { 196 if (a == $inline$returnValueLong(a)) { 197 return 1; 198 } else { 199 return 0; 200 } 201 } 202 203 /// CHECK-START: int Main.$noinline$testNotEqualLong(long) register (after) 204 /// CHECK: <<Const0:i\d+>> IntConstant 0 205 /// CHECK: Return [<<Const0>>] $noinline$testNotEqualLong(long a)206 private static int $noinline$testNotEqualLong(long a) { 207 if (a != $inline$returnValueLong(a)) { 208 return 1; 209 } else { 210 return 0; 211 } 212 } 213 214 /// CHECK-START: int Main.$noinline$testGreaterThanLong(long) register (after) 215 /// CHECK: <<Const0:i\d+>> IntConstant 0 216 /// CHECK: Return [<<Const0>>] $noinline$testGreaterThanLong(long a)217 private static int $noinline$testGreaterThanLong(long a) { 218 if (a > $inline$returnValueLong(a)) { 219 return 1; 220 } else { 221 return 0; 222 } 223 } 224 225 /// CHECK-START: int Main.$noinline$testGreaterThanOrEqualLong(long) register (after) 226 /// CHECK: <<Const1:i\d+>> IntConstant 1 227 /// CHECK: Return [<<Const1>>] $noinline$testGreaterThanOrEqualLong(long a)228 private static int $noinline$testGreaterThanOrEqualLong(long a) { 229 if (a >= $inline$returnValueLong(a)) { 230 return 1; 231 } else { 232 return 0; 233 } 234 } 235 236 /// CHECK-START: int Main.$noinline$testLessThanLong(long) register (after) 237 /// CHECK: <<Const0:i\d+>> IntConstant 0 238 /// CHECK: Return [<<Const0>>] $noinline$testLessThanLong(long a)239 private static int $noinline$testLessThanLong(long a) { 240 if (a < $inline$returnValueLong(a)) { 241 return 1; 242 } else { 243 return 0; 244 } 245 } 246 247 /// CHECK-START: int Main.$noinline$testLessThanOrEqualLong(long) register (after) 248 /// CHECK: <<Const1:i\d+>> IntConstant 1 249 /// CHECK: Return [<<Const1>>] $noinline$testLessThanOrEqualLong(long a)250 private static int $noinline$testLessThanOrEqualLong(long a) { 251 if (a <= $inline$returnValueLong(a)) { 252 return 1; 253 } else { 254 return 0; 255 } 256 } 257 $inline$returnValueLong(long a)258 private static long $inline$returnValueLong(long a) { 259 return a; 260 } 261 262 /// CHECK-START: int Main.$noinline$testEqualFloat(float) register (after) 263 /// CHECK: <<NotEqual:z\d+>> NotEqual 264 /// CHECK: <<BNot:z\d+>> BooleanNot [<<NotEqual>>] 265 /// CHECK: Return [<<BNot>>] $noinline$testEqualFloat(float a)266 private static int $noinline$testEqualFloat(float a) { 267 if (a == $inline$returnValueFloat(a)) { 268 return 1; 269 } else { 270 return 0; 271 } 272 } 273 274 /// CHECK-START: int Main.$noinline$testNotEqualFloat(float) register (after) 275 /// CHECK: <<Equal:z\d+>> Equal 276 /// CHECK: <<BNot:z\d+>> BooleanNot [<<Equal>>] 277 /// CHECK: Return [<<BNot>>] $noinline$testNotEqualFloat(float a)278 private static int $noinline$testNotEqualFloat(float a) { 279 if (a != $inline$returnValueFloat(a)) { 280 return 1; 281 } else { 282 return 0; 283 } 284 } 285 286 /// CHECK-START: int Main.$noinline$testGreaterThanFloat(float) register (after) 287 /// CHECK: <<Const0:i\d+>> IntConstant 0 288 /// CHECK: Return [<<Const0>>] $noinline$testGreaterThanFloat(float a)289 private static int $noinline$testGreaterThanFloat(float a) { 290 if (a > $inline$returnValueFloat(a)) { 291 return 1; 292 } else { 293 return 0; 294 } 295 } 296 297 /// CHECK-START: int Main.$noinline$testGreaterThanOrEqualFloat(float) register (after) 298 /// CHECK: <<LessThan:z\d+>> LessThan 299 /// CHECK: <<BNot:z\d+>> BooleanNot [<<LessThan>>] 300 /// CHECK: Return [<<BNot>>] $noinline$testGreaterThanOrEqualFloat(float a)301 private static int $noinline$testGreaterThanOrEqualFloat(float a) { 302 if (a >= $inline$returnValueFloat(a)) { 303 return 1; 304 } else { 305 return 0; 306 } 307 } 308 309 /// CHECK-START: int Main.$noinline$testLessThanFloat(float) register (after) 310 /// CHECK: <<Const0:i\d+>> IntConstant 0 311 /// CHECK: Return [<<Const0>>] $noinline$testLessThanFloat(float a)312 private static int $noinline$testLessThanFloat(float a) { 313 if (a < $inline$returnValueFloat(a)) { 314 return 1; 315 } else { 316 return 0; 317 } 318 } 319 320 /// CHECK-START: int Main.$noinline$testLessThanOrEqualFloat(float) register (after) 321 /// CHECK: <<GreaterThan:z\d+>> GreaterThan 322 /// CHECK: <<BNot:z\d+>> BooleanNot [<<GreaterThan>>] 323 /// CHECK: Return [<<BNot>>] $noinline$testLessThanOrEqualFloat(float a)324 private static int $noinline$testLessThanOrEqualFloat(float a) { 325 if (a <= $inline$returnValueFloat(a)) { 326 return 1; 327 } else { 328 return 0; 329 } 330 } 331 $inline$returnValueFloat(float a)332 private static float $inline$returnValueFloat(float a) { 333 return a; 334 } 335 336 /// CHECK-START: int Main.$noinline$testEqualDouble(double) register (after) 337 /// CHECK: <<NotEqual:z\d+>> NotEqual 338 /// CHECK: <<BNot:z\d+>> BooleanNot [<<NotEqual>>] 339 /// CHECK: Return [<<BNot>>] $noinline$testEqualDouble(double a)340 private static int $noinline$testEqualDouble(double a) { 341 if (a == $inline$returnValueDouble(a)) { 342 return 1; 343 } else { 344 return 0; 345 } 346 } 347 348 /// CHECK-START: int Main.$noinline$testNotEqualDouble(double) register (after) 349 /// CHECK: <<Equal:z\d+>> Equal 350 /// CHECK: <<BNot:z\d+>> BooleanNot [<<Equal>>] 351 /// CHECK: Return [<<BNot>>] $noinline$testNotEqualDouble(double a)352 private static int $noinline$testNotEqualDouble(double a) { 353 if (a != $inline$returnValueDouble(a)) { 354 return 1; 355 } else { 356 return 0; 357 } 358 } 359 360 /// CHECK-START: int Main.$noinline$testGreaterThanDouble(double) register (after) 361 /// CHECK: <<Const0:i\d+>> IntConstant 0 362 /// CHECK: Return [<<Const0>>] $noinline$testGreaterThanDouble(double a)363 private static int $noinline$testGreaterThanDouble(double a) { 364 if (a > $inline$returnValueDouble(a)) { 365 return 1; 366 } else { 367 return 0; 368 } 369 } 370 371 /// CHECK-START: int Main.$noinline$testGreaterThanOrEqualDouble(double) register (after) 372 /// CHECK: <<LessThan:z\d+>> LessThan 373 /// CHECK: <<BNot:z\d+>> BooleanNot [<<LessThan>>] 374 /// CHECK: Return [<<BNot>>] $noinline$testGreaterThanOrEqualDouble(double a)375 private static int $noinline$testGreaterThanOrEqualDouble(double a) { 376 if (a >= $inline$returnValueDouble(a)) { 377 return 1; 378 } else { 379 return 0; 380 } 381 } 382 383 /// CHECK-START: int Main.$noinline$testLessThanDouble(double) register (after) 384 /// CHECK: <<Const0:i\d+>> IntConstant 0 385 /// CHECK: Return [<<Const0>>] $noinline$testLessThanDouble(double a)386 private static int $noinline$testLessThanDouble(double a) { 387 if (a < $inline$returnValueDouble(a)) { 388 return 1; 389 } else { 390 return 0; 391 } 392 } 393 394 /// CHECK-START: int Main.$noinline$testLessThanOrEqualDouble(double) register (after) 395 /// CHECK: <<GreaterThan:z\d+>> GreaterThan 396 /// CHECK: <<BNot:z\d+>> BooleanNot [<<GreaterThan>>] 397 /// CHECK: Return [<<BNot>>] $noinline$testLessThanOrEqualDouble(double a)398 private static int $noinline$testLessThanOrEqualDouble(double a) { 399 if (a <= $inline$returnValueDouble(a)) { 400 return 1; 401 } else { 402 return 0; 403 } 404 } 405 $inline$returnValueDouble(double a)406 private static double $inline$returnValueDouble(double a) { 407 return a; 408 } 409 410 /// CHECK-START: int Main.$noinline$testEqualObject(java.lang.Object) register (after) 411 /// CHECK: <<Const1:i\d+>> IntConstant 1 412 /// CHECK: Return [<<Const1>>] $noinline$testEqualObject(Object a)413 private static int $noinline$testEqualObject(Object a) { 414 if (a == $inline$returnValueObject(a)) { 415 return 1; 416 } else { 417 return 0; 418 } 419 } 420 421 /// CHECK-START: int Main.$noinline$testNotEqualObject(java.lang.Object) register (after) 422 /// CHECK: <<Const0:i\d+>> IntConstant 0 423 /// CHECK: Return [<<Const0>>] $noinline$testNotEqualObject(Object a)424 private static int $noinline$testNotEqualObject(Object a) { 425 if (a != $inline$returnValueObject(a)) { 426 return 1; 427 } else { 428 return 0; 429 } 430 } 431 $inline$returnValueObject(Object a)432 private static Object $inline$returnValueObject(Object a) { 433 return a; 434 } 435 assertEquals(int expected, int actual)436 static void assertEquals(int expected, int actual) { 437 if (expected != actual) { 438 throw new AssertionError("Expected " + expected + " got " + actual); 439 } 440 } 441 } 442