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 long[] a; 23 24 // 25 // Arithmetic operations. 26 // 27 28 /// CHECK-START: void Main.add(long) 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(long) 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(long x)38 static void add(long x) { 39 for (int i = 0; i < 128; i++) 40 a[i] += x; 41 } 42 43 /// CHECK-START: void Main.sub(long) 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(long) 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(long x)53 static void sub(long x) { 54 for (int i = 0; i < 128; i++) 55 a[i] -= x; 56 } 57 58 /// CHECK-START: void Main.mul(long) 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 // Not supported for longs. 64 /// CHECK-START-ARM64: void Main.mul(long) loop_optimization (after) 65 /// CHECK-NOT: VecMul mul(long x)66 static void mul(long x) { 67 for (int i = 0; i < 128; i++) 68 a[i] *= x; 69 } 70 71 /// CHECK-START: void Main.div(long) loop_optimization (before) 72 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 73 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 74 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 75 // 76 /// CHECK-START: void Main.div(long) loop_optimization (after) 77 // 78 // Not supported on any architecture. 79 // div(long x)80 static void div(long x) { 81 for (int i = 0; i < 128; i++) 82 a[i] /= x; 83 } 84 85 /// CHECK-START: void Main.neg() loop_optimization (before) 86 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 87 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 88 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 89 // 90 /// CHECK-START-ARM64: void Main.neg() loop_optimization (after) 91 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 92 /// CHECK-DAG: VecLoad loop:<<Loop>> outer_loop:none 93 /// CHECK-DAG: VecNeg loop:<<Loop>> outer_loop:none 94 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none neg()95 static void neg() { 96 for (int i = 0; i < 128; i++) 97 a[i] = -a[i]; 98 } 99 100 /// CHECK-START: void Main.not() loop_optimization (before) 101 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 102 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 103 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 104 // 105 /// CHECK-START-ARM64: void Main.not() loop_optimization (after) 106 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 107 /// CHECK-DAG: VecLoad loop:<<Loop>> outer_loop:none 108 /// CHECK-DAG: VecNot loop:<<Loop>> outer_loop:none 109 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none not()110 static void not() { 111 for (int i = 0; i < 128; i++) 112 a[i] = ~a[i]; 113 } 114 115 /// CHECK-START: void Main.shl4() loop_optimization (before) 116 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 117 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 118 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 119 // 120 /// CHECK-START-ARM64: void Main.shl4() loop_optimization (after) 121 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 122 /// CHECK-DAG: VecLoad loop:<<Loop>> outer_loop:none 123 /// CHECK-DAG: VecShl loop:<<Loop>> outer_loop:none 124 /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none shl4()125 static void shl4() { 126 for (int i = 0; i < 128; i++) 127 a[i] <<= 4; 128 } 129 130 /// CHECK-START: void Main.sar2() loop_optimization (before) 131 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 132 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 133 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 134 // 135 /// CHECK-START-ARM64: void Main.sar2() loop_optimization (after) 136 // 137 // TODO: fill in when supported sar2()138 static void sar2() { 139 for (int i = 0; i < 128; i++) 140 a[i] >>= 2; 141 } 142 143 /// CHECK-START: void Main.shr2() loop_optimization (before) 144 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 145 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 146 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 147 // 148 /// CHECK-START-ARM64: void Main.shr2() loop_optimization (after) 149 // 150 // TODO: fill in when supported shr2()151 static void shr2() { 152 for (int i = 0; i < 128; i++) 153 a[i] >>>= 2; 154 } 155 156 // 157 // Shift sanity. 158 // 159 shr64()160 static void shr64() { 161 for (int i = 0; i < 128; i++) 162 a[i] >>>= 64; // 0, since & 63 163 } 164 shr65()165 static void shr65() { 166 for (int i = 0; i < 128; i++) 167 a[i] >>>= 65; // 1, since & 63 168 } 169 170 // 171 // Loop bounds. 172 // 173 bounds()174 static void bounds() { 175 for (int i = 1; i < 127; i++) 176 a[i] += 11; 177 } 178 179 // 180 // Test Driver. 181 // 182 main(String[] args)183 public static void main(String[] args) { 184 // Set up. 185 a = new long[128]; 186 for (int i = 0; i < 128; i++) { 187 a[i] = i; 188 } 189 // Arithmetic operations. 190 add(2L); 191 for (int i = 0; i < 128; i++) { 192 expectEquals(i + 2, a[i], "add"); 193 } 194 sub(2L); 195 for (int i = 0; i < 128; i++) { 196 expectEquals(i, a[i], "sub"); 197 } 198 mul(2L); 199 for (int i = 0; i < 128; i++) { 200 expectEquals(i + i, a[i], "mul"); 201 } 202 div(2L); 203 for (int i = 0; i < 128; i++) { 204 expectEquals(i, a[i], "div"); 205 } 206 neg(); 207 for (int i = 0; i < 128; i++) { 208 expectEquals(-i, a[i], "neg"); 209 } 210 // Loop bounds. 211 bounds(); 212 expectEquals(0, a[0], "bounds0"); 213 for (int i = 1; i < 127; i++) { 214 expectEquals(11 - i, a[i], "bounds"); 215 } 216 expectEquals(-127, a[127], "bounds127"); 217 // Shifts. 218 for (int i = 0; i < 128; i++) { 219 a[i] = 0xffffffffffffffffL; 220 } 221 shl4(); 222 for (int i = 0; i < 128; i++) { 223 expectEquals(0xfffffffffffffff0L, a[i], "shl4"); 224 } 225 sar2(); 226 for (int i = 0; i < 128; i++) { 227 expectEquals(0xfffffffffffffffcL, a[i], "sar2"); 228 } 229 shr2(); 230 for (int i = 0; i < 128; i++) { 231 expectEquals(0x3fffffffffffffffL, a[i], "shr2"); 232 } 233 shr64(); 234 for (int i = 0; i < 128; i++) { 235 expectEquals(0x3fffffffffffffffL, a[i], "shr64"); 236 } 237 shr65(); 238 for (int i = 0; i < 128; i++) { 239 expectEquals(0x1fffffffffffffffL, a[i], "shr65"); 240 } 241 not(); 242 for (int i = 0; i < 128; i++) { 243 expectEquals(0xe000000000000000L, a[i], "not"); 244 } 245 // Done. 246 System.out.println("passed"); 247 } 248 expectEquals(long expected, long result, String action)249 private static void expectEquals(long expected, long result, String action) { 250 if (expected != result) { 251 throw new Error("Expected: " + expected + ", found: " + result + " for " + action); 252 } 253 } 254 } 255