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. 6define 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. 16define 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. 27define 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. 37define 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. 48define 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. 60define 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. 70define 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. 80define 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. 91define 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. 101define 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. 112define 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. 124define 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. 134define 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. 144define 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. 155define 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. 165define 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. 176define 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. 188define 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. 198define 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. 208define 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. 219define 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. 229define 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. 240define 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. 252define 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. 262define 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. 272define 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. 283define 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. 293define 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. 304define 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. 316define 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. 326define 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. 336define 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. 346define 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. 357define 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. 369define 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. 379define 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. 393define 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. 407define 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. 422define 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. 435define 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. 448define 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. 462define 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. 476define 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. 489define 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