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 import java.lang.reflect.Method; 18 19 public class Main { main(String[] args)20 public static void main(String[] args) throws Throwable { 21 assertLongEquals(11L, $noinline$testIntToLong(0, 1)); 22 assertLongEquals(12L, $noinline$testIntToLong(1, 0)); 23 24 assertFloatEquals(11f, $noinline$testIntToFloat(0, 1)); 25 assertFloatEquals(12f, $noinline$testIntToFloat(1, 0)); 26 27 assertIntEquals(11, $noinline$testIntToByte(0, 1)); 28 assertIntEquals(12, $noinline$testIntToByte(1, 0)); 29 30 assertIntEquals(11, $noinline$testLongToInt(0, 1)); 31 assertIntEquals(12, $noinline$testLongToInt(1, 0)); 32 } 33 34 /// CHECK-START: long Main.$noinline$testIntToLong(int, int) select_generator (after) 35 /// CHECK: <<Const10:j\d+>> LongConstant 10 36 /// CHECK: <<Const1:i\d+>> IntConstant 1 37 /// CHECK: <<Const2:i\d+>> IntConstant 2 38 /// CHECK: <<Sel:i\d+>> Select [<<Const1>>,<<Const2>>,<<Condition:z\d+>>] 39 /// CHECK: <<Type:j\d+>> TypeConversion [<<Sel>>] 40 /// CHECK: Add [<<Type>>,<<Const10>>] 41 42 /// CHECK-START: long Main.$noinline$testIntToLong(int, int) constant_folding$after_gvn (after) 43 /// CHECK: <<Const11:j\d+>> LongConstant 11 44 /// CHECK: <<Const12:j\d+>> LongConstant 12 45 /// CHECK: Select [<<Const11>>,<<Const12>>,<<Condition:z\d+>>] 46 47 /// CHECK-START: long Main.$noinline$testIntToLong(int, int) constant_folding$after_gvn (after) 48 /// CHECK-NOT: TypeConversion 49 /// CHECK-NOT: Add $noinline$testIntToLong(int a, int b)50 private static long $noinline$testIntToLong(int a, int b) { 51 long result = 10; 52 int c = 1; 53 int d = 2; 54 return result + (a < b ? c : d); 55 } 56 57 /// CHECK-START: float Main.$noinline$testIntToFloat(int, int) select_generator (after) 58 /// CHECK: <<Const10:f\d+>> FloatConstant 10 59 /// CHECK: <<Const1:i\d+>> IntConstant 1 60 /// CHECK: <<Const2:i\d+>> IntConstant 2 61 /// CHECK: <<Sel:i\d+>> Select [<<Const1>>,<<Const2>>,<<Condition:z\d+>>] 62 /// CHECK: <<Type:f\d+>> TypeConversion [<<Sel>>] 63 /// CHECK: Add [<<Type>>,<<Const10>>] 64 65 /// CHECK-START: float Main.$noinline$testIntToFloat(int, int) constant_folding$after_gvn (after) 66 /// CHECK: <<Const11:f\d+>> FloatConstant 11 67 /// CHECK: <<Const12:f\d+>> FloatConstant 12 68 /// CHECK: Select [<<Const11>>,<<Const12>>,<<Condition:z\d+>>] 69 70 /// CHECK-START: float Main.$noinline$testIntToFloat(int, int) constant_folding$after_gvn (after) 71 /// CHECK-NOT: TypeConversion 72 /// CHECK-NOT: Add $noinline$testIntToFloat(int a, int b)73 private static float $noinline$testIntToFloat(int a, int b) { 74 float result = 10; 75 int c = 1; 76 int d = 2; 77 return result + (a < b ? c : d); 78 } 79 80 /// CHECK-START: byte Main.$noinline$testIntToByte(int, int) select_generator (after) 81 /// CHECK: <<Const10:i\d+>> IntConstant 10 82 /// CHECK: <<Const257:i\d+>> IntConstant 257 83 /// CHECK: <<Const258:i\d+>> IntConstant 258 84 /// CHECK: <<Sel:i\d+>> Select [<<Const257>>,<<Const258>>,<<Condition:z\d+>>] 85 /// CHECK: <<Type:b\d+>> TypeConversion [<<Sel>>] 86 /// CHECK: Add [<<Type>>,<<Const10>>] 87 88 /// CHECK-START: byte Main.$noinline$testIntToByte(int, int) constant_folding$after_gvn (after) 89 /// CHECK: <<Const11:i\d+>> IntConstant 11 90 /// CHECK: <<Const12:i\d+>> IntConstant 12 91 /// CHECK: Select [<<Const11>>,<<Const12>>,<<Condition:z\d+>>] 92 93 /// CHECK-START: byte Main.$noinline$testIntToByte(int, int) constant_folding$after_gvn (after) 94 /// CHECK-NOT: TypeConversion 95 /// CHECK-NOT: Add $noinline$testIntToByte(int a, int b)96 private static byte $noinline$testIntToByte(int a, int b) { 97 byte result = 10; 98 int c = 257; // equal to 1 in byte 99 int d = 258; // equal to 2 in byte 100 // Due to `+` operating in ints, we need to do an extra cast. We can optimize away both type 101 // conversions. 102 return (byte) (result + (byte) (a < b ? c : d)); 103 } 104 105 /// CHECK-START: int Main.$noinline$testLongToInt(int, int) select_generator (after) 106 /// CHECK: <<Const10:i\d+>> IntConstant 10 107 /// CHECK: <<Const1:j\d+>> LongConstant 4294967297 108 /// CHECK: <<Const2:j\d+>> LongConstant 4294967298 109 /// CHECK: <<Sel:j\d+>> Select [<<Const1>>,<<Const2>>,<<Condition:z\d+>>] 110 /// CHECK: <<Type:i\d+>> TypeConversion [<<Sel>>] 111 /// CHECK: Add [<<Type>>,<<Const10>>] 112 113 /// CHECK-START: int Main.$noinline$testLongToInt(int, int) constant_folding$after_gvn (after) 114 /// CHECK: <<Const11:i\d+>> IntConstant 11 115 /// CHECK: <<Const12:i\d+>> IntConstant 12 116 /// CHECK: Select [<<Const11>>,<<Const12>>,<<Condition:z\d+>>] 117 118 /// CHECK-START: int Main.$noinline$testLongToInt(int, int) constant_folding$after_gvn (after) 119 /// CHECK-NOT: TypeConversion 120 /// CHECK-NOT: Add $noinline$testLongToInt(int a, int b)121 private static int $noinline$testLongToInt(int a, int b) { 122 int result = 10; 123 long c = (1L << 32) + 1L; // Will be 1, when cast to int 124 long d = (1L << 32) + 2L; // Will be 2, when cast to int 125 return result + (int) (a < b ? c : d); 126 } 127 assertIntEquals(int expected, int actual)128 private static void assertIntEquals(int expected, int actual) { 129 if (expected != actual) { 130 throw new AssertionError("Expected " + expected + " got " + actual); 131 } 132 } 133 assertLongEquals(long expected, long actual)134 private static void assertLongEquals(long expected, long actual) { 135 if (expected != actual) { 136 throw new AssertionError("Expected " + expected + " got " + actual); 137 } 138 } 139 assertFloatEquals(float expected, float actual)140 private static void assertFloatEquals(float expected, float actual) { 141 if (expected != actual) { 142 throw new AssertionError("Expected " + expected + " got " + actual); 143 } 144 } 145 } 146