1 ; Test vector extraction to memory. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s 4 5 ; Test v16i8 extraction from the first element. 6 define void @f1(<16 x i8> %val, i8 *%ptr) { 7 ; CHECK-LABEL: f1: 8 ; CHECK: vsteb %v24, 0(%r2), 0 9 ; CHECK: br %r14 10 %element = extractelement <16 x i8> %val, i32 0 11 store i8 %element, i8 *%ptr 12 ret void 13 } 14 15 ; Test v16i8 extraction from the last element. 16 define void @f2(<16 x i8> %val, i8 *%ptr) { 17 ; CHECK-LABEL: f2: 18 ; CHECK: vsteb %v24, 0(%r2), 15 19 ; CHECK: br %r14 20 %element = extractelement <16 x i8> %val, i32 15 21 store i8 %element, i8 *%ptr 22 ret void 23 } 24 25 ; Test v16i8 extraction of an invalid element. This must compile, 26 ; but we don't care what it does. 27 define void @f3(<16 x i8> %val, i8 *%ptr) { 28 ; CHECK-LABEL: f3: 29 ; CHECK-NOT: vsteb %v24, 0(%r2), 16 30 ; CHECK: br %r14 31 %element = extractelement <16 x i8> %val, i32 16 32 store i8 %element, i8 *%ptr 33 ret void 34 } 35 36 ; Test v16i8 extraction with the highest in-range offset. 37 define void @f4(<16 x i8> %val, i8 *%base) { 38 ; CHECK-LABEL: f4: 39 ; CHECK: vsteb %v24, 4095(%r2), 10 40 ; CHECK: br %r14 41 %ptr = getelementptr i8, i8 *%base, i32 4095 42 %element = extractelement <16 x i8> %val, i32 10 43 store i8 %element, i8 *%ptr 44 ret void 45 } 46 47 ; Test v16i8 extraction with the first ouf-of-range offset. 48 define void @f5(<16 x i8> %val, i8 *%base) { 49 ; CHECK-LABEL: f5: 50 ; CHECK: aghi %r2, 4096 51 ; CHECK: vsteb %v24, 0(%r2), 5 52 ; CHECK: br %r14 53 %ptr = getelementptr i8, i8 *%base, i32 4096 54 %element = extractelement <16 x i8> %val, i32 5 55 store i8 %element, i8 *%ptr 56 ret void 57 } 58 59 ; Test v16i8 extraction from a variable element. 60 define void @f6(<16 x i8> %val, i8 *%ptr, i32 %index) { 61 ; CHECK-LABEL: f6: 62 ; CHECK-NOT: vsteb 63 ; CHECK: br %r14 64 %element = extractelement <16 x i8> %val, i32 %index 65 store i8 %element, i8 *%ptr 66 ret void 67 } 68 69 ; Test v8i16 extraction from the first element. 70 define void @f7(<8 x i16> %val, i16 *%ptr) { 71 ; CHECK-LABEL: f7: 72 ; CHECK: vsteh %v24, 0(%r2), 0 73 ; CHECK: br %r14 74 %element = extractelement <8 x i16> %val, i32 0 75 store i16 %element, i16 *%ptr 76 ret void 77 } 78 79 ; Test v8i16 extraction from the last element. 80 define void @f8(<8 x i16> %val, i16 *%ptr) { 81 ; CHECK-LABEL: f8: 82 ; CHECK: vsteh %v24, 0(%r2), 7 83 ; CHECK: br %r14 84 %element = extractelement <8 x i16> %val, i32 7 85 store i16 %element, i16 *%ptr 86 ret void 87 } 88 89 ; Test v8i16 extraction of an invalid element. This must compile, 90 ; but we don't care what it does. 91 define void @f9(<8 x i16> %val, i16 *%ptr) { 92 ; CHECK-LABEL: f9: 93 ; CHECK-NOT: vsteh %v24, 0(%r2), 8 94 ; CHECK: br %r14 95 %element = extractelement <8 x i16> %val, i32 8 96 store i16 %element, i16 *%ptr 97 ret void 98 } 99 100 ; Test v8i16 extraction with the highest in-range offset. 101 define void @f10(<8 x i16> %val, i16 *%base) { 102 ; CHECK-LABEL: f10: 103 ; CHECK: vsteh %v24, 4094(%r2), 5 104 ; CHECK: br %r14 105 %ptr = getelementptr i16, i16 *%base, i32 2047 106 %element = extractelement <8 x i16> %val, i32 5 107 store i16 %element, i16 *%ptr 108 ret void 109 } 110 111 ; Test v8i16 extraction with the first ouf-of-range offset. 112 define void @f11(<8 x i16> %val, i16 *%base) { 113 ; CHECK-LABEL: f11: 114 ; CHECK: aghi %r2, 4096 115 ; CHECK: vsteh %v24, 0(%r2), 1 116 ; CHECK: br %r14 117 %ptr = getelementptr i16, i16 *%base, i32 2048 118 %element = extractelement <8 x i16> %val, i32 1 119 store i16 %element, i16 *%ptr 120 ret void 121 } 122 123 ; Test v8i16 extraction from a variable element. 124 define void @f12(<8 x i16> %val, i16 *%ptr, i32 %index) { 125 ; CHECK-LABEL: f12: 126 ; CHECK-NOT: vsteh 127 ; CHECK: br %r14 128 %element = extractelement <8 x i16> %val, i32 %index 129 store i16 %element, i16 *%ptr 130 ret void 131 } 132 133 ; Test v4i32 extraction from the first element. 134 define void @f13(<4 x i32> %val, i32 *%ptr) { 135 ; CHECK-LABEL: f13: 136 ; CHECK: vstef %v24, 0(%r2), 0 137 ; CHECK: br %r14 138 %element = extractelement <4 x i32> %val, i32 0 139 store i32 %element, i32 *%ptr 140 ret void 141 } 142 143 ; Test v4i32 extraction from the last element. 144 define void @f14(<4 x i32> %val, i32 *%ptr) { 145 ; CHECK-LABEL: f14: 146 ; CHECK: vstef %v24, 0(%r2), 3 147 ; CHECK: br %r14 148 %element = extractelement <4 x i32> %val, i32 3 149 store i32 %element, i32 *%ptr 150 ret void 151 } 152 153 ; Test v4i32 extraction of an invalid element. This must compile, 154 ; but we don't care what it does. 155 define void @f15(<4 x i32> %val, i32 *%ptr) { 156 ; CHECK-LABEL: f15: 157 ; CHECK-NOT: vstef %v24, 0(%r2), 4 158 ; CHECK: br %r14 159 %element = extractelement <4 x i32> %val, i32 4 160 store i32 %element, i32 *%ptr 161 ret void 162 } 163 164 ; Test v4i32 extraction with the highest in-range offset. 165 define void @f16(<4 x i32> %val, i32 *%base) { 166 ; CHECK-LABEL: f16: 167 ; CHECK: vstef %v24, 4092(%r2), 2 168 ; CHECK: br %r14 169 %ptr = getelementptr i32, i32 *%base, i32 1023 170 %element = extractelement <4 x i32> %val, i32 2 171 store i32 %element, i32 *%ptr 172 ret void 173 } 174 175 ; Test v4i32 extraction with the first ouf-of-range offset. 176 define void @f17(<4 x i32> %val, i32 *%base) { 177 ; CHECK-LABEL: f17: 178 ; CHECK: aghi %r2, 4096 179 ; CHECK: vstef %v24, 0(%r2), 1 180 ; CHECK: br %r14 181 %ptr = getelementptr i32, i32 *%base, i32 1024 182 %element = extractelement <4 x i32> %val, i32 1 183 store i32 %element, i32 *%ptr 184 ret void 185 } 186 187 ; Test v4i32 extraction from a variable element. 188 define void @f18(<4 x i32> %val, i32 *%ptr, i32 %index) { 189 ; CHECK-LABEL: f18: 190 ; CHECK-NOT: vstef 191 ; CHECK: br %r14 192 %element = extractelement <4 x i32> %val, i32 %index 193 store i32 %element, i32 *%ptr 194 ret void 195 } 196 197 ; Test v2i64 extraction from the first element. 198 define void @f19(<2 x i64> %val, i64 *%ptr) { 199 ; CHECK-LABEL: f19: 200 ; CHECK: vsteg %v24, 0(%r2), 0 201 ; CHECK: br %r14 202 %element = extractelement <2 x i64> %val, i32 0 203 store i64 %element, i64 *%ptr 204 ret void 205 } 206 207 ; Test v2i64 extraction from the last element. 208 define void @f20(<2 x i64> %val, i64 *%ptr) { 209 ; CHECK-LABEL: f20: 210 ; CHECK: vsteg %v24, 0(%r2), 1 211 ; CHECK: br %r14 212 %element = extractelement <2 x i64> %val, i32 1 213 store i64 %element, i64 *%ptr 214 ret void 215 } 216 217 ; Test v2i64 extraction of an invalid element. This must compile, 218 ; but we don't care what it does. 219 define void @f21(<2 x i64> %val, i64 *%ptr) { 220 ; CHECK-LABEL: f21: 221 ; CHECK-NOT: vsteg %v24, 0(%r2), 2 222 ; CHECK: br %r14 223 %element = extractelement <2 x i64> %val, i32 2 224 store i64 %element, i64 *%ptr 225 ret void 226 } 227 228 ; Test v2i64 extraction with the highest in-range offset. 229 define void @f22(<2 x i64> %val, i64 *%base) { 230 ; CHECK-LABEL: f22: 231 ; CHECK: vsteg %v24, 4088(%r2), 1 232 ; CHECK: br %r14 233 %ptr = getelementptr i64, i64 *%base, i32 511 234 %element = extractelement <2 x i64> %val, i32 1 235 store i64 %element, i64 *%ptr 236 ret void 237 } 238 239 ; Test v2i64 extraction with the first ouf-of-range offset. 240 define void @f23(<2 x i64> %val, i64 *%base) { 241 ; CHECK-LABEL: f23: 242 ; CHECK: aghi %r2, 4096 243 ; CHECK: vsteg %v24, 0(%r2), 0 244 ; CHECK: br %r14 245 %ptr = getelementptr i64, i64 *%base, i32 512 246 %element = extractelement <2 x i64> %val, i32 0 247 store i64 %element, i64 *%ptr 248 ret void 249 } 250 251 ; Test v2i64 extraction from a variable element. 252 define void @f24(<2 x i64> %val, i64 *%ptr, i32 %index) { 253 ; CHECK-LABEL: f24: 254 ; CHECK-NOT: vsteg 255 ; CHECK: br %r14 256 %element = extractelement <2 x i64> %val, i32 %index 257 store i64 %element, i64 *%ptr 258 ret void 259 } 260 261 ; Test v4f32 extraction from the first element. 262 define void @f25(<4 x float> %val, float *%ptr) { 263 ; CHECK-LABEL: f25: 264 ; CHECK: vstef %v24, 0(%r2), 0 265 ; CHECK: br %r14 266 %element = extractelement <4 x float> %val, i32 0 267 store float %element, float *%ptr 268 ret void 269 } 270 271 ; Test v4f32 extraction from the last element. 272 define void @f26(<4 x float> %val, float *%ptr) { 273 ; CHECK-LABEL: f26: 274 ; CHECK: vstef %v24, 0(%r2), 3 275 ; CHECK: br %r14 276 %element = extractelement <4 x float> %val, i32 3 277 store float %element, float *%ptr 278 ret void 279 } 280 281 ; Test v4f32 extraction of an invalid element. This must compile, 282 ; but we don't care what it does. 283 define void @f27(<4 x float> %val, float *%ptr) { 284 ; CHECK-LABEL: f27: 285 ; CHECK-NOT: vstef %v24, 0(%r2), 4 286 ; CHECK: br %r14 287 %element = extractelement <4 x float> %val, i32 4 288 store float %element, float *%ptr 289 ret void 290 } 291 292 ; Test v4f32 extraction with the highest in-range offset. 293 define void @f28(<4 x float> %val, float *%base) { 294 ; CHECK-LABEL: f28: 295 ; CHECK: vstef %v24, 4092(%r2), 2 296 ; CHECK: br %r14 297 %ptr = getelementptr float, float *%base, i32 1023 298 %element = extractelement <4 x float> %val, i32 2 299 store float %element, float *%ptr 300 ret void 301 } 302 303 ; Test v4f32 extraction with the first ouf-of-range offset. 304 define void @f29(<4 x float> %val, float *%base) { 305 ; CHECK-LABEL: f29: 306 ; CHECK: aghi %r2, 4096 307 ; CHECK: vstef %v24, 0(%r2), 1 308 ; CHECK: br %r14 309 %ptr = getelementptr float, float *%base, i32 1024 310 %element = extractelement <4 x float> %val, i32 1 311 store float %element, float *%ptr 312 ret void 313 } 314 315 ; Test v4f32 extraction from a variable element. 316 define void @f30(<4 x float> %val, float *%ptr, i32 %index) { 317 ; CHECK-LABEL: f30: 318 ; CHECK-NOT: vstef 319 ; CHECK: br %r14 320 %element = extractelement <4 x float> %val, i32 %index 321 store float %element, float *%ptr 322 ret void 323 } 324 325 ; Test v2f64 extraction from the first element. 326 define void @f32(<2 x double> %val, double *%ptr) { 327 ; CHECK-LABEL: f32: 328 ; CHECK: vsteg %v24, 0(%r2), 0 329 ; CHECK: br %r14 330 %element = extractelement <2 x double> %val, i32 0 331 store double %element, double *%ptr 332 ret void 333 } 334 335 ; Test v2f64 extraction from the last element. 336 define void @f33(<2 x double> %val, double *%ptr) { 337 ; CHECK-LABEL: f33: 338 ; CHECK: vsteg %v24, 0(%r2), 1 339 ; CHECK: br %r14 340 %element = extractelement <2 x double> %val, i32 1 341 store double %element, double *%ptr 342 ret void 343 } 344 345 ; Test v2f64 extraction with the highest in-range offset. 346 define void @f34(<2 x double> %val, double *%base) { 347 ; CHECK-LABEL: f34: 348 ; CHECK: vsteg %v24, 4088(%r2), 1 349 ; CHECK: br %r14 350 %ptr = getelementptr double, double *%base, i32 511 351 %element = extractelement <2 x double> %val, i32 1 352 store double %element, double *%ptr 353 ret void 354 } 355 356 ; Test v2f64 extraction with the first ouf-of-range offset. 357 define void @f35(<2 x double> %val, double *%base) { 358 ; CHECK-LABEL: f35: 359 ; CHECK: aghi %r2, 4096 360 ; CHECK: vsteg %v24, 0(%r2), 0 361 ; CHECK: br %r14 362 %ptr = getelementptr double, double *%base, i32 512 363 %element = extractelement <2 x double> %val, i32 0 364 store double %element, double *%ptr 365 ret void 366 } 367 368 ; Test v2f64 extraction from a variable element. 369 define void @f36(<2 x double> %val, double *%ptr, i32 %index) { 370 ; CHECK-LABEL: f36: 371 ; CHECK-NOT: vsteg 372 ; CHECK: br %r14 373 %element = extractelement <2 x double> %val, i32 %index 374 store double %element, double *%ptr 375 ret void 376 } 377 378 ; Test a v4i32 scatter of the first element. 379 define void @f37(<4 x i32> %val, <4 x i32> %index, i64 %base) { 380 ; CHECK-LABEL: f37: 381 ; CHECK: vscef %v24, 0(%v26,%r2), 0 382 ; CHECK: br %r14 383 %elem = extractelement <4 x i32> %index, i32 0 384 %ext = zext i32 %elem to i64 385 %add = add i64 %base, %ext 386 %ptr = inttoptr i64 %add to i32 * 387 %element = extractelement <4 x i32> %val, i32 0 388 store i32 %element, i32 *%ptr 389 ret void 390 } 391 392 ; Test a v4i32 scatter of the last element. 393 define void @f38(<4 x i32> %val, <4 x i32> %index, i64 %base) { 394 ; CHECK-LABEL: f38: 395 ; CHECK: vscef %v24, 0(%v26,%r2), 3 396 ; CHECK: br %r14 397 %elem = extractelement <4 x i32> %index, i32 3 398 %ext = zext i32 %elem to i64 399 %add = add i64 %base, %ext 400 %ptr = inttoptr i64 %add to i32 * 401 %element = extractelement <4 x i32> %val, i32 3 402 store i32 %element, i32 *%ptr 403 ret void 404 } 405 406 ; Test a v4i32 scatter with the highest in-range offset. 407 define void @f39(<4 x i32> %val, <4 x i32> %index, i64 %base) { 408 ; CHECK-LABEL: f39: 409 ; CHECK: vscef %v24, 4095(%v26,%r2), 1 410 ; CHECK: br %r14 411 %elem = extractelement <4 x i32> %index, i32 1 412 %ext = zext i32 %elem to i64 413 %add1 = add i64 %base, %ext 414 %add2 = add i64 %add1, 4095 415 %ptr = inttoptr i64 %add2 to i32 * 416 %element = extractelement <4 x i32> %val, i32 1 417 store i32 %element, i32 *%ptr 418 ret void 419 } 420 421 ; Test a v2i64 scatter of the first element. 422 define void @f40(<2 x i64> %val, <2 x i64> %index, i64 %base) { 423 ; CHECK-LABEL: f40: 424 ; CHECK: vsceg %v24, 0(%v26,%r2), 0 425 ; CHECK: br %r14 426 %elem = extractelement <2 x i64> %index, i32 0 427 %add = add i64 %base, %elem 428 %ptr = inttoptr i64 %add to i64 * 429 %element = extractelement <2 x i64> %val, i32 0 430 store i64 %element, i64 *%ptr 431 ret void 432 } 433 434 ; Test a v2i64 scatter of the last element. 435 define void @f41(<2 x i64> %val, <2 x i64> %index, i64 %base) { 436 ; CHECK-LABEL: f41: 437 ; CHECK: vsceg %v24, 0(%v26,%r2), 1 438 ; CHECK: br %r14 439 %elem = extractelement <2 x i64> %index, i32 1 440 %add = add i64 %base, %elem 441 %ptr = inttoptr i64 %add to i64 * 442 %element = extractelement <2 x i64> %val, i32 1 443 store i64 %element, i64 *%ptr 444 ret void 445 } 446 447 ; Test a v4f32 scatter of the first element. 448 define void @f42(<4 x float> %val, <4 x i32> %index, i64 %base) { 449 ; CHECK-LABEL: f42: 450 ; CHECK: vscef %v24, 0(%v26,%r2), 0 451 ; CHECK: br %r14 452 %elem = extractelement <4 x i32> %index, i32 0 453 %ext = zext i32 %elem to i64 454 %add = add i64 %base, %ext 455 %ptr = inttoptr i64 %add to float * 456 %element = extractelement <4 x float> %val, i32 0 457 store float %element, float *%ptr 458 ret void 459 } 460 461 ; Test a v4f32 scatter of the last element. 462 define void @f43(<4 x float> %val, <4 x i32> %index, i64 %base) { 463 ; CHECK-LABEL: f43: 464 ; CHECK: vscef %v24, 0(%v26,%r2), 3 465 ; CHECK: br %r14 466 %elem = extractelement <4 x i32> %index, i32 3 467 %ext = zext i32 %elem to i64 468 %add = add i64 %base, %ext 469 %ptr = inttoptr i64 %add to float * 470 %element = extractelement <4 x float> %val, i32 3 471 store float %element, float *%ptr 472 ret void 473 } 474 475 ; Test a v2f64 scatter of the first element. 476 define void @f44(<2 x double> %val, <2 x i64> %index, i64 %base) { 477 ; CHECK-LABEL: f44: 478 ; CHECK: vsceg %v24, 0(%v26,%r2), 0 479 ; CHECK: br %r14 480 %elem = extractelement <2 x i64> %index, i32 0 481 %add = add i64 %base, %elem 482 %ptr = inttoptr i64 %add to double * 483 %element = extractelement <2 x double> %val, i32 0 484 store double %element, double *%ptr 485 ret void 486 } 487 488 ; Test a v2f64 scatter of the last element. 489 define void @f45(<2 x double> %val, <2 x i64> %index, i64 %base) { 490 ; CHECK-LABEL: f45: 491 ; CHECK: vsceg %v24, 0(%v26,%r2), 1 492 ; CHECK: br %r14 493 %elem = extractelement <2 x i64> %index, i32 1 494 %add = add i64 %base, %elem 495 %ptr = inttoptr i64 %add to double * 496 %element = extractelement <2 x double> %val, i32 1 497 store double %element, double *%ptr 498 ret void 499 } 500