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 /** 18 * Functional tests for SIMD vectorization. 19 */ 20 public class Main { 21 22 static short[] a; 23 24 // 25 // Arithmetic operations. 26 // 27 28 /// CHECK-START: void Main.add(int) loop_optimization (before) 29 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 30 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 31 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 32 // 33 /// CHECK-START-ARM64: void Main.add(int) loop_optimization (after) 34 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 35 /// CHECK-DAG: VecLoad loop:<<Loop>> outer_loop:none 36 /// CHECK-DAG: VecAdd loop:<<Loop>> outer_loop:none 37 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none add(int x)38 static void add(int x) { 39 for (int i = 0; i < 128; i++) 40 a[i] += x; 41 } 42 43 /// CHECK-START: void Main.sub(int) loop_optimization (before) 44 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 45 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 46 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 47 // 48 /// CHECK-START-ARM64: void Main.sub(int) loop_optimization (after) 49 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 50 /// CHECK-DAG: VecLoad loop:<<Loop>> outer_loop:none 51 /// CHECK-DAG: VecSub loop:<<Loop>> outer_loop:none 52 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none sub(int x)53 static void sub(int x) { 54 for (int i = 0; i < 128; i++) 55 a[i] -= x; 56 } 57 58 /// CHECK-START: void Main.mul(int) loop_optimization (before) 59 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 60 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 61 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 62 // 63 /// CHECK-START-ARM64: void Main.mul(int) loop_optimization (after) 64 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 65 /// CHECK-DAG: VecLoad loop:<<Loop>> outer_loop:none 66 /// CHECK-DAG: VecMul loop:<<Loop>> outer_loop:none 67 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none mul(int x)68 static void mul(int x) { 69 for (int i = 0; i < 128; i++) 70 a[i] *= x; 71 } 72 73 /// CHECK-START: void Main.div(int) loop_optimization (before) 74 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 75 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 76 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 77 // 78 /// CHECK-START: void Main.div(int) loop_optimization (after) 79 // 80 // Not supported on any architecture. 81 // div(int x)82 static void div(int x) { 83 for (int i = 0; i < 128; i++) 84 a[i] /= x; 85 } 86 87 /// CHECK-START: void Main.neg() loop_optimization (before) 88 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 89 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 90 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 91 // 92 /// CHECK-START-ARM64: void Main.neg() loop_optimization (after) 93 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 94 /// CHECK-DAG: VecLoad loop:<<Loop>> outer_loop:none 95 /// CHECK-DAG: VecNeg loop:<<Loop>> outer_loop:none 96 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none neg()97 static void neg() { 98 for (int i = 0; i < 128; i++) 99 a[i] = (short) -a[i]; 100 } 101 102 /// CHECK-START: void Main.not() loop_optimization (before) 103 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 104 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 105 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 106 // 107 /// CHECK-START-ARM64: void Main.not() loop_optimization (after) 108 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 109 /// CHECK-DAG: VecLoad loop:<<Loop>> outer_loop:none 110 /// CHECK-DAG: VecNot loop:<<Loop>> outer_loop:none 111 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none not()112 static void not() { 113 for (int i = 0; i < 128; i++) 114 a[i] = (short) ~a[i]; 115 } 116 117 /// CHECK-START: void Main.shl4() loop_optimization (before) 118 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 119 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 120 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 121 // 122 /// CHECK-START-ARM64: void Main.shl4() loop_optimization (after) 123 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 124 /// CHECK-DAG: VecLoad loop:<<Loop>> outer_loop:none 125 /// CHECK-DAG: VecShl loop:<<Loop>> outer_loop:none 126 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none shl4()127 static void shl4() { 128 for (int i = 0; i < 128; i++) 129 a[i] <<= 4; 130 } 131 132 /// CHECK-START: void Main.sar2() loop_optimization (before) 133 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 134 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 135 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 136 // 137 /// CHECK-START-ARM64: void Main.sar2() loop_optimization (after) 138 // 139 // TODO: fill in when supported sar2()140 static void sar2() { 141 for (int i = 0; i < 128; i++) 142 a[i] >>= 2; 143 } 144 145 /// CHECK-START: void Main.shr2() loop_optimization (before) 146 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 147 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 148 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 149 // 150 /// CHECK-START-ARM64: void Main.shr2() loop_optimization (after) 151 // 152 // TODO: fill in when supported shr2()153 static void shr2() { 154 for (int i = 0; i < 128; i++) 155 a[i] >>>= 2; 156 } 157 158 // 159 // Shift sanity. 160 // 161 sar31()162 static void sar31() { 163 for (int i = 0; i < 128; i++) 164 a[i] >>= 31; 165 } 166 shr31()167 static void shr31() { 168 for (int i = 0; i < 128; i++) 169 a[i] >>>= 31; 170 } 171 shr32()172 static void shr32() { 173 for (int i = 0; i < 128; i++) 174 a[i] >>>= 32; // 0, since & 31 175 } 176 177 shr33()178 static void shr33() { 179 for (int i = 0; i < 128; i++) 180 a[i] >>>= 33; // 1, since & 31 181 } 182 183 // 184 // Loop bounds. 185 // 186 add()187 static void add() { 188 for (int i = 1; i < 127; i++) 189 a[i] += 11; 190 } 191 192 // 193 // Test Driver. 194 // 195 main(String[] args)196 public static void main(String[] args) { 197 // Set up. 198 a = new short[128]; 199 for (int i = 0; i < 128; i++) { 200 a[i] = (short) i; 201 } 202 // Arithmetic operations. 203 add(2); 204 for (int i = 0; i < 128; i++) { 205 expectEquals(i + 2, a[i], "add"); 206 } 207 sub(2); 208 for (int i = 0; i < 128; i++) { 209 expectEquals(i, a[i], "sub"); 210 } 211 mul(2); 212 for (int i = 0; i < 128; i++) { 213 expectEquals(i + i, a[i], "mul"); 214 } 215 div(2); 216 for (int i = 0; i < 128; i++) { 217 expectEquals(i, a[i], "div"); 218 } 219 neg(); 220 for (int i = 0; i < 128; i++) { 221 expectEquals(-i, a[i], "neg"); 222 } 223 // Loop bounds. 224 add(); 225 expectEquals(0, a[0], "bounds0"); 226 for (int i = 1; i < 127; i++) { 227 expectEquals(11 - i, a[i], "bounds"); 228 } 229 expectEquals(-127, a[127], "bounds127"); 230 // Shifts. 231 for (int i = 0; i < 128; i++) { 232 a[i] = (short) 0xffff; 233 } 234 shl4(); 235 for (int i = 0; i < 128; i++) { 236 expectEquals((short) 0xfff0, a[i], "shl4"); 237 } 238 sar2(); 239 for (int i = 0; i < 128; i++) { 240 expectEquals((short) 0xfffc, a[i], "sar2"); 241 } 242 shr2(); 243 for (int i = 0; i < 128; i++) { 244 expectEquals((short) 0xffff, a[i], "shr2"); // sic! 245 } 246 sar31(); 247 for (int i = 0; i < 128; i++) { 248 expectEquals((short) 0xffff, a[i], "sar31"); 249 } 250 shr31(); 251 for (int i = 0; i < 128; i++) { 252 expectEquals(0x0001, a[i], "shr31"); 253 a[i] = (short) 0x1200; // reset 254 } 255 shr32(); 256 for (int i = 0; i < 128; i++) { 257 expectEquals((short) 0x1200, a[i], "shr32"); 258 } 259 shr33(); 260 for (int i = 0; i < 128; i++) { 261 expectEquals((short) 0x0900, a[i], "shr33"); 262 a[i] = (short) 0xf0f1; // reset 263 } 264 not(); 265 for (int i = 0; i < 128; i++) { 266 expectEquals((short) 0x0f0e, a[i], "not"); 267 } 268 // Done. 269 System.out.println("passed"); 270 } 271 expectEquals(int expected, int result, String action)272 private static void expectEquals(int expected, int result, String action) { 273 if (expected != result) { 274 throw new Error("Expected: " + expected + ", found: " + result + " for " + action); 275 } 276 } 277 } 278