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 import java.lang.reflect.Method; 18 19 public class Main { 20 main(String args[])21 public static void main(String args[]) { 22 expectEqualsByte((byte)1, booleanToByte(true)); 23 expectEqualsShort((short)1, booleanToShort(true)); 24 expectEqualsChar((char)1, booleanToChar(true)); 25 expectEqualsInt(1, booleanToInt(true)); 26 expectEqualsLong(1L, booleanToLong(true)); 27 expectEqualsLong(1L, $noinline$runSmaliTest("booleanToLong", true)); 28 29 expectEqualsInt(1, longToIntOfBoolean()); 30 expectEqualsInt(1, $noinline$runSmaliTest("longToIntOfBoolean")); 31 32 System.out.println("passed"); 33 } 34 35 /// CHECK-START: byte Main.booleanToByte(boolean) instruction_simplifier$after_bce (after) 36 /// CHECK: <<Arg:z\d+>> ParameterValue 37 /// CHECK-DAG: Return [<<Arg>>] 38 booleanToByte(boolean b)39 static byte booleanToByte(boolean b) { 40 return (byte)(b ? 1 : 0); 41 } 42 43 /// CHECK-START: short Main.booleanToShort(boolean) instruction_simplifier$after_bce (after) 44 /// CHECK: <<Arg:z\d+>> ParameterValue 45 /// CHECK-DAG: Return [<<Arg>>] 46 booleanToShort(boolean b)47 static short booleanToShort(boolean b) { 48 return (short)(b ? 1 : 0); 49 } 50 51 /// CHECK-START: char Main.booleanToChar(boolean) instruction_simplifier$after_bce (after) 52 /// CHECK: <<Arg:z\d+>> ParameterValue 53 /// CHECK-DAG: Return [<<Arg>>] 54 booleanToChar(boolean b)55 static char booleanToChar(boolean b) { 56 return (char)(b ? 1 : 0); 57 } 58 59 /// CHECK-START: int Main.booleanToInt(boolean) instruction_simplifier$after_bce (after) 60 /// CHECK: <<Arg:z\d+>> ParameterValue 61 /// CHECK-DAG: Return [<<Arg>>] 62 booleanToInt(boolean b)63 static int booleanToInt(boolean b) { 64 return b ? 1 : 0; 65 } 66 67 /// CHECK-START: long Main.booleanToLong(boolean) builder (after) 68 /// CHECK: <<Arg:z\d+>> ParameterValue 69 /// CHECK-DAG: <<IZero:i\d+>> IntConstant 0 70 /// CHECK-DAG: <<Zero:j\d+>> LongConstant 0 71 /// CHECK-DAG: <<One:j\d+>> LongConstant 1 72 /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Arg>>,<<IZero>>] 73 /// CHECK-DAG: If [<<Cond>>] 74 /// CHECK-DAG: <<Phi:j\d+>> Phi [<<One>>,<<Zero>>] 75 /// CHECK-DAG: Return [<<Phi>>] 76 77 /// CHECK-START: long Main.booleanToLong(boolean) select_generator (after) 78 /// CHECK-NOT: IntConstant 79 /// CHECK-NOT: Equal 80 /// CHECK-NOT: If 81 /// CHECK-NOT: Phi 82 83 /// CHECK-START: long Main.booleanToLong(boolean) select_generator (after) 84 /// CHECK: <<Arg:z\d+>> ParameterValue 85 /// CHECK-DAG: <<Zero:j\d+>> LongConstant 0 86 /// CHECK-DAG: <<One:j\d+>> LongConstant 1 87 /// CHECK-DAG: <<Sel:j\d+>> Select [<<Zero>>,<<One>>,<<Arg>>] 88 /// CHECK-DAG: Return [<<Sel>>] 89 90 // As of now, the code is not optimized any further than the above. 91 // TODO: Re-enable checks below after simplifier is updated to handle this pattern: b/63064517 92 93 // CHECK-START: long Main.booleanToLong(boolean) instruction_simplifier$after_bce (after) 94 // CHECK: <<Arg:z\d+>> ParameterValue 95 // CHECK-DAG: <<ZToJ:j\d+>> TypeConversion [<<Arg>>] 96 // CHECK-DAG: Return [<<ZToJ>>] 97 booleanToLong(boolean b)98 static long booleanToLong(boolean b) { 99 return b ? 1 : 0; 100 } 101 102 /// CHECK-START: int Main.longToIntOfBoolean() builder (after) 103 /// CHECK-DAG: <<Sget:z\d+>> StaticFieldGet 104 /// CHECK-DAG: <<ZToJ:j\d+>> InvokeStaticOrDirect [<<Sget>>{{(,[ij]\d+)?}}] 105 /// CHECK-DAG: <<JToI:i\d+>> TypeConversion [<<ZToJ>>] 106 /// CHECK-DAG: Return [<<JToI>>] 107 108 /// CHECK-START: int Main.longToIntOfBoolean() inliner (after) 109 /// CHECK-DAG: <<Zero:j\d+>> LongConstant 0 110 /// CHECK-DAG: <<One:j\d+>> LongConstant 1 111 /// CHECK-DAG: <<Sget:z\d+>> StaticFieldGet 112 /// CHECK-DAG: If [<<Sget>>] 113 /// CHECK-DAG: <<Phi:j\d+>> Phi [<<One>>,<<Zero>>] 114 /// CHECK-DAG: <<JToI:i\d+>> TypeConversion [<<Phi>>] 115 /// CHECK-DAG: Return [<<JToI>>] 116 117 /// CHECK-START: long Main.booleanToLong(boolean) select_generator (after) 118 /// CHECK-NOT: IntConstant 119 /// CHECK-NOT: Equal 120 /// CHECK-NOT: If 121 /// CHECK-NOT: Phi 122 123 /// CHECK-START: int Main.longToIntOfBoolean() select_generator (after) 124 /// CHECK-DAG: <<Zero:j\d+>> LongConstant 0 125 /// CHECK-DAG: <<One:j\d+>> LongConstant 1 126 /// CHECK-DAG: <<Sget:z\d+>> StaticFieldGet 127 /// CHECK-DAG: <<Sel:j\d+>> Select [<<Zero>>,<<One>>,<<Sget>>] 128 /// CHECK-DAG: <<JToI:i\d+>> TypeConversion [<<Sel>>] 129 /// CHECK-DAG: Return [<<JToI>>] 130 131 // As of now, the code is not optimized any further than the above. 132 // TODO: Re-enable checks below after simplifier is updated to handle this pattern: b/63064517 133 134 // CHECK-START: int Main.longToIntOfBoolean() instruction_simplifier$after_bce (after) 135 // CHECK-DAG: <<Sget:z\d+>> StaticFieldGet 136 // CHECK-DAG: Return [<<Sget>>] 137 longToIntOfBoolean()138 static int longToIntOfBoolean() { 139 long l = booleanToLong(booleanField); 140 return (int) l; 141 } 142 143 expectEqualsByte(byte expected, byte result)144 private static void expectEqualsByte(byte expected, byte result) { 145 if (expected != result) { 146 throw new Error("Expected: " + expected + ", found: " + result); 147 } 148 } 149 expectEqualsShort(short expected, short result)150 private static void expectEqualsShort(short expected, short result) { 151 if (expected != result) { 152 throw new Error("Expected: " + expected + ", found: " + result); 153 } 154 } 155 expectEqualsChar(char expected, char result)156 private static void expectEqualsChar(char expected, char result) { 157 if (expected != result) { 158 throw new Error("Expected: " + expected + ", found: " + result); 159 } 160 } 161 expectEqualsInt(int expected, int result)162 private static void expectEqualsInt(int expected, int result) { 163 if (expected != result) { 164 throw new Error("Expected: " + expected + ", found: " + result); 165 } 166 } 167 expectEqualsLong(long expected, long result)168 private static void expectEqualsLong(long expected, long result) { 169 if (expected != result) { 170 throw new Error("Expected: " + expected + ", found: " + result); 171 } 172 } 173 $noinline$runSmaliTest(String name, boolean input)174 public static long $noinline$runSmaliTest(String name, boolean input) { 175 try { 176 Class<?> c = Class.forName("SmaliTests"); 177 Method m = c.getMethod(name, boolean.class); 178 return (Long) m.invoke(null, input); 179 } catch (Exception ex) { 180 throw new Error(ex); 181 } 182 } 183 $noinline$runSmaliTest(String name)184 public static int $noinline$runSmaliTest(String name) { 185 try { 186 Class<?> c = Class.forName("SmaliTests"); 187 Method m = c.getMethod(name); 188 return (Integer) m.invoke(null); 189 } catch (Exception ex) { 190 throw new Error(ex); 191 } 192 } 193 194 195 public static boolean booleanField = true; 196 197 } 198