1 // RUN: %clang_cc1 -std=c++14 -Wno-unused-value %s -disable-llvm-passes -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s 2 3 // FIXME: Unfortunately there is no good way to validate that our values are 4 // correct since Vector types don't have operator [] implemented for constexpr. 5 // Instead, we need to use filecheck to ensure the emitted IR is correct. Once 6 // someone implements array subscript operator for these types as constexpr, 7 // this test should modified to jsut use static asserts. 8 9 using FourCharsVecSize __attribute__((vector_size(4))) = char; 10 using FourIntsVecSize __attribute__((vector_size(16))) = int; 11 using FourLongLongsVecSize __attribute__((vector_size(32))) = long long; 12 using FourFloatsVecSize __attribute__((vector_size(16))) = float; 13 using FourDoublesVecSize __attribute__((vector_size(32))) = double; 14 using FourI128VecSize __attribute__((vector_size(64))) = __int128; 15 16 using FourCharsExtVec __attribute__((ext_vector_type(4))) = char; 17 using FourIntsExtVec __attribute__((ext_vector_type(4))) = int; 18 using FourLongLongsExtVec __attribute__((ext_vector_type(4))) = long long; 19 using FourFloatsExtVec __attribute__((ext_vector_type(4))) = float; 20 using FourDoublesExtVec __attribute__((ext_vector_type(4))) = double; 21 using FourI128ExtVec __attribute__((ext_vector_type(4))) = __int128; 22 23 24 // Next a series of tests to make sure these operations are usable in 25 // constexpr functions. Template instantiations don't emit Winvalid-constexpr, 26 // so we have to do these as macros. 27 #define MathShiftOps(Type) \ 28 constexpr auto MathShiftOps##Type(Type a, Type b) { \ 29 a = a + b; \ 30 a = a - b; \ 31 a = a * b; \ 32 a = a / b; \ 33 b = a + 1; \ 34 b = a - 1; \ 35 b = a * 1; \ 36 b = a / 1; \ 37 a += a; \ 38 a -= a; \ 39 a *= a; \ 40 a /= a; \ 41 b += a; \ 42 b -= a; \ 43 b *= a; \ 44 b /= a; \ 45 a < b; \ 46 a > b; \ 47 a <= b; \ 48 a >= b; \ 49 a == b; \ 50 a != b; \ 51 a &&b; \ 52 a || b; \ 53 auto c = (a, b); \ 54 return c; \ 55 } 56 57 // Ops specific to Integers. 58 #define MathShiftOpsInts(Type) \ 59 constexpr auto MathShiftopsInts##Type(Type a, Type b) { \ 60 a = a << b; \ 61 a = a >> b; \ 62 a = a << 3; \ 63 a = a >> 3; \ 64 a = 3 << b; \ 65 a = 3 >> b; \ 66 a <<= b; \ 67 a >>= b; \ 68 a <<= 3; \ 69 a >>= 3; \ 70 a = a % b; \ 71 a &b; \ 72 a | b; \ 73 a ^ b; \ 74 return a; \ 75 } 76 77 MathShiftOps(FourCharsVecSize); 78 MathShiftOps(FourIntsVecSize); 79 MathShiftOps(FourLongLongsVecSize); 80 MathShiftOps(FourFloatsVecSize); 81 MathShiftOps(FourDoublesVecSize); 82 MathShiftOps(FourCharsExtVec); 83 MathShiftOps(FourIntsExtVec); 84 MathShiftOps(FourLongLongsExtVec); 85 MathShiftOps(FourFloatsExtVec); 86 MathShiftOps(FourDoublesExtVec); 87 88 MathShiftOpsInts(FourCharsVecSize); 89 MathShiftOpsInts(FourIntsVecSize); 90 MathShiftOpsInts(FourLongLongsVecSize); 91 MathShiftOpsInts(FourCharsExtVec); 92 MathShiftOpsInts(FourIntsExtVec); 93 MathShiftOpsInts(FourLongLongsExtVec); 94 95 template <typename T, typename U> 96 constexpr auto CmpMul(T t, U u) { 97 t *= u; 98 return t; 99 } 100 template <typename T, typename U> 101 constexpr auto CmpDiv(T t, U u) { 102 t /= u; 103 return t; 104 } 105 template <typename T, typename U> 106 constexpr auto CmpRem(T t, U u) { 107 t %= u; 108 return t; 109 } 110 111 template <typename T, typename U> 112 constexpr auto CmpAdd(T t, U u) { 113 t += u; 114 return t; 115 } 116 117 template <typename T, typename U> 118 constexpr auto CmpSub(T t, U u) { 119 t -= u; 120 return t; 121 } 122 123 template <typename T, typename U> 124 constexpr auto CmpLSH(T t, U u) { 125 t <<= u; 126 return t; 127 } 128 129 template <typename T, typename U> 130 constexpr auto CmpRSH(T t, U u) { 131 t >>= u; 132 return t; 133 } 134 135 template <typename T, typename U> 136 constexpr auto CmpBinAnd(T t, U u) { 137 t &= u; 138 return t; 139 } 140 141 template <typename T, typename U> 142 constexpr auto CmpBinXOr(T t, U u) { 143 t ^= u; 144 return t; 145 } 146 147 template <typename T, typename U> 148 constexpr auto CmpBinOr(T t, U u) { 149 t |= u; 150 return t; 151 } 152 153 // Only int vs float makes a difference here, so we only need to test 1 of each. 154 // Test Char to make sure the mixed-nature of shifts around char is evident. 155 void CharUsage() { 156 constexpr auto a = FourCharsVecSize{6, 3, 2, 1} + 157 FourCharsVecSize{12, 15, 5, 7}; 158 // CHECK: store <4 x i8> <i8 18, i8 18, i8 7, i8 8> 159 constexpr auto b = FourCharsVecSize{19, 15, 13, 12} - 160 FourCharsVecSize{13, 14, 5, 3}; 161 // CHECK: store <4 x i8> <i8 6, i8 1, i8 8, i8 9> 162 constexpr auto c = FourCharsVecSize{8, 4, 2, 1} * 163 FourCharsVecSize{3, 4, 5, 6}; 164 // CHECK: store <4 x i8> <i8 24, i8 16, i8 10, i8 6> 165 constexpr auto d = FourCharsVecSize{12, 12, 10, 10} / 166 FourCharsVecSize{6, 4, 5, 2}; 167 // CHECK: store <4 x i8> <i8 2, i8 3, i8 2, i8 5> 168 constexpr auto e = FourCharsVecSize{12, 12, 10, 10} % 169 FourCharsVecSize{6, 4, 4, 3}; 170 // CHECK: store <4 x i8> <i8 0, i8 0, i8 2, i8 1> 171 172 constexpr auto f = FourCharsVecSize{6, 3, 2, 1} + 3; 173 // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4> 174 constexpr auto g = FourCharsVecSize{19, 15, 12, 10} - 3; 175 // CHECK: store <4 x i8> <i8 16, i8 12, i8 9, i8 7> 176 constexpr auto h = FourCharsVecSize{8, 4, 2, 1} * 3; 177 // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3> 178 constexpr auto j = FourCharsVecSize{12, 15, 18, 21} / 3; 179 // CHECK: store <4 x i8> <i8 4, i8 5, i8 6, i8 7> 180 constexpr auto k = FourCharsVecSize{12, 17, 19, 22} % 3; 181 // CHECK: store <4 x i8> <i8 0, i8 2, i8 1, i8 1> 182 183 constexpr auto l = 3 + FourCharsVecSize{6, 3, 2, 1}; 184 // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4> 185 constexpr auto m = 20 - FourCharsVecSize{19, 15, 12, 10}; 186 // CHECK: store <4 x i8> <i8 1, i8 5, i8 8, i8 10> 187 constexpr auto n = 3 * FourCharsVecSize{8, 4, 2, 1}; 188 // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3> 189 constexpr auto o = 100 / FourCharsVecSize{12, 15, 18, 21}; 190 // CHECK: store <4 x i8> <i8 8, i8 6, i8 5, i8 4> 191 constexpr auto p = 100 % FourCharsVecSize{12, 15, 18, 21}; 192 // CHECK: store <4 x i8> <i8 4, i8 10, i8 10, i8 16> 193 194 constexpr auto q = FourCharsVecSize{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2}; 195 // CHECK: store <4 x i8> <i8 12, i8 6, i8 8, i8 4> 196 constexpr auto r = FourCharsVecSize{19, 15, 12, 10} >> 197 FourCharsVecSize{1, 1, 2, 2}; 198 // CHECK: store <4 x i8> <i8 9, i8 7, i8 3, i8 2> 199 constexpr auto s = FourCharsVecSize{6, 3, 5, 10} << 1; 200 // CHECK: store <4 x i8> <i8 12, i8 6, i8 10, i8 20> 201 constexpr auto t = FourCharsVecSize{19, 15, 10, 20} >> 1; 202 // CHECK: store <4 x i8> <i8 9, i8 7, i8 5, i8 10> 203 constexpr auto u = 12 << FourCharsVecSize{1, 2, 3, 3}; 204 // CHECK: store <4 x i8> <i8 24, i8 48, i8 96, i8 96> 205 constexpr auto v = 12 >> FourCharsVecSize{1, 2, 2, 1}; 206 // CHECK: store <4 x i8> <i8 6, i8 3, i8 3, i8 6> 207 208 constexpr auto w = FourCharsVecSize{1, 2, 3, 4} < 209 FourCharsVecSize{4, 3, 2, 1}; 210 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0> 211 constexpr auto x = FourCharsVecSize{1, 2, 3, 4} > 212 FourCharsVecSize{4, 3, 2, 1}; 213 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1> 214 constexpr auto y = FourCharsVecSize{1, 2, 3, 4} <= 215 FourCharsVecSize{4, 3, 3, 1}; 216 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0> 217 constexpr auto z = FourCharsVecSize{1, 2, 3, 4} >= 218 FourCharsVecSize{4, 3, 3, 1}; 219 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1> 220 constexpr auto A = FourCharsVecSize{1, 2, 3, 4} == 221 FourCharsVecSize{4, 3, 3, 1}; 222 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0> 223 constexpr auto B = FourCharsVecSize{1, 2, 3, 4} != 224 FourCharsVecSize{4, 3, 3, 1}; 225 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1> 226 227 constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3; 228 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0> 229 constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3; 230 // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 -1> 231 constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3; 232 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0> 233 constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3; 234 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1> 235 constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3; 236 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0> 237 constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3; 238 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1> 239 240 constexpr auto I = FourCharsVecSize{1, 2, 3, 4} & 241 FourCharsVecSize{4, 3, 2, 1}; 242 // CHECK: store <4 x i8> <i8 0, i8 2, i8 2, i8 0> 243 constexpr auto J = FourCharsVecSize{1, 2, 3, 4} ^ 244 FourCharsVecSize { 4, 3, 2, 1 }; 245 // CHECK: store <4 x i8> <i8 5, i8 1, i8 1, i8 5> 246 constexpr auto K = FourCharsVecSize{1, 2, 3, 4} | 247 FourCharsVecSize{4, 3, 2, 1}; 248 // CHECK: store <4 x i8> <i8 5, i8 3, i8 3, i8 5> 249 constexpr auto L = FourCharsVecSize{1, 2, 3, 4} & 3; 250 // CHECK: store <4 x i8> <i8 1, i8 2, i8 3, i8 0> 251 constexpr auto M = FourCharsVecSize{1, 2, 3, 4} ^ 3; 252 // CHECK: store <4 x i8> <i8 2, i8 1, i8 0, i8 7> 253 constexpr auto N = FourCharsVecSize{1, 2, 3, 4} | 3; 254 // CHECK: store <4 x i8> <i8 3, i8 3, i8 3, i8 7> 255 256 constexpr auto O = FourCharsVecSize{5, 0, 6, 0} && 257 FourCharsVecSize{5, 5, 0, 0}; 258 // CHECK: store <4 x i8> <i8 1, i8 0, i8 0, i8 0> 259 constexpr auto P = FourCharsVecSize{5, 0, 6, 0} || 260 FourCharsVecSize{5, 5, 0, 0}; 261 // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0> 262 263 constexpr auto Q = FourCharsVecSize{5, 0, 6, 0} && 3; 264 // CHECK: store <4 x i8> <i8 1, i8 0, i8 1, i8 0> 265 constexpr auto R = FourCharsVecSize{5, 0, 6, 0} || 3; 266 // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 1> 267 268 constexpr auto T = CmpMul(a, b); 269 // CHECK: store <4 x i8> <i8 108, i8 18, i8 56, i8 72> 270 271 constexpr auto U = CmpDiv(a, b); 272 // CHECK: store <4 x i8> <i8 3, i8 18, i8 0, i8 0> 273 274 constexpr auto V = CmpRem(a, b); 275 // CHECK: store <4 x i8> <i8 0, i8 0, i8 7, i8 8> 276 277 constexpr auto X = CmpAdd(a, b); 278 // CHECK: store <4 x i8> <i8 24, i8 19, i8 15, i8 17> 279 280 constexpr auto Y = CmpSub(a, b); 281 // CHECK: store <4 x i8> <i8 12, i8 17, i8 -1, i8 -1> 282 283 constexpr auto InvH = -H; 284 // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1> 285 constexpr auto Z = CmpLSH(a, InvH); 286 // CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16> 287 288 constexpr auto aa = CmpRSH(a, InvH); 289 // CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4> 290 291 constexpr auto ab = CmpBinAnd(a, b); 292 // CHECK: store <4 x i8> <i8 2, i8 0, i8 0, i8 8> 293 294 constexpr auto ac = CmpBinXOr(a, b); 295 // CHECK: store <4 x i8> <i8 20, i8 19, i8 15, i8 1> 296 297 constexpr auto ad = CmpBinOr(a, b); 298 // CHECK: store <4 x i8> <i8 22, i8 19, i8 15, i8 9> 299 300 constexpr auto ae = ~FourCharsVecSize{1, 2, 10, 20}; 301 // CHECK: store <4 x i8> <i8 -2, i8 -3, i8 -11, i8 -21> 302 303 constexpr auto af = !FourCharsVecSize{0, 1, 8, -1}; 304 // CHECK: store <4 x i8> <i8 -1, i8 0, i8 0, i8 0> 305 } 306 307 void CharExtVecUsage() { 308 constexpr auto a = FourCharsExtVec{6, 3, 2, 1} + 309 FourCharsExtVec{12, 15, 5, 7}; 310 // CHECK: store <4 x i8> <i8 18, i8 18, i8 7, i8 8> 311 constexpr auto b = FourCharsExtVec{19, 15, 13, 12} - 312 FourCharsExtVec{13, 14, 5, 3}; 313 // CHECK: store <4 x i8> <i8 6, i8 1, i8 8, i8 9> 314 constexpr auto c = FourCharsExtVec{8, 4, 2, 1} * 315 FourCharsExtVec{3, 4, 5, 6}; 316 // CHECK: store <4 x i8> <i8 24, i8 16, i8 10, i8 6> 317 constexpr auto d = FourCharsExtVec{12, 12, 10, 10} / 318 FourCharsExtVec{6, 4, 5, 2}; 319 // CHECK: store <4 x i8> <i8 2, i8 3, i8 2, i8 5> 320 constexpr auto e = FourCharsExtVec{12, 12, 10, 10} % 321 FourCharsExtVec{6, 4, 4, 3}; 322 // CHECK: store <4 x i8> <i8 0, i8 0, i8 2, i8 1> 323 324 constexpr auto f = FourCharsExtVec{6, 3, 2, 1} + 3; 325 // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4> 326 constexpr auto g = FourCharsExtVec{19, 15, 12, 10} - 3; 327 // CHECK: store <4 x i8> <i8 16, i8 12, i8 9, i8 7> 328 constexpr auto h = FourCharsExtVec{8, 4, 2, 1} * 3; 329 // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3> 330 constexpr auto j = FourCharsExtVec{12, 15, 18, 21} / 3; 331 // CHECK: store <4 x i8> <i8 4, i8 5, i8 6, i8 7> 332 constexpr auto k = FourCharsExtVec{12, 17, 19, 22} % 3; 333 // CHECK: store <4 x i8> <i8 0, i8 2, i8 1, i8 1> 334 335 constexpr auto l = 3 + FourCharsExtVec{6, 3, 2, 1}; 336 // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4> 337 constexpr auto m = 20 - FourCharsExtVec{19, 15, 12, 10}; 338 // CHECK: store <4 x i8> <i8 1, i8 5, i8 8, i8 10> 339 constexpr auto n = 3 * FourCharsExtVec{8, 4, 2, 1}; 340 // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3> 341 constexpr auto o = 100 / FourCharsExtVec{12, 15, 18, 21}; 342 // CHECK: store <4 x i8> <i8 8, i8 6, i8 5, i8 4> 343 constexpr auto p = 100 % FourCharsExtVec{12, 15, 18, 21}; 344 // CHECK: store <4 x i8> <i8 4, i8 10, i8 10, i8 16> 345 346 constexpr auto q = FourCharsExtVec{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2}; 347 // CHECK: store <4 x i8> <i8 12, i8 6, i8 8, i8 4> 348 constexpr auto r = FourCharsExtVec{19, 15, 12, 10} >> 349 FourCharsExtVec{1, 1, 2, 2}; 350 // CHECK: store <4 x i8> <i8 9, i8 7, i8 3, i8 2> 351 constexpr auto s = FourCharsExtVec{6, 3, 5, 10} << 1; 352 // CHECK: store <4 x i8> <i8 12, i8 6, i8 10, i8 20> 353 constexpr auto t = FourCharsExtVec{19, 15, 10, 20} >> 1; 354 // CHECK: store <4 x i8> <i8 9, i8 7, i8 5, i8 10> 355 constexpr auto u = 12 << FourCharsExtVec{1, 2, 3, 3}; 356 // CHECK: store <4 x i8> <i8 24, i8 48, i8 96, i8 96> 357 constexpr auto v = 12 >> FourCharsExtVec{1, 2, 2, 1}; 358 // CHECK: store <4 x i8> <i8 6, i8 3, i8 3, i8 6> 359 360 constexpr auto w = FourCharsExtVec{1, 2, 3, 4} < 361 FourCharsExtVec{4, 3, 2, 1}; 362 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0> 363 constexpr auto x = FourCharsExtVec{1, 2, 3, 4} > 364 FourCharsExtVec{4, 3, 2, 1}; 365 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1> 366 constexpr auto y = FourCharsExtVec{1, 2, 3, 4} <= 367 FourCharsExtVec{4, 3, 3, 1}; 368 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0> 369 constexpr auto z = FourCharsExtVec{1, 2, 3, 4} >= 370 FourCharsExtVec{4, 3, 3, 1}; 371 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1> 372 constexpr auto A = FourCharsExtVec{1, 2, 3, 4} == 373 FourCharsExtVec{4, 3, 3, 1}; 374 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0> 375 constexpr auto B = FourCharsExtVec{1, 2, 3, 4} != 376 FourCharsExtVec{4, 3, 3, 1}; 377 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1> 378 379 constexpr auto C = FourCharsExtVec{1, 2, 3, 4} < 3; 380 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0> 381 constexpr auto D = FourCharsExtVec{1, 2, 3, 4} > 3; 382 // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 -1> 383 constexpr auto E = FourCharsExtVec{1, 2, 3, 4} <= 3; 384 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0> 385 constexpr auto F = FourCharsExtVec{1, 2, 3, 4} >= 3; 386 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1> 387 constexpr auto G = FourCharsExtVec{1, 2, 3, 4} == 3; 388 // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0> 389 constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3; 390 // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1> 391 392 constexpr auto I = FourCharsExtVec{1, 2, 3, 4} & 393 FourCharsExtVec{4, 3, 2, 1}; 394 // CHECK: store <4 x i8> <i8 0, i8 2, i8 2, i8 0> 395 constexpr auto J = FourCharsExtVec{1, 2, 3, 4} ^ 396 FourCharsExtVec { 4, 3, 2, 1 }; 397 // CHECK: store <4 x i8> <i8 5, i8 1, i8 1, i8 5> 398 constexpr auto K = FourCharsExtVec{1, 2, 3, 4} | 399 FourCharsExtVec{4, 3, 2, 1}; 400 // CHECK: store <4 x i8> <i8 5, i8 3, i8 3, i8 5> 401 constexpr auto L = FourCharsExtVec{1, 2, 3, 4} & 3; 402 // CHECK: store <4 x i8> <i8 1, i8 2, i8 3, i8 0> 403 constexpr auto M = FourCharsExtVec{1, 2, 3, 4} ^ 3; 404 // CHECK: store <4 x i8> <i8 2, i8 1, i8 0, i8 7> 405 constexpr auto N = FourCharsExtVec{1, 2, 3, 4} | 3; 406 // CHECK: store <4 x i8> <i8 3, i8 3, i8 3, i8 7> 407 408 constexpr auto O = FourCharsExtVec{5, 0, 6, 0} && 409 FourCharsExtVec{5, 5, 0, 0}; 410 // CHECK: store <4 x i8> <i8 1, i8 0, i8 0, i8 0> 411 constexpr auto P = FourCharsExtVec{5, 0, 6, 0} || 412 FourCharsExtVec{5, 5, 0, 0}; 413 // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0> 414 415 constexpr auto Q = FourCharsExtVec{5, 0, 6, 0} && 3; 416 // CHECK: store <4 x i8> <i8 1, i8 0, i8 1, i8 0> 417 constexpr auto R = FourCharsExtVec{5, 0, 6, 0} || 3; 418 // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 1> 419 420 constexpr auto T = CmpMul(a, b); 421 // CHECK: store <4 x i8> <i8 108, i8 18, i8 56, i8 72> 422 423 constexpr auto U = CmpDiv(a, b); 424 // CHECK: store <4 x i8> <i8 3, i8 18, i8 0, i8 0> 425 426 constexpr auto V = CmpRem(a, b); 427 // CHECK: store <4 x i8> <i8 0, i8 0, i8 7, i8 8> 428 429 constexpr auto X = CmpAdd(a, b); 430 // CHECK: store <4 x i8> <i8 24, i8 19, i8 15, i8 17> 431 432 constexpr auto Y = CmpSub(a, b); 433 // CHECK: store <4 x i8> <i8 12, i8 17, i8 -1, i8 -1> 434 435 constexpr auto InvH = -H; 436 // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1> 437 438 constexpr auto Z = CmpLSH(a, InvH); 439 // CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16> 440 441 constexpr auto aa = CmpRSH(a, InvH); 442 // CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4> 443 444 constexpr auto ab = CmpBinAnd(a, b); 445 // CHECK: store <4 x i8> <i8 2, i8 0, i8 0, i8 8> 446 447 constexpr auto ac = CmpBinXOr(a, b); 448 // CHECK: store <4 x i8> <i8 20, i8 19, i8 15, i8 1> 449 450 constexpr auto ad = CmpBinOr(a, b); 451 // CHECK: store <4 x i8> <i8 22, i8 19, i8 15, i8 9> 452 453 constexpr auto ae = ~FourCharsExtVec{1, 2, 10, 20}; 454 // CHECK: store <4 x i8> <i8 -2, i8 -3, i8 -11, i8 -21> 455 456 constexpr auto af = !FourCharsExtVec{0, 1, 8, -1}; 457 // CHECK: store <4 x i8> <i8 -1, i8 0, i8 0, i8 0> 458 } 459 460 void FloatUsage() { 461 constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} + 462 FourFloatsVecSize{12, 15, 5, 7}; 463 // CHECK: <4 x float> <float 1.800000e+01, float 1.800000e+01, float 7.000000e+00, float 8.000000e+00> 464 constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} - 465 FourFloatsVecSize{13, 14, 5, 3}; 466 // CHECK: store <4 x float> <float 6.000000e+00, float 1.000000e+00, float 8.000000e+00, float 9.000000e+00> 467 constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} * 468 FourFloatsVecSize{3, 4, 5, 6}; 469 // CHECK: store <4 x float> <float 2.400000e+01, float 1.600000e+01, float 1.000000e+01, float 6.000000e+00> 470 constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} / 471 FourFloatsVecSize{6, 4, 5, 2}; 472 // CHECK: store <4 x float> <float 2.000000e+00, float 3.000000e+00, float 2.000000e+00, float 5.000000e+00> 473 474 constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3; 475 // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00> 476 constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3; 477 // CHECK: store <4 x float> <float 1.600000e+01, float 1.200000e+01, float 9.000000e+00, float 7.000000e+00> 478 constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3; 479 // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00> 480 constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3; 481 // CHECK: store <4 x float> <float 4.000000e+00, float 5.000000e+00, float 6.000000e+00, float 7.000000e+00> 482 483 constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1}; 484 // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00> 485 constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10}; 486 // CHECK: store <4 x float> <float 1.000000e+00, float 5.000000e+00, float 8.000000e+00, float 1.000000e+01> 487 constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1}; 488 // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00> 489 constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21}; 490 // CHECK: store <4 x float> <float 0x4020AAAAA0000000, float 0x401AAAAAA0000000, float 0x401638E380000000, float 0x40130C30C0000000> 491 492 constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < 493 FourFloatsVecSize{4, 3, 2, 1}; 494 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0> 495 constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > 496 FourFloatsVecSize{4, 3, 2, 1}; 497 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1> 498 constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= 499 FourFloatsVecSize{4, 3, 3, 1}; 500 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0> 501 constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= 502 FourFloatsVecSize{4, 3, 3, 1}; 503 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1> 504 constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == 505 FourFloatsVecSize{4, 3, 3, 1}; 506 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0> 507 constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != 508 FourFloatsVecSize{4, 3, 3, 1}; 509 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1> 510 511 constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; 512 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0> 513 constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; 514 // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 -1> 515 constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; 516 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0> 517 constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; 518 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1> 519 constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; 520 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0> 521 constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; 522 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1> 523 524 constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} && 525 FourFloatsVecSize{5, 5, 0, 0}; 526 // CHECK: store <4 x i32> <i32 1, i32 0, i32 0, i32 0> 527 constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} || 528 FourFloatsVecSize{5, 5, 0, 0}; 529 // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0> 530 531 constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3; 532 // CHECK: store <4 x i32> <i32 1, i32 0, i32 1, i32 0> 533 constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3; 534 // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 1> 535 536 constexpr auto T = CmpMul(a, b); 537 // CHECK: store <4 x float> <float 1.080000e+02, float 1.800000e+01, float 5.600000e+01, float 7.200000e+01> 538 539 constexpr auto U = CmpDiv(a, b); 540 // CHECK: store <4 x float> <float 3.000000e+00, float 1.800000e+01, float 8.750000e-01, float 0x3FEC71C720000000> 541 542 constexpr auto X = CmpAdd(a, b); 543 // CHECK: store <4 x float> <float 2.400000e+01, float 1.900000e+01, float 1.500000e+01, float 1.700000e+01> 544 545 constexpr auto Y = CmpSub(a, b); 546 // CHECK: store <4 x float> <float 1.200000e+01, float 1.700000e+01, float -1.000000e+00, float -1.000000e+00> 547 548 constexpr auto Z = -Y; 549 // CHECK: store <4 x float> <float -1.200000e+01, float -1.700000e+01, float 1.000000e+00, float 1.000000e+00> 550 551 // Operator ~ is illegal on floats, so no test for that. 552 constexpr auto af = !FourFloatsVecSize{0, 1, 8, -1}; 553 // CHECK: store <4 x i32> <i32 -1, i32 0, i32 0, i32 0> 554 } 555 556 void FloatVecUsage() { 557 constexpr auto a = FourFloatsVecSize{6, 3, 2, 1} + 558 FourFloatsVecSize{12, 15, 5, 7}; 559 // CHECK: <4 x float> <float 1.800000e+01, float 1.800000e+01, float 7.000000e+00, float 8.000000e+00> 560 constexpr auto b = FourFloatsVecSize{19, 15, 13, 12} - 561 FourFloatsVecSize{13, 14, 5, 3}; 562 // CHECK: store <4 x float> <float 6.000000e+00, float 1.000000e+00, float 8.000000e+00, float 9.000000e+00> 563 constexpr auto c = FourFloatsVecSize{8, 4, 2, 1} * 564 FourFloatsVecSize{3, 4, 5, 6}; 565 // CHECK: store <4 x float> <float 2.400000e+01, float 1.600000e+01, float 1.000000e+01, float 6.000000e+00> 566 constexpr auto d = FourFloatsVecSize{12, 12, 10, 10} / 567 FourFloatsVecSize{6, 4, 5, 2}; 568 // CHECK: store <4 x float> <float 2.000000e+00, float 3.000000e+00, float 2.000000e+00, float 5.000000e+00> 569 570 constexpr auto f = FourFloatsVecSize{6, 3, 2, 1} + 3; 571 // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00> 572 constexpr auto g = FourFloatsVecSize{19, 15, 12, 10} - 3; 573 // CHECK: store <4 x float> <float 1.600000e+01, float 1.200000e+01, float 9.000000e+00, float 7.000000e+00> 574 constexpr auto h = FourFloatsVecSize{8, 4, 2, 1} * 3; 575 // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00> 576 constexpr auto j = FourFloatsVecSize{12, 15, 18, 21} / 3; 577 // CHECK: store <4 x float> <float 4.000000e+00, float 5.000000e+00, float 6.000000e+00, float 7.000000e+00> 578 579 constexpr auto l = 3 + FourFloatsVecSize{6, 3, 2, 1}; 580 // CHECK: store <4 x float> <float 9.000000e+00, float 6.000000e+00, float 5.000000e+00, float 4.000000e+00> 581 constexpr auto m = 20 - FourFloatsVecSize{19, 15, 12, 10}; 582 // CHECK: store <4 x float> <float 1.000000e+00, float 5.000000e+00, float 8.000000e+00, float 1.000000e+01> 583 constexpr auto n = 3 * FourFloatsVecSize{8, 4, 2, 1}; 584 // CHECK: store <4 x float> <float 2.400000e+01, float 1.200000e+01, float 6.000000e+00, float 3.000000e+00> 585 constexpr auto o = 100 / FourFloatsVecSize{12, 15, 18, 21}; 586 // CHECK: store <4 x float> <float 0x4020AAAAA0000000, float 0x401AAAAAA0000000, float 0x401638E380000000, float 0x40130C30C0000000> 587 588 constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} < 589 FourFloatsVecSize{4, 3, 2, 1}; 590 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0> 591 constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} > 592 FourFloatsVecSize{4, 3, 2, 1}; 593 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1> 594 constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <= 595 FourFloatsVecSize{4, 3, 3, 1}; 596 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0> 597 constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >= 598 FourFloatsVecSize{4, 3, 3, 1}; 599 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1> 600 constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} == 601 FourFloatsVecSize{4, 3, 3, 1}; 602 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0> 603 constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} != 604 FourFloatsVecSize{4, 3, 3, 1}; 605 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1> 606 607 constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3; 608 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0> 609 constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3; 610 // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 -1> 611 constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3; 612 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0> 613 constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3; 614 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1> 615 constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3; 616 // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0> 617 constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3; 618 // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1> 619 620 constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} && 621 FourFloatsVecSize{5, 5, 0, 0}; 622 // CHECK: store <4 x i32> <i32 1, i32 0, i32 0, i32 0> 623 constexpr auto P = FourFloatsVecSize{5, 0, 6, 0} || 624 FourFloatsVecSize{5, 5, 0, 0}; 625 // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0> 626 627 constexpr auto Q = FourFloatsVecSize{5, 0, 6, 0} && 3; 628 // CHECK: store <4 x i32> <i32 1, i32 0, i32 1, i32 0> 629 constexpr auto R = FourFloatsVecSize{5, 0, 6, 0} || 3; 630 // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 1> 631 632 constexpr auto T = CmpMul(a, b); 633 // CHECK: store <4 x float> <float 1.080000e+02, float 1.800000e+01, float 5.600000e+01, float 7.200000e+01> 634 635 constexpr auto U = CmpDiv(a, b); 636 // CHECK: store <4 x float> <float 3.000000e+00, float 1.800000e+01, float 8.750000e-01, float 0x3FEC71C720000000> 637 638 constexpr auto X = CmpAdd(a, b); 639 // CHECK: store <4 x float> <float 2.400000e+01, float 1.900000e+01, float 1.500000e+01, float 1.700000e+01> 640 641 constexpr auto Y = CmpSub(a, b); 642 // CHECK: store <4 x float> <float 1.200000e+01, float 1.700000e+01, float -1.000000e+00, float -1.000000e+00> 643 644 constexpr auto Z = -Y; 645 // CHECK: store <4 x float> <float -1.200000e+01, float -1.700000e+01, float 1.000000e+00, float 1.000000e+00> 646 647 // Operator ~ is illegal on floats, so no test for that. 648 constexpr auto af = !FourFloatsVecSize{0, 1, 8, -1}; 649 // CHECK: store <4 x i32> <i32 -1, i32 0, i32 0, i32 0> 650 } 651 652 void I128Usage() { 653 constexpr auto a = FourI128VecSize{1, 2, 3, 4}; 654 // CHECK: store <4 x i128> <i128 1, i128 2, i128 3, i128 4> 655 constexpr auto b = a < 3; 656 // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 0, i128 0> 657 658 // Operator ~ is illegal on floats, so no test for that. 659 constexpr auto c = ~FourI128VecSize{1, 2, 10, 20}; 660 // CHECK: store <4 x i128> <i128 -2, i128 -3, i128 -11, i128 -21> 661 662 constexpr auto d = !FourI128VecSize{0, 1, 8, -1}; 663 // CHECK: store <4 x i128> <i128 -1, i128 0, i128 0, i128 0> 664 } 665 666 void I128VecUsage() { 667 constexpr auto a = FourI128ExtVec{1, 2, 3, 4}; 668 // CHECK: store <4 x i128> <i128 1, i128 2, i128 3, i128 4> 669 constexpr auto b = a < 3; 670 // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 0, i128 0> 671 672 // Operator ~ is illegal on floats, so no test for that. 673 constexpr auto c = ~FourI128ExtVec{1, 2, 10, 20}; 674 // CHECK: store <4 x i128> <i128 -2, i128 -3, i128 -11, i128 -21> 675 676 constexpr auto d = !FourI128ExtVec{0, 1, 8, -1}; 677 // CHECK: store <4 x i128> <i128 -1, i128 0, i128 0, i128 0> 678 } 679 680