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 v2f64 extraction from the first element. 262define void @f32(<2 x double> %val, double *%ptr) { 263; CHECK-LABEL: f32: 264; CHECK: vsteg %v24, 0(%r2), 0 265; CHECK: br %r14 266 %element = extractelement <2 x double> %val, i32 0 267 store double %element, double *%ptr 268 ret void 269} 270 271; Test v2f64 extraction from the last element. 272define void @f33(<2 x double> %val, double *%ptr) { 273; CHECK-LABEL: f33: 274; CHECK: vsteg %v24, 0(%r2), 1 275; CHECK: br %r14 276 %element = extractelement <2 x double> %val, i32 1 277 store double %element, double *%ptr 278 ret void 279} 280 281; Test v2f64 extraction with the highest in-range offset. 282define void @f34(<2 x double> %val, double *%base) { 283; CHECK-LABEL: f34: 284; CHECK: vsteg %v24, 4088(%r2), 1 285; CHECK: br %r14 286 %ptr = getelementptr double, double *%base, i32 511 287 %element = extractelement <2 x double> %val, i32 1 288 store double %element, double *%ptr 289 ret void 290} 291 292; Test v2f64 extraction with the first ouf-of-range offset. 293define void @f35(<2 x double> %val, double *%base) { 294; CHECK-LABEL: f35: 295; CHECK: aghi %r2, 4096 296; CHECK: vsteg %v24, 0(%r2), 0 297; CHECK: br %r14 298 %ptr = getelementptr double, double *%base, i32 512 299 %element = extractelement <2 x double> %val, i32 0 300 store double %element, double *%ptr 301 ret void 302} 303 304; Test v2f64 extraction from a variable element. 305define void @f36(<2 x double> %val, double *%ptr, i32 %index) { 306; CHECK-LABEL: f36: 307; CHECK-NOT: vsteg 308; CHECK: br %r14 309 %element = extractelement <2 x double> %val, i32 %index 310 store double %element, double *%ptr 311 ret void 312} 313 314; Test a v4i32 scatter of the first element. 315define void @f37(<4 x i32> %val, <4 x i32> %index, i64 %base) { 316; CHECK-LABEL: f37: 317; CHECK: vscef %v24, 0(%v26,%r2), 0 318; CHECK: br %r14 319 %elem = extractelement <4 x i32> %index, i32 0 320 %ext = zext i32 %elem to i64 321 %add = add i64 %base, %ext 322 %ptr = inttoptr i64 %add to i32 * 323 %element = extractelement <4 x i32> %val, i32 0 324 store i32 %element, i32 *%ptr 325 ret void 326} 327 328; Test a v4i32 scatter of the last element. 329define void @f38(<4 x i32> %val, <4 x i32> %index, i64 %base) { 330; CHECK-LABEL: f38: 331; CHECK: vscef %v24, 0(%v26,%r2), 3 332; CHECK: br %r14 333 %elem = extractelement <4 x i32> %index, i32 3 334 %ext = zext i32 %elem to i64 335 %add = add i64 %base, %ext 336 %ptr = inttoptr i64 %add to i32 * 337 %element = extractelement <4 x i32> %val, i32 3 338 store i32 %element, i32 *%ptr 339 ret void 340} 341 342; Test a v4i32 scatter with the highest in-range offset. 343define void @f39(<4 x i32> %val, <4 x i32> %index, i64 %base) { 344; CHECK-LABEL: f39: 345; CHECK: vscef %v24, 4095(%v26,%r2), 1 346; CHECK: br %r14 347 %elem = extractelement <4 x i32> %index, i32 1 348 %ext = zext i32 %elem to i64 349 %add1 = add i64 %base, %ext 350 %add2 = add i64 %add1, 4095 351 %ptr = inttoptr i64 %add2 to i32 * 352 %element = extractelement <4 x i32> %val, i32 1 353 store i32 %element, i32 *%ptr 354 ret void 355} 356 357; Test a v2i64 scatter of the first element. 358define void @f40(<2 x i64> %val, <2 x i64> %index, i64 %base) { 359; CHECK-LABEL: f40: 360; CHECK: vsceg %v24, 0(%v26,%r2), 0 361; CHECK: br %r14 362 %elem = extractelement <2 x i64> %index, i32 0 363 %add = add i64 %base, %elem 364 %ptr = inttoptr i64 %add to i64 * 365 %element = extractelement <2 x i64> %val, i32 0 366 store i64 %element, i64 *%ptr 367 ret void 368} 369 370; Test a v2i64 scatter of the last element. 371define void @f41(<2 x i64> %val, <2 x i64> %index, i64 %base) { 372; CHECK-LABEL: f41: 373; CHECK: vsceg %v24, 0(%v26,%r2), 1 374; CHECK: br %r14 375 %elem = extractelement <2 x i64> %index, i32 1 376 %add = add i64 %base, %elem 377 %ptr = inttoptr i64 %add to i64 * 378 %element = extractelement <2 x i64> %val, i32 1 379 store i64 %element, i64 *%ptr 380 ret void 381} 382 383; Test a v2f64 scatter of the first element. 384define void @f44(<2 x double> %val, <2 x i64> %index, i64 %base) { 385; CHECK-LABEL: f44: 386; CHECK: vsceg %v24, 0(%v26,%r2), 0 387; CHECK: br %r14 388 %elem = extractelement <2 x i64> %index, i32 0 389 %add = add i64 %base, %elem 390 %ptr = inttoptr i64 %add to double * 391 %element = extractelement <2 x double> %val, i32 0 392 store double %element, double *%ptr 393 ret void 394} 395 396; Test a v2f64 scatter of the last element. 397define void @f45(<2 x double> %val, <2 x i64> %index, i64 %base) { 398; CHECK-LABEL: f45: 399; CHECK: vsceg %v24, 0(%v26,%r2), 1 400; CHECK: br %r14 401 %elem = extractelement <2 x i64> %index, i32 1 402 %add = add i64 %base, %elem 403 %ptr = inttoptr i64 %add to double * 404 %element = extractelement <2 x double> %val, i32 1 405 store double %element, double *%ptr 406 ret void 407} 408