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