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 char[] 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] = (char) -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] = (char) ~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 shr33()177 static void shr33() { 178 for (int i = 0; i < 128; i++) 179 a[i] >>>= 33; // 1, since & 31 180 } 181 182 // 183 // Loop bounds. 184 // 185 bounds()186 static void bounds() { 187 for (int i = 1; i < 127; i++) 188 a[i] += 11; 189 } 190 191 // 192 // Test Driver. 193 // 194 main(String[] args)195 public static void main(String[] args) { 196 // Set up. 197 a = new char[128]; 198 for (int i = 0; i < 128; i++) { 199 a[i] = (char) i; 200 } 201 // Arithmetic operations. 202 add(2); 203 for (int i = 0; i < 128; i++) { 204 expectEquals(i + 2, a[i], "add"); 205 } 206 sub(2); 207 for (int i = 0; i < 128; i++) { 208 expectEquals(i, a[i], "sub"); 209 } 210 mul(2); 211 for (int i = 0; i < 128; i++) { 212 expectEquals(i + i, a[i], "mul"); 213 } 214 div(2); 215 for (int i = 0; i < 128; i++) { 216 expectEquals(i, a[i], "div"); 217 } 218 neg(); 219 for (int i = 0; i < 128; i++) { 220 expectEquals((char)-i, a[i], "neg"); 221 } 222 // Loop bounds. 223 bounds(); 224 expectEquals(0, a[0], "bounds0"); 225 for (int i = 1; i < 127; i++) { 226 expectEquals((char)(11 - i), a[i], "bounds"); 227 } 228 expectEquals((char)-127, a[127], "bounds127"); 229 // Shifts. 230 for (int i = 0; i < 128; i++) { 231 a[i] = (char) 0xffff; 232 } 233 shl4(); 234 for (int i = 0; i < 128; i++) { 235 expectEquals((char) 0xfff0, a[i], "shl4"); 236 } 237 sar2(); 238 for (int i = 0; i < 128; i++) { 239 expectEquals((char) 0x3ffc, a[i], "sar2"); 240 } 241 shr2(); 242 for (int i = 0; i < 128; i++) { 243 expectEquals((char) 0x0fff, a[i], "shr2"); 244 a[i] = (char) 0xffff; // reset 245 } 246 sar31(); 247 for (int i = 0; i < 128; i++) { 248 expectEquals(0, a[i], "sar31"); 249 a[i] = (char) 0xffff; // reset 250 } 251 shr31(); 252 for (int i = 0; i < 128; i++) { 253 expectEquals(0, a[i], "shr31"); 254 a[i] = (char) 0x1200; // reset 255 } 256 shr32(); 257 for (int i = 0; i < 128; i++) { 258 expectEquals((char) 0x1200, a[i], "shr32"); 259 } 260 shr33(); 261 for (int i = 0; i < 128; i++) { 262 expectEquals((char) 0x0900, a[i], "shr33"); 263 a[i] = (char) 0xf1f0; // reset 264 } 265 not(); 266 for (int i = 0; i < 128; i++) { 267 expectEquals((char) 0x0e0f, a[i], "not"); 268 } 269 // Done. 270 System.out.println("passed"); 271 } 272 expectEquals(int expected, int result, String action)273 private static void expectEquals(int expected, int result, String action) { 274 if (expected != result) { 275 throw new Error("Expected: " + expected + ", found: " + result + " for " + action); 276 } 277 } 278 } 279