1 /* 2 * Copyright (C) 2017 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 { 18 assertIntEquals(int expected, int result)19 public static void assertIntEquals(int expected, int result) { 20 if (expected != result) { 21 throw new Error("Expected: " + expected + ", found: " + result); 22 } 23 } 24 25 /// CHECK-START-ARM64: void Main.checkIntCase(int[]) instruction_simplifier_arm64 (before) 26 /// CHECK-DAG: <<Array:l\d+>> ParameterValue 27 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 28 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>] 29 // -------------- Loop 30 /// CHECK-DAG: <<Index:i\d+>> Phi 31 /// CHECK-DAG: If 32 /// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Index>>] 33 /// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>] 34 /// CHECK-DAG: VecStore [<<Array>>,<<Index>>,<<Add>>] 35 36 /// CHECK-START-ARM64: void Main.checkIntCase(int[]) instruction_simplifier_arm64 (after) 37 /// CHECK-DAG: <<Array:l\d+>> ParameterValue 38 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 39 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12 40 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 41 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>] 42 // -------------- Loop 43 /// CHECK-DAG: <<Index:i\d+>> Phi 44 /// CHECK-DAG: If 45 /// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>] 46 /// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Address1>>] 47 /// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>] 48 /// CHECK-DAG: <<Address2:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>] 49 /// CHECK-DAG: VecStore [<<Array>>,<<Address2>>,<<Add>>] 50 51 /// CHECK-START-ARM64: void Main.checkIntCase(int[]) GVN$after_arch (after) 52 /// CHECK-DAG: <<Array:l\d+>> ParameterValue 53 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 54 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12 55 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 56 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>] 57 // -------------- Loop 58 /// CHECK-DAG: <<Index:i\d+>> Phi 59 /// CHECK-DAG: If 60 /// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>] 61 /// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Address1>>] 62 /// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>] 63 /// CHECK-NOT: IntermediateAddress 64 /// CHECK-DAG: VecStore [<<Array>>,<<Address1>>,<<Add>>] 65 66 /// CHECK-START-ARM64: void Main.checkIntCase(int[]) disassembly (after) 67 /// CHECK: IntermediateAddressIndex 68 /// CHECK-NEXT: add w{{[0-9]+}}, w{{[0-9]+}}, w{{[0-9]+}}, lsl #2 checkIntCase(int[] a)69 public static void checkIntCase(int[] a) { 70 for (int i = 0; i < 128; i++) { 71 a[i] += 5; 72 } 73 } 74 75 /// CHECK-START-ARM64: void Main.checkByteCase(byte[]) instruction_simplifier_arm64 (before) 76 /// CHECK-DAG: <<Array:l\d+>> ParameterValue 77 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 78 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>] 79 // -------------- Loop 80 /// CHECK-DAG: <<Index:i\d+>> Phi 81 /// CHECK-DAG: If 82 /// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Index>>] 83 /// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>] 84 /// CHECK-DAG: VecStore [<<Array>>,<<Index>>,<<Add>>] 85 86 /// CHECK-START-ARM64: void Main.checkByteCase(byte[]) instruction_simplifier_arm64 (after) 87 /// CHECK-DAG: <<Array:l\d+>> ParameterValue 88 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 89 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 90 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12 91 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>] 92 // -------------- Loop 93 /// CHECK-DAG: <<Index:i\d+>> Phi 94 /// CHECK-DAG: If 95 /// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const0>>] 96 /// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Address1>>] 97 /// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>] 98 /// CHECK-DAG: <<Address2:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const0>>] 99 /// CHECK-DAG: VecStore [<<Array>>,<<Address2>>,<<Add>>] 100 101 /// CHECK-START-ARM64: void Main.checkByteCase(byte[]) GVN$after_arch (after) 102 /// CHECK-DAG: <<Array:l\d+>> ParameterValue 103 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 104 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 105 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12 106 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>] 107 // -------------- Loop 108 /// CHECK-DAG: <<Index:i\d+>> Phi 109 /// CHECK-DAG: If 110 /// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const0>>] 111 /// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array>>,<<Address1>>] 112 /// CHECK-DAG: <<Add:d\d+>> VecAdd [<<Load>>,<<Repl>>] 113 /// CHECK-NOT: IntermediateAddress 114 /// CHECK-DAG: VecStore [<<Array>>,<<Address1>>,<<Add>>] 115 116 /// CHECK-START-ARM64: void Main.checkByteCase(byte[]) disassembly (after) 117 /// CHECK: IntermediateAddressIndex 118 /// CHECK-NEXT: add w{{[0-9]+}}, w{{[0-9]+}}, #0x{{[0-9a-fA-F]+}} 119 /// CHECK: VecLoad 120 /// CHECK-NEXT: ldr q{{[0-9]+}}, [x{{[0-9]+}}, x{{[0-9]+}}] 121 /// CHECK: VecStore 122 /// CHECK-NEXT: str q{{[0-9]+}}, [x{{[0-9]+}}, x{{[0-9]+}}] checkByteCase(byte[] a)123 public static void checkByteCase(byte[] a) { 124 for (int i = 0; i < 128; i++) { 125 a[i] += 5; 126 } 127 } 128 129 /// CHECK-START-ARM64: void Main.checkSingleAccess(int[]) instruction_simplifier_arm64 (before) 130 /// CHECK-DAG: <<Array:l\d+>> ParameterValue 131 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 132 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>] 133 // -------------- Loop 134 /// CHECK-DAG: <<Index:i\d+>> Phi 135 /// CHECK-DAG: If 136 /// CHECK-DAG: VecStore [<<Array>>,<<Index>>,<<Repl>>] 137 138 /// CHECK-START-ARM64: void Main.checkSingleAccess(int[]) instruction_simplifier_arm64 (after) 139 /// CHECK-DAG: <<Array:l\d+>> ParameterValue 140 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 141 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 142 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const5>>] 143 // -------------- Loop 144 /// CHECK-DAG: <<Index:i\d+>> Phi 145 /// CHECK-DAG: If 146 /// CHECK-DAG: VecStore [<<Array>>,<<Index>>,<<Repl>>] 147 /// CHECK-NOT: IntermediateAddress checkSingleAccess(int[] a)148 public static void checkSingleAccess(int[] a) { 149 for (int i = 0; i < 128; i++) { 150 a[i] = 5; 151 } 152 } 153 154 /// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) instruction_simplifier_arm64 (before) 155 /// CHECK-DAG: <<Array1:l\d+>> ParameterValue 156 /// CHECK-DAG: <<Array2:l\d+>> ParameterValue 157 // -------------- Loop 158 /// CHECK-DAG: <<Index:i\d+>> Phi 159 /// CHECK-DAG: If 160 /// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array1>>,<<Index>>] 161 /// CHECK-DAG: <<Cnv:d\d+>> VecCnv [<<Load>>] 162 /// CHECK-DAG: VecStore [<<Array2>>,<<Index>>,<<Cnv>>] 163 164 /// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) instruction_simplifier_arm64 (after) 165 /// CHECK-DAG: <<Array1:l\d+>> ParameterValue 166 /// CHECK-DAG: <<Array2:l\d+>> ParameterValue 167 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12 168 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 169 // -------------- Loop 170 /// CHECK-DAG: <<Index:i\d+>> Phi 171 /// CHECK-DAG: If 172 /// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>] 173 /// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array1>>,<<Address1>>] 174 /// CHECK-DAG: <<Cnv:d\d+>> VecCnv [<<Load>>] 175 /// CHECK-DAG: <<Address2:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>] 176 /// CHECK-DAG: VecStore [<<Array2>>,<<Address2>>,<<Cnv>>] 177 178 /// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) GVN$after_arch (after) 179 /// CHECK-DAG: <<Array1:l\d+>> ParameterValue 180 /// CHECK-DAG: <<Array2:l\d+>> ParameterValue 181 /// CHECK-DAG: <<DataOffset:i\d+>> IntConstant 12 182 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 183 // -------------- Loop 184 /// CHECK-DAG: <<Index:i\d+>> Phi 185 /// CHECK-DAG: If 186 /// CHECK-DAG: <<Address1:i\d+>> IntermediateAddressIndex [<<Index>>,<<DataOffset>>,<<Const2>>] 187 /// CHECK-DAG: <<Load:d\d+>> VecLoad [<<Array1>>,<<Address1>>] 188 /// CHECK-DAG: <<Cnv:d\d+>> VecCnv [<<Load>>] 189 /// CHECK-NOT: IntermediateAddress 190 /// CHECK-DAG: VecStore [<<Array2>>,<<Address1>>,<<Cnv>>] 191 192 /// CHECK-START-ARM64: void Main.checkInt2Float(int[], float[]) disassembly (after) 193 /// CHECK: IntermediateAddressIndex 194 /// CHECK-NEXT: add w{{[0-9]+}}, w{{[0-9]+}}, w{{[0-9]+}}, lsl #2 checkInt2Float(int[] a, float[] b)195 public static void checkInt2Float(int[] a, float[] b) { 196 for (int i = 0; i < 128; i++) { 197 b[i] = (float) a[i]; 198 } 199 } 200 201 public static final int ARRAY_SIZE = 1024; 202 calcArraySum(int[] a, byte[] b, float[] c)203 public static int calcArraySum(int[] a, byte[] b, float[] c) { 204 int sum = 0; 205 for (int i = 0; i < 128; i++) { 206 sum += a[i] + b[i] + (int) c[i]; 207 } 208 return sum; 209 } 210 main(String[] args)211 public static void main(String[] args) { 212 byte[] ba = new byte[ARRAY_SIZE]; 213 int[] ia = new int[ARRAY_SIZE]; 214 float[] fa = new float[ARRAY_SIZE]; 215 216 checkSingleAccess(ia); 217 checkIntCase(ia); 218 checkByteCase(ba); 219 checkInt2Float(ia, fa); 220 221 assertIntEquals(3200, calcArraySum(ia, ba, fa)); 222 } 223 } 224