1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mattr=+sve -force-streaming-compatible < %s | FileCheck %s 3; RUN: llc -mattr=+sme -force-streaming < %s | FileCheck %s 4; RUN: llc -force-streaming-compatible < %s | FileCheck %s --check-prefix=NONEON-NOSVE 5 6 7; Test we can code generater patterns of the form: 8; fixed_length_vector = ISD::EXTRACT_SUBVECTOR scalable_vector, 0 9; scalable_vector = ISD::INSERT_SUBVECTOR scalable_vector, fixed_length_vector, 0 10; 11; NOTE: Currently shufflevector does not support scalable vectors so it cannot 12; be used to model the above operations. Instead these tests rely on knowing 13; how fixed length operation are lowered to scalable ones, with multiple blocks 14; ensuring insert/extract sequences are not folded away. 15 16target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 17target triple = "aarch64-unknown-linux-gnu" 18 19; i8 20define void @subvector_v4i8(ptr %in, ptr %out) { 21; CHECK-LABEL: subvector_v4i8: 22; CHECK: // %bb.0: // %bb1 23; CHECK-NEXT: ptrue p0.h, vl4 24; CHECK-NEXT: ld1b { z0.h }, p0/z, [x0] 25; CHECK-NEXT: st1b { z0.h }, p0, [x1] 26; CHECK-NEXT: ret 27; 28; NONEON-NOSVE-LABEL: subvector_v4i8: 29; NONEON-NOSVE: // %bb.0: // %bb1 30; NONEON-NOSVE-NEXT: ldrh w8, [x0, #2] 31; NONEON-NOSVE-NEXT: ldrb w9, [x0, #1] 32; NONEON-NOSVE-NEXT: ldrb w10, [x0] 33; NONEON-NOSVE-NEXT: strh w8, [x1, #2] 34; NONEON-NOSVE-NEXT: strb w9, [x1, #1] 35; NONEON-NOSVE-NEXT: strb w10, [x1] 36; NONEON-NOSVE-NEXT: ret 37 %a = load <4 x i8>, ptr %in 38 br label %bb1 39 40bb1: 41 store <4 x i8> %a, ptr %out 42 ret void 43} 44 45define void @subvector_v8i8(ptr %in, ptr %out) { 46; CHECK-LABEL: subvector_v8i8: 47; CHECK: // %bb.0: // %bb1 48; CHECK-NEXT: ldr d0, [x0] 49; CHECK-NEXT: str d0, [x1] 50; CHECK-NEXT: ret 51; 52; NONEON-NOSVE-LABEL: subvector_v8i8: 53; NONEON-NOSVE: // %bb.0: // %bb1 54; NONEON-NOSVE-NEXT: ldr d0, [x0] 55; NONEON-NOSVE-NEXT: str d0, [x1] 56; NONEON-NOSVE-NEXT: ret 57 %a = load <8 x i8>, ptr %in 58 br label %bb1 59 60bb1: 61 store <8 x i8> %a, ptr %out 62 ret void 63} 64 65define void @subvector_v16i8(ptr %in, ptr %out) { 66; CHECK-LABEL: subvector_v16i8: 67; CHECK: // %bb.0: // %bb1 68; CHECK-NEXT: ldr q0, [x0] 69; CHECK-NEXT: str q0, [x1] 70; CHECK-NEXT: ret 71; 72; NONEON-NOSVE-LABEL: subvector_v16i8: 73; NONEON-NOSVE: // %bb.0: // %bb1 74; NONEON-NOSVE-NEXT: ldr q0, [x0] 75; NONEON-NOSVE-NEXT: str q0, [x1] 76; NONEON-NOSVE-NEXT: ret 77 %a = load <16 x i8>, ptr %in 78 br label %bb1 79 80bb1: 81 store <16 x i8> %a, ptr %out 82 ret void 83} 84 85define void @subvector_v32i8(ptr %in, ptr %out) { 86; CHECK-LABEL: subvector_v32i8: 87; CHECK: // %bb.0: // %bb1 88; CHECK-NEXT: ldp q0, q1, [x0] 89; CHECK-NEXT: stp q0, q1, [x1] 90; CHECK-NEXT: ret 91; 92; NONEON-NOSVE-LABEL: subvector_v32i8: 93; NONEON-NOSVE: // %bb.0: // %bb1 94; NONEON-NOSVE-NEXT: ldp q0, q1, [x0] 95; NONEON-NOSVE-NEXT: stp q0, q1, [x1] 96; NONEON-NOSVE-NEXT: ret 97 %a = load <32 x i8>, ptr %in 98 br label %bb1 99 100bb1: 101 store <32 x i8> %a, ptr %out 102 ret void 103} 104 105; i16 106define void @subvector_v2i16(ptr %in, ptr %out) { 107; CHECK-LABEL: subvector_v2i16: 108; CHECK: // %bb.0: // %bb1 109; CHECK-NEXT: ptrue p0.s, vl2 110; CHECK-NEXT: ld1h { z0.s }, p0/z, [x0] 111; CHECK-NEXT: st1h { z0.s }, p0, [x1] 112; CHECK-NEXT: ret 113; 114; NONEON-NOSVE-LABEL: subvector_v2i16: 115; NONEON-NOSVE: // %bb.0: // %bb1 116; NONEON-NOSVE-NEXT: ldr w8, [x0] 117; NONEON-NOSVE-NEXT: str w8, [x1] 118; NONEON-NOSVE-NEXT: ret 119 %a = load <2 x i16>, ptr %in 120 br label %bb1 121 122bb1: 123 store <2 x i16> %a, ptr %out 124 ret void 125} 126 127define void @subvector_v4i16(ptr %in, ptr %out) { 128; CHECK-LABEL: subvector_v4i16: 129; CHECK: // %bb.0: // %bb1 130; CHECK-NEXT: ldr d0, [x0] 131; CHECK-NEXT: str d0, [x1] 132; CHECK-NEXT: ret 133; 134; NONEON-NOSVE-LABEL: subvector_v4i16: 135; NONEON-NOSVE: // %bb.0: // %bb1 136; NONEON-NOSVE-NEXT: ldr d0, [x0] 137; NONEON-NOSVE-NEXT: str d0, [x1] 138; NONEON-NOSVE-NEXT: ret 139 %a = load <4 x i16>, ptr %in 140 br label %bb1 141 142bb1: 143 store <4 x i16> %a, ptr %out 144 ret void 145} 146 147define void @subvector_v8i16(ptr %in, ptr %out) { 148; CHECK-LABEL: subvector_v8i16: 149; CHECK: // %bb.0: // %bb1 150; CHECK-NEXT: ldr q0, [x0] 151; CHECK-NEXT: str q0, [x1] 152; CHECK-NEXT: ret 153; 154; NONEON-NOSVE-LABEL: subvector_v8i16: 155; NONEON-NOSVE: // %bb.0: // %bb1 156; NONEON-NOSVE-NEXT: ldr q0, [x0] 157; NONEON-NOSVE-NEXT: str q0, [x1] 158; NONEON-NOSVE-NEXT: ret 159 %a = load <8 x i16>, ptr %in 160 br label %bb1 161 162bb1: 163 store <8 x i16> %a, ptr %out 164 ret void 165} 166 167define void @subvector_v16i16(ptr %in, ptr %out) { 168; CHECK-LABEL: subvector_v16i16: 169; CHECK: // %bb.0: // %bb1 170; CHECK-NEXT: ldp q0, q1, [x0] 171; CHECK-NEXT: stp q0, q1, [x1] 172; CHECK-NEXT: ret 173; 174; NONEON-NOSVE-LABEL: subvector_v16i16: 175; NONEON-NOSVE: // %bb.0: // %bb1 176; NONEON-NOSVE-NEXT: ldp q0, q1, [x0] 177; NONEON-NOSVE-NEXT: stp q0, q1, [x1] 178; NONEON-NOSVE-NEXT: ret 179 %a = load <16 x i16>, ptr %in 180 br label %bb1 181 182bb1: 183 store <16 x i16> %a, ptr %out 184 ret void 185} 186 187; i32 188define void @subvector_v2i32(ptr %in, ptr %out) { 189; CHECK-LABEL: subvector_v2i32: 190; CHECK: // %bb.0: // %bb1 191; CHECK-NEXT: ldr d0, [x0] 192; CHECK-NEXT: str d0, [x1] 193; CHECK-NEXT: ret 194; 195; NONEON-NOSVE-LABEL: subvector_v2i32: 196; NONEON-NOSVE: // %bb.0: // %bb1 197; NONEON-NOSVE-NEXT: ldr d0, [x0] 198; NONEON-NOSVE-NEXT: str d0, [x1] 199; NONEON-NOSVE-NEXT: ret 200 %a = load <2 x i32>, ptr %in 201 br label %bb1 202 203bb1: 204 store <2 x i32> %a, ptr %out 205 ret void 206} 207 208define void @subvector_v4i32(ptr %in, ptr %out) { 209; CHECK-LABEL: subvector_v4i32: 210; CHECK: // %bb.0: // %bb1 211; CHECK-NEXT: ldr q0, [x0] 212; CHECK-NEXT: str q0, [x1] 213; CHECK-NEXT: ret 214; 215; NONEON-NOSVE-LABEL: subvector_v4i32: 216; NONEON-NOSVE: // %bb.0: // %bb1 217; NONEON-NOSVE-NEXT: ldr q0, [x0] 218; NONEON-NOSVE-NEXT: str q0, [x1] 219; NONEON-NOSVE-NEXT: ret 220 %a = load <4 x i32>, ptr %in 221 br label %bb1 222 223bb1: 224 store <4 x i32> %a, ptr %out 225 ret void 226} 227 228define void @subvector_v8i32(ptr %in, ptr %out) { 229; CHECK-LABEL: subvector_v8i32: 230; CHECK: // %bb.0: // %bb1 231; CHECK-NEXT: ldp q0, q1, [x0] 232; CHECK-NEXT: stp q0, q1, [x1] 233; CHECK-NEXT: ret 234; 235; NONEON-NOSVE-LABEL: subvector_v8i32: 236; NONEON-NOSVE: // %bb.0: // %bb1 237; NONEON-NOSVE-NEXT: ldp q0, q1, [x0] 238; NONEON-NOSVE-NEXT: stp q0, q1, [x1] 239; NONEON-NOSVE-NEXT: ret 240 %a = load <8 x i32>, ptr %in 241 br label %bb1 242 243bb1: 244 store <8 x i32> %a, ptr %out 245 ret void 246} 247 248; i64 249define void @subvector_v2i64(ptr %in, ptr %out) { 250; CHECK-LABEL: subvector_v2i64: 251; CHECK: // %bb.0: // %bb1 252; CHECK-NEXT: ldr q0, [x0] 253; CHECK-NEXT: str q0, [x1] 254; CHECK-NEXT: ret 255; 256; NONEON-NOSVE-LABEL: subvector_v2i64: 257; NONEON-NOSVE: // %bb.0: // %bb1 258; NONEON-NOSVE-NEXT: ldr q0, [x0] 259; NONEON-NOSVE-NEXT: str q0, [x1] 260; NONEON-NOSVE-NEXT: ret 261 %a = load <2 x i64>, ptr %in 262 br label %bb1 263 264bb1: 265 store <2 x i64> %a, ptr %out 266 ret void 267} 268 269define void @subvector_v4i64(ptr %in, ptr %out) { 270; CHECK-LABEL: subvector_v4i64: 271; CHECK: // %bb.0: // %bb1 272; CHECK-NEXT: ldp q0, q1, [x0] 273; CHECK-NEXT: stp q0, q1, [x1] 274; CHECK-NEXT: ret 275; 276; NONEON-NOSVE-LABEL: subvector_v4i64: 277; NONEON-NOSVE: // %bb.0: // %bb1 278; NONEON-NOSVE-NEXT: ldp q0, q1, [x0] 279; NONEON-NOSVE-NEXT: stp q0, q1, [x1] 280; NONEON-NOSVE-NEXT: ret 281 %a = load <4 x i64>, ptr %in 282 br label %bb1 283 284bb1: 285 store <4 x i64> %a, ptr %out 286 ret void 287} 288 289; f16 290define void @subvector_v2f16(ptr %in, ptr %out) { 291; CHECK-LABEL: subvector_v2f16: 292; CHECK: // %bb.0: // %bb1 293; CHECK-NEXT: ldr w8, [x0] 294; CHECK-NEXT: str w8, [x1] 295; CHECK-NEXT: ret 296; 297; NONEON-NOSVE-LABEL: subvector_v2f16: 298; NONEON-NOSVE: // %bb.0: // %bb1 299; NONEON-NOSVE-NEXT: ldr w8, [x0] 300; NONEON-NOSVE-NEXT: str w8, [x1] 301; NONEON-NOSVE-NEXT: ret 302 %a = load <2 x half>, ptr %in 303 br label %bb1 304 305bb1: 306 store <2 x half> %a, ptr %out 307 ret void 308} 309 310define void @subvector_v4f16(ptr %in, ptr %out) { 311; CHECK-LABEL: subvector_v4f16: 312; CHECK: // %bb.0: // %bb1 313; CHECK-NEXT: ldr d0, [x0] 314; CHECK-NEXT: str d0, [x1] 315; CHECK-NEXT: ret 316; 317; NONEON-NOSVE-LABEL: subvector_v4f16: 318; NONEON-NOSVE: // %bb.0: // %bb1 319; NONEON-NOSVE-NEXT: ldr d0, [x0] 320; NONEON-NOSVE-NEXT: str d0, [x1] 321; NONEON-NOSVE-NEXT: ret 322 %a = load <4 x half>, ptr %in 323 br label %bb1 324 325bb1: 326 store <4 x half> %a, ptr %out 327 ret void 328} 329 330define void @subvector_v8f16(ptr %in, ptr %out) { 331; CHECK-LABEL: subvector_v8f16: 332; CHECK: // %bb.0: // %bb1 333; CHECK-NEXT: ldr q0, [x0] 334; CHECK-NEXT: str q0, [x1] 335; CHECK-NEXT: ret 336; 337; NONEON-NOSVE-LABEL: subvector_v8f16: 338; NONEON-NOSVE: // %bb.0: // %bb1 339; NONEON-NOSVE-NEXT: ldr q0, [x0] 340; NONEON-NOSVE-NEXT: str q0, [x1] 341; NONEON-NOSVE-NEXT: ret 342 %a = load <8 x half>, ptr %in 343 br label %bb1 344 345bb1: 346 store <8 x half> %a, ptr %out 347 ret void 348} 349 350define void @subvector_v16f16(ptr %in, ptr %out) { 351; CHECK-LABEL: subvector_v16f16: 352; CHECK: // %bb.0: // %bb1 353; CHECK-NEXT: ldp q0, q1, [x0] 354; CHECK-NEXT: stp q0, q1, [x1] 355; CHECK-NEXT: ret 356; 357; NONEON-NOSVE-LABEL: subvector_v16f16: 358; NONEON-NOSVE: // %bb.0: // %bb1 359; NONEON-NOSVE-NEXT: ldp q0, q1, [x0] 360; NONEON-NOSVE-NEXT: stp q0, q1, [x1] 361; NONEON-NOSVE-NEXT: ret 362 %a = load <16 x half>, ptr %in 363 br label %bb1 364 365bb1: 366 store <16 x half> %a, ptr %out 367 ret void 368} 369 370; f32 371define void @subvector_v2f32(ptr %in, ptr %out) { 372; CHECK-LABEL: subvector_v2f32: 373; CHECK: // %bb.0: // %bb1 374; CHECK-NEXT: ldr d0, [x0] 375; CHECK-NEXT: str d0, [x1] 376; CHECK-NEXT: ret 377; 378; NONEON-NOSVE-LABEL: subvector_v2f32: 379; NONEON-NOSVE: // %bb.0: // %bb1 380; NONEON-NOSVE-NEXT: ldr d0, [x0] 381; NONEON-NOSVE-NEXT: str d0, [x1] 382; NONEON-NOSVE-NEXT: ret 383 %a = load <2 x float>, ptr %in 384 br label %bb1 385 386bb1: 387 store <2 x float> %a, ptr %out 388 ret void 389} 390 391define void @subvector_v4f32(ptr %in, ptr %out) { 392; CHECK-LABEL: subvector_v4f32: 393; CHECK: // %bb.0: // %bb1 394; CHECK-NEXT: ldr q0, [x0] 395; CHECK-NEXT: str q0, [x1] 396; CHECK-NEXT: ret 397; 398; NONEON-NOSVE-LABEL: subvector_v4f32: 399; NONEON-NOSVE: // %bb.0: // %bb1 400; NONEON-NOSVE-NEXT: ldr q0, [x0] 401; NONEON-NOSVE-NEXT: str q0, [x1] 402; NONEON-NOSVE-NEXT: ret 403 %a = load <4 x float>, ptr %in 404 br label %bb1 405 406bb1: 407 store <4 x float> %a, ptr %out 408 ret void 409} 410 411define void @subvector_v8f32(ptr %in, ptr %out) { 412; CHECK-LABEL: subvector_v8f32: 413; CHECK: // %bb.0: // %bb1 414; CHECK-NEXT: ldp q0, q1, [x0] 415; CHECK-NEXT: stp q0, q1, [x1] 416; CHECK-NEXT: ret 417; 418; NONEON-NOSVE-LABEL: subvector_v8f32: 419; NONEON-NOSVE: // %bb.0: // %bb1 420; NONEON-NOSVE-NEXT: ldp q0, q1, [x0] 421; NONEON-NOSVE-NEXT: stp q0, q1, [x1] 422; NONEON-NOSVE-NEXT: ret 423 %a = load <8 x float>,ptr %in 424 br label %bb1 425 426bb1: 427 store <8 x float> %a, ptr %out 428 ret void 429} 430 431; f64 432define void @subvector_v2f64(ptr %in, ptr %out) { 433; CHECK-LABEL: subvector_v2f64: 434; CHECK: // %bb.0: // %bb1 435; CHECK-NEXT: ldr q0, [x0] 436; CHECK-NEXT: str q0, [x1] 437; CHECK-NEXT: ret 438; 439; NONEON-NOSVE-LABEL: subvector_v2f64: 440; NONEON-NOSVE: // %bb.0: // %bb1 441; NONEON-NOSVE-NEXT: ldr q0, [x0] 442; NONEON-NOSVE-NEXT: str q0, [x1] 443; NONEON-NOSVE-NEXT: ret 444 %a = load <2 x double>, ptr %in 445 br label %bb1 446 447bb1: 448 store <2 x double> %a, ptr %out 449 ret void 450} 451 452define void @subvector_v4f64(ptr %in, ptr %out) { 453; CHECK-LABEL: subvector_v4f64: 454; CHECK: // %bb.0: // %bb1 455; CHECK-NEXT: ldp q0, q1, [x0] 456; CHECK-NEXT: stp q0, q1, [x1] 457; CHECK-NEXT: ret 458; 459; NONEON-NOSVE-LABEL: subvector_v4f64: 460; NONEON-NOSVE: // %bb.0: // %bb1 461; NONEON-NOSVE-NEXT: ldp q0, q1, [x0] 462; NONEON-NOSVE-NEXT: stp q0, q1, [x1] 463; NONEON-NOSVE-NEXT: ret 464 %a = load <4 x double>, ptr %in 465 br label %bb1 466 467bb1: 468 store <4 x double> %a, ptr %out 469 ret void 470} 471