1; Test vector insertion of memory values. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s 4 5; Test v16i8 insertion into the first element. 6define <16 x i8> @f1(<16 x i8> %val, i8 *%ptr) { 7; CHECK-LABEL: f1: 8; CHECK: vleb %v24, 0(%r2), 0 9; CHECK: br %r14 10 %element = load i8, i8 *%ptr 11 %ret = insertelement <16 x i8> %val, i8 %element, i32 0 12 ret <16 x i8> %ret 13} 14 15; Test v16i8 insertion into the last element. 16define <16 x i8> @f2(<16 x i8> %val, i8 *%ptr) { 17; CHECK-LABEL: f2: 18; CHECK: vleb %v24, 0(%r2), 15 19; CHECK: br %r14 20 %element = load i8, i8 *%ptr 21 %ret = insertelement <16 x i8> %val, i8 %element, i32 15 22 ret <16 x i8> %ret 23} 24 25; Test v16i8 insertion with the highest in-range offset. 26define <16 x i8> @f3(<16 x i8> %val, i8 *%base) { 27; CHECK-LABEL: f3: 28; CHECK: vleb %v24, 4095(%r2), 10 29; CHECK: br %r14 30 %ptr = getelementptr i8, i8 *%base, i32 4095 31 %element = load i8, i8 *%ptr 32 %ret = insertelement <16 x i8> %val, i8 %element, i32 10 33 ret <16 x i8> %ret 34} 35 36; Test v16i8 insertion with the first ouf-of-range offset. 37define <16 x i8> @f4(<16 x i8> %val, i8 *%base) { 38; CHECK-LABEL: f4: 39; CHECK: aghi %r2, 4096 40; CHECK: vleb %v24, 0(%r2), 5 41; CHECK: br %r14 42 %ptr = getelementptr i8, i8 *%base, i32 4096 43 %element = load i8, i8 *%ptr 44 %ret = insertelement <16 x i8> %val, i8 %element, i32 5 45 ret <16 x i8> %ret 46} 47 48; Test v16i8 insertion into a variable element. 49define <16 x i8> @f5(<16 x i8> %val, i8 *%ptr, i32 %index) { 50; CHECK-LABEL: f5: 51; CHECK-NOT: vleb 52; CHECK: br %r14 53 %element = load i8, i8 *%ptr 54 %ret = insertelement <16 x i8> %val, i8 %element, i32 %index 55 ret <16 x i8> %ret 56} 57 58; Test v8i16 insertion into the first element. 59define <8 x i16> @f6(<8 x i16> %val, i16 *%ptr) { 60; CHECK-LABEL: f6: 61; CHECK: vleh %v24, 0(%r2), 0 62; CHECK: br %r14 63 %element = load i16, i16 *%ptr 64 %ret = insertelement <8 x i16> %val, i16 %element, i32 0 65 ret <8 x i16> %ret 66} 67 68; Test v8i16 insertion into the last element. 69define <8 x i16> @f7(<8 x i16> %val, i16 *%ptr) { 70; CHECK-LABEL: f7: 71; CHECK: vleh %v24, 0(%r2), 7 72; CHECK: br %r14 73 %element = load i16, i16 *%ptr 74 %ret = insertelement <8 x i16> %val, i16 %element, i32 7 75 ret <8 x i16> %ret 76} 77 78; Test v8i16 insertion with the highest in-range offset. 79define <8 x i16> @f8(<8 x i16> %val, i16 *%base) { 80; CHECK-LABEL: f8: 81; CHECK: vleh %v24, 4094(%r2), 5 82; CHECK: br %r14 83 %ptr = getelementptr i16, i16 *%base, i32 2047 84 %element = load i16, i16 *%ptr 85 %ret = insertelement <8 x i16> %val, i16 %element, i32 5 86 ret <8 x i16> %ret 87} 88 89; Test v8i16 insertion with the first ouf-of-range offset. 90define <8 x i16> @f9(<8 x i16> %val, i16 *%base) { 91; CHECK-LABEL: f9: 92; CHECK: aghi %r2, 4096 93; CHECK: vleh %v24, 0(%r2), 1 94; CHECK: br %r14 95 %ptr = getelementptr i16, i16 *%base, i32 2048 96 %element = load i16, i16 *%ptr 97 %ret = insertelement <8 x i16> %val, i16 %element, i32 1 98 ret <8 x i16> %ret 99} 100 101; Test v8i16 insertion into a variable element. 102define <8 x i16> @f10(<8 x i16> %val, i16 *%ptr, i32 %index) { 103; CHECK-LABEL: f10: 104; CHECK-NOT: vleh 105; CHECK: br %r14 106 %element = load i16, i16 *%ptr 107 %ret = insertelement <8 x i16> %val, i16 %element, i32 %index 108 ret <8 x i16> %ret 109} 110 111; Test v4i32 insertion into the first element. 112define <4 x i32> @f11(<4 x i32> %val, i32 *%ptr) { 113; CHECK-LABEL: f11: 114; CHECK: vlef %v24, 0(%r2), 0 115; CHECK: br %r14 116 %element = load i32, i32 *%ptr 117 %ret = insertelement <4 x i32> %val, i32 %element, i32 0 118 ret <4 x i32> %ret 119} 120 121; Test v4i32 insertion into the last element. 122define <4 x i32> @f12(<4 x i32> %val, i32 *%ptr) { 123; CHECK-LABEL: f12: 124; CHECK: vlef %v24, 0(%r2), 3 125; CHECK: br %r14 126 %element = load i32, i32 *%ptr 127 %ret = insertelement <4 x i32> %val, i32 %element, i32 3 128 ret <4 x i32> %ret 129} 130 131; Test v4i32 insertion with the highest in-range offset. 132define <4 x i32> @f13(<4 x i32> %val, i32 *%base) { 133; CHECK-LABEL: f13: 134; CHECK: vlef %v24, 4092(%r2), 2 135; CHECK: br %r14 136 %ptr = getelementptr i32, i32 *%base, i32 1023 137 %element = load i32, i32 *%ptr 138 %ret = insertelement <4 x i32> %val, i32 %element, i32 2 139 ret <4 x i32> %ret 140} 141 142; Test v4i32 insertion with the first ouf-of-range offset. 143define <4 x i32> @f14(<4 x i32> %val, i32 *%base) { 144; CHECK-LABEL: f14: 145; CHECK: aghi %r2, 4096 146; CHECK: vlef %v24, 0(%r2), 1 147; CHECK: br %r14 148 %ptr = getelementptr i32, i32 *%base, i32 1024 149 %element = load i32, i32 *%ptr 150 %ret = insertelement <4 x i32> %val, i32 %element, i32 1 151 ret <4 x i32> %ret 152} 153 154; Test v4i32 insertion into a variable element. 155define <4 x i32> @f15(<4 x i32> %val, i32 *%ptr, i32 %index) { 156; CHECK-LABEL: f15: 157; CHECK-NOT: vlef 158; CHECK: br %r14 159 %element = load i32, i32 *%ptr 160 %ret = insertelement <4 x i32> %val, i32 %element, i32 %index 161 ret <4 x i32> %ret 162} 163 164; Test v2i64 insertion into the first element. 165define <2 x i64> @f16(<2 x i64> %val, i64 *%ptr) { 166; CHECK-LABEL: f16: 167; CHECK: vleg %v24, 0(%r2), 0 168; CHECK: br %r14 169 %element = load i64, i64 *%ptr 170 %ret = insertelement <2 x i64> %val, i64 %element, i32 0 171 ret <2 x i64> %ret 172} 173 174; Test v2i64 insertion into the last element. 175define <2 x i64> @f17(<2 x i64> %val, i64 *%ptr) { 176; CHECK-LABEL: f17: 177; CHECK: vleg %v24, 0(%r2), 1 178; CHECK: br %r14 179 %element = load i64, i64 *%ptr 180 %ret = insertelement <2 x i64> %val, i64 %element, i32 1 181 ret <2 x i64> %ret 182} 183 184; Test v2i64 insertion with the highest in-range offset. 185define <2 x i64> @f18(<2 x i64> %val, i64 *%base) { 186; CHECK-LABEL: f18: 187; CHECK: vleg %v24, 4088(%r2), 1 188; CHECK: br %r14 189 %ptr = getelementptr i64, i64 *%base, i32 511 190 %element = load i64, i64 *%ptr 191 %ret = insertelement <2 x i64> %val, i64 %element, i32 1 192 ret <2 x i64> %ret 193} 194 195; Test v2i64 insertion with the first ouf-of-range offset. 196define <2 x i64> @f19(<2 x i64> %val, i64 *%base) { 197; CHECK-LABEL: f19: 198; CHECK: aghi %r2, 4096 199; CHECK: vleg %v24, 0(%r2), 0 200; CHECK: br %r14 201 %ptr = getelementptr i64, i64 *%base, i32 512 202 %element = load i64, i64 *%ptr 203 %ret = insertelement <2 x i64> %val, i64 %element, i32 0 204 ret <2 x i64> %ret 205} 206 207; Test v2i64 insertion into a variable element. 208define <2 x i64> @f20(<2 x i64> %val, i64 *%ptr, i32 %index) { 209; CHECK-LABEL: f20: 210; CHECK-NOT: vleg 211; CHECK: br %r14 212 %element = load i64, i64 *%ptr 213 %ret = insertelement <2 x i64> %val, i64 %element, i32 %index 214 ret <2 x i64> %ret 215} 216 217; Test v2f64 insertion into the first element. 218define <2 x double> @f26(<2 x double> %val, double *%ptr) { 219; CHECK-LABEL: f26: 220; CHECK: vleg %v24, 0(%r2), 0 221; CHECK: br %r14 222 %element = load double, double *%ptr 223 %ret = insertelement <2 x double> %val, double %element, i32 0 224 ret <2 x double> %ret 225} 226 227; Test v2f64 insertion into the last element. 228define <2 x double> @f27(<2 x double> %val, double *%ptr) { 229; CHECK-LABEL: f27: 230; CHECK: vleg %v24, 0(%r2), 1 231; CHECK: br %r14 232 %element = load double, double *%ptr 233 %ret = insertelement <2 x double> %val, double %element, i32 1 234 ret <2 x double> %ret 235} 236 237; Test v2f64 insertion with the highest in-range offset. 238define <2 x double> @f28(<2 x double> %val, double *%base) { 239; CHECK-LABEL: f28: 240; CHECK: vleg %v24, 4088(%r2), 1 241; CHECK: br %r14 242 %ptr = getelementptr double, double *%base, i32 511 243 %element = load double, double *%ptr 244 %ret = insertelement <2 x double> %val, double %element, i32 1 245 ret <2 x double> %ret 246} 247 248; Test v2f64 insertion with the first ouf-of-range offset. 249define <2 x double> @f29(<2 x double> %val, double *%base) { 250; CHECK-LABEL: f29: 251; CHECK: aghi %r2, 4096 252; CHECK: vleg %v24, 0(%r2), 0 253; CHECK: br %r14 254 %ptr = getelementptr double, double *%base, i32 512 255 %element = load double, double *%ptr 256 %ret = insertelement <2 x double> %val, double %element, i32 0 257 ret <2 x double> %ret 258} 259 260; Test v2f64 insertion into a variable element. 261define <2 x double> @f30(<2 x double> %val, double *%ptr, i32 %index) { 262; CHECK-LABEL: f30: 263; CHECK-NOT: vleg 264; CHECK: br %r14 265 %element = load double, double *%ptr 266 %ret = insertelement <2 x double> %val, double %element, i32 %index 267 ret <2 x double> %ret 268} 269 270; Test a v4i32 gather of the first element. 271define <4 x i32> @f31(<4 x i32> %val, <4 x i32> %index, i64 %base) { 272; CHECK-LABEL: f31: 273; CHECK: vgef %v24, 0(%v26,%r2), 0 274; CHECK: br %r14 275 %elem = extractelement <4 x i32> %index, i32 0 276 %ext = zext i32 %elem to i64 277 %add = add i64 %base, %ext 278 %ptr = inttoptr i64 %add to i32 * 279 %element = load i32, i32 *%ptr 280 %ret = insertelement <4 x i32> %val, i32 %element, i32 0 281 ret <4 x i32> %ret 282} 283 284; Test a v4i32 gather of the last element. 285define <4 x i32> @f32(<4 x i32> %val, <4 x i32> %index, i64 %base) { 286; CHECK-LABEL: f32: 287; CHECK: vgef %v24, 0(%v26,%r2), 3 288; CHECK: br %r14 289 %elem = extractelement <4 x i32> %index, i32 3 290 %ext = zext i32 %elem to i64 291 %add = add i64 %base, %ext 292 %ptr = inttoptr i64 %add to i32 * 293 %element = load i32, i32 *%ptr 294 %ret = insertelement <4 x i32> %val, i32 %element, i32 3 295 ret <4 x i32> %ret 296} 297 298; Test a v4i32 gather with the highest in-range offset. 299define <4 x i32> @f33(<4 x i32> %val, <4 x i32> %index, i64 %base) { 300; CHECK-LABEL: f33: 301; CHECK: vgef %v24, 4095(%v26,%r2), 1 302; CHECK: br %r14 303 %elem = extractelement <4 x i32> %index, i32 1 304 %ext = zext i32 %elem to i64 305 %add1 = add i64 %base, %ext 306 %add2 = add i64 %add1, 4095 307 %ptr = inttoptr i64 %add2 to i32 * 308 %element = load i32, i32 *%ptr 309 %ret = insertelement <4 x i32> %val, i32 %element, i32 1 310 ret <4 x i32> %ret 311} 312 313; Test a v2i64 gather of the first element. 314define <2 x i64> @f34(<2 x i64> %val, <2 x i64> %index, i64 %base) { 315; CHECK-LABEL: f34: 316; CHECK: vgeg %v24, 0(%v26,%r2), 0 317; CHECK: br %r14 318 %elem = extractelement <2 x i64> %index, i32 0 319 %add = add i64 %base, %elem 320 %ptr = inttoptr i64 %add to i64 * 321 %element = load i64, i64 *%ptr 322 %ret = insertelement <2 x i64> %val, i64 %element, i32 0 323 ret <2 x i64> %ret 324} 325 326; Test a v2i64 gather of the last element. 327define <2 x i64> @f35(<2 x i64> %val, <2 x i64> %index, i64 %base) { 328; CHECK-LABEL: f35: 329; CHECK: vgeg %v24, 0(%v26,%r2), 1 330; CHECK: br %r14 331 %elem = extractelement <2 x i64> %index, i32 1 332 %add = add i64 %base, %elem 333 %ptr = inttoptr i64 %add to i64 * 334 %element = load i64, i64 *%ptr 335 %ret = insertelement <2 x i64> %val, i64 %element, i32 1 336 ret <2 x i64> %ret 337} 338 339; Test a v2f64 gather of the first element. 340define <2 x double> @f38(<2 x double> %val, <2 x i64> %index, i64 %base) { 341; CHECK-LABEL: f38: 342; CHECK: vgeg %v24, 0(%v26,%r2), 0 343; CHECK: br %r14 344 %elem = extractelement <2 x i64> %index, i32 0 345 %add = add i64 %base, %elem 346 %ptr = inttoptr i64 %add to double * 347 %element = load double, double *%ptr 348 %ret = insertelement <2 x double> %val, double %element, i32 0 349 ret <2 x double> %ret 350} 351 352; Test a v2f64 gather of the last element. 353define <2 x double> @f39(<2 x double> %val, <2 x i64> %index, i64 %base) { 354; CHECK-LABEL: f39: 355; CHECK: vgeg %v24, 0(%v26,%r2), 1 356; CHECK: br %r14 357 %elem = extractelement <2 x i64> %index, i32 1 358 %add = add i64 %base, %elem 359 %ptr = inttoptr i64 %add to double * 360 %element = load double, double *%ptr 361 %ret = insertelement <2 x double> %val, double %element, i32 1 362 ret <2 x double> %ret 363} 364