1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method; 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard Worker public class Main { main(String[] args)20*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) throws Throwable { 21*795d594fSAndroid Build Coastguard Worker assertLongEquals(11L, $noinline$testIntToLong(0, 1)); 22*795d594fSAndroid Build Coastguard Worker assertLongEquals(12L, $noinline$testIntToLong(1, 0)); 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Worker assertFloatEquals(11f, $noinline$testIntToFloat(0, 1)); 25*795d594fSAndroid Build Coastguard Worker assertFloatEquals(12f, $noinline$testIntToFloat(1, 0)); 26*795d594fSAndroid Build Coastguard Worker 27*795d594fSAndroid Build Coastguard Worker assertIntEquals(11, $noinline$testIntToByte(0, 1)); 28*795d594fSAndroid Build Coastguard Worker assertIntEquals(12, $noinline$testIntToByte(1, 0)); 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker assertIntEquals(11, $noinline$testLongToInt(0, 1)); 31*795d594fSAndroid Build Coastguard Worker assertIntEquals(12, $noinline$testLongToInt(1, 0)); 32*795d594fSAndroid Build Coastguard Worker } 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.$noinline$testIntToLong(int, int) select_generator (after) 35*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const10:j\d+>> LongConstant 10 36*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const1:i\d+>> IntConstant 1 37*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 38*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Sel:i\d+>> Select [<<Const1>>,<<Const2>>,<<Condition:z\d+>>] 39*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Type:j\d+>> TypeConversion [<<Sel>>] 40*795d594fSAndroid Build Coastguard Worker /// CHECK: Add [<<Type>>,<<Const10>>] 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.$noinline$testIntToLong(int, int) constant_folding$after_gvn (after) 43*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const11:j\d+>> LongConstant 11 44*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const12:j\d+>> LongConstant 12 45*795d594fSAndroid Build Coastguard Worker /// CHECK: Select [<<Const11>>,<<Const12>>,<<Condition:z\d+>>] 46*795d594fSAndroid Build Coastguard Worker 47*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.$noinline$testIntToLong(int, int) constant_folding$after_gvn (after) 48*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: TypeConversion 49*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Add $noinline$testIntToLong(int a, int b)50*795d594fSAndroid Build Coastguard Worker private static long $noinline$testIntToLong(int a, int b) { 51*795d594fSAndroid Build Coastguard Worker long result = 10; 52*795d594fSAndroid Build Coastguard Worker int c = 1; 53*795d594fSAndroid Build Coastguard Worker int d = 2; 54*795d594fSAndroid Build Coastguard Worker return result + (a < b ? c : d); 55*795d594fSAndroid Build Coastguard Worker } 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.$noinline$testIntToFloat(int, int) select_generator (after) 58*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const10:f\d+>> FloatConstant 10 59*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const1:i\d+>> IntConstant 1 60*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:i\d+>> IntConstant 2 61*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Sel:i\d+>> Select [<<Const1>>,<<Const2>>,<<Condition:z\d+>>] 62*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Type:f\d+>> TypeConversion [<<Sel>>] 63*795d594fSAndroid Build Coastguard Worker /// CHECK: Add [<<Type>>,<<Const10>>] 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.$noinline$testIntToFloat(int, int) constant_folding$after_gvn (after) 66*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const11:f\d+>> FloatConstant 11 67*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const12:f\d+>> FloatConstant 12 68*795d594fSAndroid Build Coastguard Worker /// CHECK: Select [<<Const11>>,<<Const12>>,<<Condition:z\d+>>] 69*795d594fSAndroid Build Coastguard Worker 70*795d594fSAndroid Build Coastguard Worker /// CHECK-START: float Main.$noinline$testIntToFloat(int, int) constant_folding$after_gvn (after) 71*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: TypeConversion 72*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Add $noinline$testIntToFloat(int a, int b)73*795d594fSAndroid Build Coastguard Worker private static float $noinline$testIntToFloat(int a, int b) { 74*795d594fSAndroid Build Coastguard Worker float result = 10; 75*795d594fSAndroid Build Coastguard Worker int c = 1; 76*795d594fSAndroid Build Coastguard Worker int d = 2; 77*795d594fSAndroid Build Coastguard Worker return result + (a < b ? c : d); 78*795d594fSAndroid Build Coastguard Worker } 79*795d594fSAndroid Build Coastguard Worker 80*795d594fSAndroid Build Coastguard Worker /// CHECK-START: byte Main.$noinline$testIntToByte(int, int) select_generator (after) 81*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const10:i\d+>> IntConstant 10 82*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const257:i\d+>> IntConstant 257 83*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const258:i\d+>> IntConstant 258 84*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Sel:i\d+>> Select [<<Const257>>,<<Const258>>,<<Condition:z\d+>>] 85*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Type:b\d+>> TypeConversion [<<Sel>>] 86*795d594fSAndroid Build Coastguard Worker /// CHECK: Add [<<Type>>,<<Const10>>] 87*795d594fSAndroid Build Coastguard Worker 88*795d594fSAndroid Build Coastguard Worker /// CHECK-START: byte Main.$noinline$testIntToByte(int, int) constant_folding$after_gvn (after) 89*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const11:i\d+>> IntConstant 11 90*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const12:i\d+>> IntConstant 12 91*795d594fSAndroid Build Coastguard Worker /// CHECK: Select [<<Const11>>,<<Const12>>,<<Condition:z\d+>>] 92*795d594fSAndroid Build Coastguard Worker 93*795d594fSAndroid Build Coastguard Worker /// CHECK-START: byte Main.$noinline$testIntToByte(int, int) constant_folding$after_gvn (after) 94*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: TypeConversion 95*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Add $noinline$testIntToByte(int a, int b)96*795d594fSAndroid Build Coastguard Worker private static byte $noinline$testIntToByte(int a, int b) { 97*795d594fSAndroid Build Coastguard Worker byte result = 10; 98*795d594fSAndroid Build Coastguard Worker int c = 257; // equal to 1 in byte 99*795d594fSAndroid Build Coastguard Worker int d = 258; // equal to 2 in byte 100*795d594fSAndroid Build Coastguard Worker // Due to `+` operating in ints, we need to do an extra cast. We can optimize away both type 101*795d594fSAndroid Build Coastguard Worker // conversions. 102*795d594fSAndroid Build Coastguard Worker return (byte) (result + (byte) (a < b ? c : d)); 103*795d594fSAndroid Build Coastguard Worker } 104*795d594fSAndroid Build Coastguard Worker 105*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testLongToInt(int, int) select_generator (after) 106*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const10:i\d+>> IntConstant 10 107*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const1:j\d+>> LongConstant 4294967297 108*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const2:j\d+>> LongConstant 4294967298 109*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Sel:j\d+>> Select [<<Const1>>,<<Const2>>,<<Condition:z\d+>>] 110*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Type:i\d+>> TypeConversion [<<Sel>>] 111*795d594fSAndroid Build Coastguard Worker /// CHECK: Add [<<Type>>,<<Const10>>] 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testLongToInt(int, int) constant_folding$after_gvn (after) 114*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const11:i\d+>> IntConstant 11 115*795d594fSAndroid Build Coastguard Worker /// CHECK: <<Const12:i\d+>> IntConstant 12 116*795d594fSAndroid Build Coastguard Worker /// CHECK: Select [<<Const11>>,<<Const12>>,<<Condition:z\d+>>] 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.$noinline$testLongToInt(int, int) constant_folding$after_gvn (after) 119*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: TypeConversion 120*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: Add $noinline$testLongToInt(int a, int b)121*795d594fSAndroid Build Coastguard Worker private static int $noinline$testLongToInt(int a, int b) { 122*795d594fSAndroid Build Coastguard Worker int result = 10; 123*795d594fSAndroid Build Coastguard Worker long c = (1L << 32) + 1L; // Will be 1, when cast to int 124*795d594fSAndroid Build Coastguard Worker long d = (1L << 32) + 2L; // Will be 2, when cast to int 125*795d594fSAndroid Build Coastguard Worker return result + (int) (a < b ? c : d); 126*795d594fSAndroid Build Coastguard Worker } 127*795d594fSAndroid Build Coastguard Worker assertIntEquals(int expected, int actual)128*795d594fSAndroid Build Coastguard Worker private static void assertIntEquals(int expected, int actual) { 129*795d594fSAndroid Build Coastguard Worker if (expected != actual) { 130*795d594fSAndroid Build Coastguard Worker throw new AssertionError("Expected " + expected + " got " + actual); 131*795d594fSAndroid Build Coastguard Worker } 132*795d594fSAndroid Build Coastguard Worker } 133*795d594fSAndroid Build Coastguard Worker assertLongEquals(long expected, long actual)134*795d594fSAndroid Build Coastguard Worker private static void assertLongEquals(long expected, long actual) { 135*795d594fSAndroid Build Coastguard Worker if (expected != actual) { 136*795d594fSAndroid Build Coastguard Worker throw new AssertionError("Expected " + expected + " got " + actual); 137*795d594fSAndroid Build Coastguard Worker } 138*795d594fSAndroid Build Coastguard Worker } 139*795d594fSAndroid Build Coastguard Worker assertFloatEquals(float expected, float actual)140*795d594fSAndroid Build Coastguard Worker private static void assertFloatEquals(float expected, float actual) { 141*795d594fSAndroid Build Coastguard Worker if (expected != actual) { 142*795d594fSAndroid Build Coastguard Worker throw new AssertionError("Expected " + expected + " got " + actual); 143*795d594fSAndroid Build Coastguard Worker } 144*795d594fSAndroid Build Coastguard Worker } 145*795d594fSAndroid Build Coastguard Worker } 146