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 -force-streaming-compatible < %s | FileCheck %s --check-prefix=NONEON-NOSVE 4; RUN: llc -force-streaming-compatible -use-constant-int-for-fixed-length-splat -use-constant-fp-for-fixed-length-splat < %s | FileCheck %s --check-prefix=NONEON-NOSVE 5 6target triple = "aarch64-unknown-linux-gnu" 7 8; 9; DUP (integer) 10; 11 12define <4 x i8> @splat_v4i8(i8 %a) { 13; CHECK-LABEL: splat_v4i8: 14; CHECK: // %bb.0: 15; CHECK-NEXT: mov z0.h, w0 16; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 17; CHECK-NEXT: ret 18; 19; NONEON-NOSVE-LABEL: splat_v4i8: 20; NONEON-NOSVE: // %bb.0: 21; NONEON-NOSVE-NEXT: sub sp, sp, #16 22; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 23; NONEON-NOSVE-NEXT: strh w0, [sp, #14] 24; NONEON-NOSVE-NEXT: strh w0, [sp, #12] 25; NONEON-NOSVE-NEXT: strh w0, [sp, #10] 26; NONEON-NOSVE-NEXT: strh w0, [sp, #8] 27; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 28; NONEON-NOSVE-NEXT: add sp, sp, #16 29; NONEON-NOSVE-NEXT: ret 30 %insert = insertelement <4 x i8> undef, i8 %a, i64 0 31 %splat = shufflevector <4 x i8> %insert, <4 x i8> undef, <4 x i32> zeroinitializer 32 ret <4 x i8> %splat 33} 34 35define <8 x i8> @splat_v8i8(i8 %a) { 36; CHECK-LABEL: splat_v8i8: 37; CHECK: // %bb.0: 38; CHECK-NEXT: mov z0.b, w0 39; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 40; CHECK-NEXT: ret 41; 42; NONEON-NOSVE-LABEL: splat_v8i8: 43; NONEON-NOSVE: // %bb.0: 44; NONEON-NOSVE-NEXT: sub sp, sp, #16 45; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 46; NONEON-NOSVE-NEXT: strb w0, [sp, #15] 47; NONEON-NOSVE-NEXT: strb w0, [sp, #14] 48; NONEON-NOSVE-NEXT: strb w0, [sp, #13] 49; NONEON-NOSVE-NEXT: strb w0, [sp, #12] 50; NONEON-NOSVE-NEXT: strb w0, [sp, #11] 51; NONEON-NOSVE-NEXT: strb w0, [sp, #10] 52; NONEON-NOSVE-NEXT: strb w0, [sp, #9] 53; NONEON-NOSVE-NEXT: strb w0, [sp, #8] 54; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 55; NONEON-NOSVE-NEXT: add sp, sp, #16 56; NONEON-NOSVE-NEXT: ret 57 %insert = insertelement <8 x i8> undef, i8 %a, i64 0 58 %splat = shufflevector <8 x i8> %insert, <8 x i8> undef, <8 x i32> zeroinitializer 59 ret <8 x i8> %splat 60} 61 62define <16 x i8> @splat_v16i8(i8 %a) { 63; CHECK-LABEL: splat_v16i8: 64; CHECK: // %bb.0: 65; CHECK-NEXT: mov z0.b, w0 66; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 67; CHECK-NEXT: ret 68; 69; NONEON-NOSVE-LABEL: splat_v16i8: 70; NONEON-NOSVE: // %bb.0: 71; NONEON-NOSVE-NEXT: sub sp, sp, #16 72; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 73; NONEON-NOSVE-NEXT: strb w0, [sp, #15] 74; NONEON-NOSVE-NEXT: strb w0, [sp, #14] 75; NONEON-NOSVE-NEXT: strb w0, [sp, #13] 76; NONEON-NOSVE-NEXT: strb w0, [sp, #12] 77; NONEON-NOSVE-NEXT: strb w0, [sp, #11] 78; NONEON-NOSVE-NEXT: strb w0, [sp, #10] 79; NONEON-NOSVE-NEXT: strb w0, [sp, #9] 80; NONEON-NOSVE-NEXT: strb w0, [sp, #8] 81; NONEON-NOSVE-NEXT: strb w0, [sp, #7] 82; NONEON-NOSVE-NEXT: strb w0, [sp, #6] 83; NONEON-NOSVE-NEXT: strb w0, [sp, #5] 84; NONEON-NOSVE-NEXT: strb w0, [sp, #4] 85; NONEON-NOSVE-NEXT: strb w0, [sp, #3] 86; NONEON-NOSVE-NEXT: strb w0, [sp, #2] 87; NONEON-NOSVE-NEXT: strb w0, [sp, #1] 88; NONEON-NOSVE-NEXT: strb w0, [sp] 89; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 90; NONEON-NOSVE-NEXT: ret 91 %insert = insertelement <16 x i8> undef, i8 %a, i64 0 92 %splat = shufflevector <16 x i8> %insert, <16 x i8> undef, <16 x i32> zeroinitializer 93 ret <16 x i8> %splat 94} 95 96define void @splat_v32i8(i8 %a, ptr %b) { 97; CHECK-LABEL: splat_v32i8: 98; CHECK: // %bb.0: 99; CHECK-NEXT: mov z0.b, w0 100; CHECK-NEXT: stp q0, q0, [x1] 101; CHECK-NEXT: ret 102; 103; NONEON-NOSVE-LABEL: splat_v32i8: 104; NONEON-NOSVE: // %bb.0: 105; NONEON-NOSVE-NEXT: sub sp, sp, #16 106; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 107; NONEON-NOSVE-NEXT: strb w0, [sp, #15] 108; NONEON-NOSVE-NEXT: strb w0, [sp, #14] 109; NONEON-NOSVE-NEXT: strb w0, [sp, #13] 110; NONEON-NOSVE-NEXT: strb w0, [sp, #12] 111; NONEON-NOSVE-NEXT: strb w0, [sp, #11] 112; NONEON-NOSVE-NEXT: strb w0, [sp, #10] 113; NONEON-NOSVE-NEXT: strb w0, [sp, #9] 114; NONEON-NOSVE-NEXT: strb w0, [sp, #8] 115; NONEON-NOSVE-NEXT: strb w0, [sp, #7] 116; NONEON-NOSVE-NEXT: strb w0, [sp, #6] 117; NONEON-NOSVE-NEXT: strb w0, [sp, #5] 118; NONEON-NOSVE-NEXT: strb w0, [sp, #4] 119; NONEON-NOSVE-NEXT: strb w0, [sp, #3] 120; NONEON-NOSVE-NEXT: strb w0, [sp, #2] 121; NONEON-NOSVE-NEXT: strb w0, [sp, #1] 122; NONEON-NOSVE-NEXT: strb w0, [sp] 123; NONEON-NOSVE-NEXT: ldr q0, [sp] 124; NONEON-NOSVE-NEXT: stp q0, q0, [x1] 125; NONEON-NOSVE-NEXT: add sp, sp, #16 126; NONEON-NOSVE-NEXT: ret 127 %insert = insertelement <32 x i8> undef, i8 %a, i64 0 128 %splat = shufflevector <32 x i8> %insert, <32 x i8> undef, <32 x i32> zeroinitializer 129 store <32 x i8> %splat, ptr %b 130 ret void 131} 132 133define <2 x i16> @splat_v2i16(i16 %a) { 134; CHECK-LABEL: splat_v2i16: 135; CHECK: // %bb.0: 136; CHECK-NEXT: mov z0.s, w0 137; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 138; CHECK-NEXT: ret 139; 140; NONEON-NOSVE-LABEL: splat_v2i16: 141; NONEON-NOSVE: // %bb.0: 142; NONEON-NOSVE-NEXT: sub sp, sp, #16 143; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 144; NONEON-NOSVE-NEXT: stp w0, w0, [sp, #8] 145; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 146; NONEON-NOSVE-NEXT: add sp, sp, #16 147; NONEON-NOSVE-NEXT: ret 148 %insert = insertelement <2 x i16> undef, i16 %a, i64 0 149 %splat = shufflevector <2 x i16> %insert, <2 x i16> undef, <2 x i32> zeroinitializer 150 ret <2 x i16> %splat 151} 152 153define <4 x i16> @splat_v4i16(i16 %a) { 154; CHECK-LABEL: splat_v4i16: 155; CHECK: // %bb.0: 156; CHECK-NEXT: mov z0.h, w0 157; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 158; CHECK-NEXT: ret 159; 160; NONEON-NOSVE-LABEL: splat_v4i16: 161; NONEON-NOSVE: // %bb.0: 162; NONEON-NOSVE-NEXT: sub sp, sp, #16 163; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 164; NONEON-NOSVE-NEXT: strh w0, [sp, #14] 165; NONEON-NOSVE-NEXT: strh w0, [sp, #12] 166; NONEON-NOSVE-NEXT: strh w0, [sp, #10] 167; NONEON-NOSVE-NEXT: strh w0, [sp, #8] 168; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 169; NONEON-NOSVE-NEXT: add sp, sp, #16 170; NONEON-NOSVE-NEXT: ret 171 %insert = insertelement <4 x i16> undef, i16 %a, i64 0 172 %splat = shufflevector <4 x i16> %insert, <4 x i16> undef, <4 x i32> zeroinitializer 173 ret <4 x i16> %splat 174} 175 176define <8 x i16> @splat_v8i16(i16 %a) { 177; CHECK-LABEL: splat_v8i16: 178; CHECK: // %bb.0: 179; CHECK-NEXT: mov z0.h, w0 180; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 181; CHECK-NEXT: ret 182; 183; NONEON-NOSVE-LABEL: splat_v8i16: 184; NONEON-NOSVE: // %bb.0: 185; NONEON-NOSVE-NEXT: sub sp, sp, #16 186; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 187; NONEON-NOSVE-NEXT: strh w0, [sp, #14] 188; NONEON-NOSVE-NEXT: strh w0, [sp, #12] 189; NONEON-NOSVE-NEXT: strh w0, [sp, #10] 190; NONEON-NOSVE-NEXT: strh w0, [sp, #8] 191; NONEON-NOSVE-NEXT: strh w0, [sp, #6] 192; NONEON-NOSVE-NEXT: strh w0, [sp, #4] 193; NONEON-NOSVE-NEXT: strh w0, [sp, #2] 194; NONEON-NOSVE-NEXT: strh w0, [sp] 195; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 196; NONEON-NOSVE-NEXT: ret 197 %insert = insertelement <8 x i16> undef, i16 %a, i64 0 198 %splat = shufflevector <8 x i16> %insert, <8 x i16> undef, <8 x i32> zeroinitializer 199 ret <8 x i16> %splat 200} 201 202define void @splat_v16i16(i16 %a, ptr %b) { 203; CHECK-LABEL: splat_v16i16: 204; CHECK: // %bb.0: 205; CHECK-NEXT: mov z0.h, w0 206; CHECK-NEXT: stp q0, q0, [x1] 207; CHECK-NEXT: ret 208; 209; NONEON-NOSVE-LABEL: splat_v16i16: 210; NONEON-NOSVE: // %bb.0: 211; NONEON-NOSVE-NEXT: sub sp, sp, #16 212; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 213; NONEON-NOSVE-NEXT: strh w0, [sp, #14] 214; NONEON-NOSVE-NEXT: strh w0, [sp, #12] 215; NONEON-NOSVE-NEXT: strh w0, [sp, #10] 216; NONEON-NOSVE-NEXT: strh w0, [sp, #8] 217; NONEON-NOSVE-NEXT: strh w0, [sp, #6] 218; NONEON-NOSVE-NEXT: strh w0, [sp, #4] 219; NONEON-NOSVE-NEXT: strh w0, [sp, #2] 220; NONEON-NOSVE-NEXT: strh w0, [sp] 221; NONEON-NOSVE-NEXT: ldr q0, [sp] 222; NONEON-NOSVE-NEXT: stp q0, q0, [x1] 223; NONEON-NOSVE-NEXT: add sp, sp, #16 224; NONEON-NOSVE-NEXT: ret 225 %insert = insertelement <16 x i16> undef, i16 %a, i64 0 226 %splat = shufflevector <16 x i16> %insert, <16 x i16> undef, <16 x i32> zeroinitializer 227 store <16 x i16> %splat, ptr %b 228 ret void 229} 230 231define <2 x i32> @splat_v2i32(i32 %a) { 232; CHECK-LABEL: splat_v2i32: 233; CHECK: // %bb.0: 234; CHECK-NEXT: mov z0.s, w0 235; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 236; CHECK-NEXT: ret 237; 238; NONEON-NOSVE-LABEL: splat_v2i32: 239; NONEON-NOSVE: // %bb.0: 240; NONEON-NOSVE-NEXT: sub sp, sp, #16 241; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 242; NONEON-NOSVE-NEXT: stp w0, w0, [sp, #8] 243; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 244; NONEON-NOSVE-NEXT: add sp, sp, #16 245; NONEON-NOSVE-NEXT: ret 246 %insert = insertelement <2 x i32> undef, i32 %a, i64 0 247 %splat = shufflevector <2 x i32> %insert, <2 x i32> undef, <2 x i32> zeroinitializer 248 ret <2 x i32> %splat 249} 250 251define <4 x i32> @splat_v4i32(i32 %a) { 252; CHECK-LABEL: splat_v4i32: 253; CHECK: // %bb.0: 254; CHECK-NEXT: mov z0.s, w0 255; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 256; CHECK-NEXT: ret 257; 258; NONEON-NOSVE-LABEL: splat_v4i32: 259; NONEON-NOSVE: // %bb.0: 260; NONEON-NOSVE-NEXT: sub sp, sp, #16 261; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 262; NONEON-NOSVE-NEXT: stp w0, w0, [sp, #8] 263; NONEON-NOSVE-NEXT: stp w0, w0, [sp] 264; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 265; NONEON-NOSVE-NEXT: ret 266 %insert = insertelement <4 x i32> undef, i32 %a, i64 0 267 %splat = shufflevector <4 x i32> %insert, <4 x i32> undef, <4 x i32> zeroinitializer 268 ret <4 x i32> %splat 269} 270 271define void @splat_v8i32(i32 %a, ptr %b) { 272; CHECK-LABEL: splat_v8i32: 273; CHECK: // %bb.0: 274; CHECK-NEXT: mov z0.s, w0 275; CHECK-NEXT: stp q0, q0, [x1] 276; CHECK-NEXT: ret 277; 278; NONEON-NOSVE-LABEL: splat_v8i32: 279; NONEON-NOSVE: // %bb.0: 280; NONEON-NOSVE-NEXT: sub sp, sp, #16 281; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 282; NONEON-NOSVE-NEXT: stp w0, w0, [sp, #8] 283; NONEON-NOSVE-NEXT: stp w0, w0, [sp] 284; NONEON-NOSVE-NEXT: ldr q0, [sp] 285; NONEON-NOSVE-NEXT: stp q0, q0, [x1] 286; NONEON-NOSVE-NEXT: add sp, sp, #16 287; NONEON-NOSVE-NEXT: ret 288 %insert = insertelement <8 x i32> undef, i32 %a, i64 0 289 %splat = shufflevector <8 x i32> %insert, <8 x i32> undef, <8 x i32> zeroinitializer 290 store <8 x i32> %splat, ptr %b 291 ret void 292} 293 294define <1 x i64> @splat_v1i64(i64 %a) { 295; CHECK-LABEL: splat_v1i64: 296; CHECK: // %bb.0: 297; CHECK-NEXT: mov z0.d, x0 298; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 299; CHECK-NEXT: ret 300; 301; NONEON-NOSVE-LABEL: splat_v1i64: 302; NONEON-NOSVE: // %bb.0: 303; NONEON-NOSVE-NEXT: sub sp, sp, #16 304; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 305; NONEON-NOSVE-NEXT: str x0, [sp, #8] 306; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 307; NONEON-NOSVE-NEXT: add sp, sp, #16 308; NONEON-NOSVE-NEXT: ret 309 %insert = insertelement <1 x i64> undef, i64 %a, i64 0 310 %splat = shufflevector <1 x i64> %insert, <1 x i64> undef, <1 x i32> zeroinitializer 311 ret <1 x i64> %splat 312} 313 314define <2 x i64> @splat_v2i64(i64 %a) { 315; CHECK-LABEL: splat_v2i64: 316; CHECK: // %bb.0: 317; CHECK-NEXT: mov z0.d, x0 318; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 319; CHECK-NEXT: ret 320; 321; NONEON-NOSVE-LABEL: splat_v2i64: 322; NONEON-NOSVE: // %bb.0: 323; NONEON-NOSVE-NEXT: stp x0, x0, [sp, #-16]! 324; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 325; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 326; NONEON-NOSVE-NEXT: ret 327 %insert = insertelement <2 x i64> undef, i64 %a, i64 0 328 %splat = shufflevector <2 x i64> %insert, <2 x i64> undef, <2 x i32> zeroinitializer 329 ret <2 x i64> %splat 330} 331 332define void @splat_v4i64(i64 %a, ptr %b) { 333; CHECK-LABEL: splat_v4i64: 334; CHECK: // %bb.0: 335; CHECK-NEXT: mov z0.d, x0 336; CHECK-NEXT: stp q0, q0, [x1] 337; CHECK-NEXT: ret 338; 339; NONEON-NOSVE-LABEL: splat_v4i64: 340; NONEON-NOSVE: // %bb.0: 341; NONEON-NOSVE-NEXT: stp x0, x0, [sp, #-16]! 342; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 343; NONEON-NOSVE-NEXT: ldr q0, [sp] 344; NONEON-NOSVE-NEXT: stp q0, q0, [x1] 345; NONEON-NOSVE-NEXT: add sp, sp, #16 346; NONEON-NOSVE-NEXT: ret 347 %insert = insertelement <4 x i64> undef, i64 %a, i64 0 348 %splat = shufflevector <4 x i64> %insert, <4 x i64> undef, <4 x i32> zeroinitializer 349 store <4 x i64> %splat, ptr %b 350 ret void 351} 352 353; 354; DUP (floating-point) 355; 356 357define <2 x half> @splat_v2f16(half %a) { 358; CHECK-LABEL: splat_v2f16: 359; CHECK: // %bb.0: 360; CHECK-NEXT: // kill: def $h0 killed $h0 def $z0 361; CHECK-NEXT: mov z0.h, h0 362; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 363; CHECK-NEXT: ret 364; 365; NONEON-NOSVE-LABEL: splat_v2f16: 366; NONEON-NOSVE: // %bb.0: 367; NONEON-NOSVE-NEXT: sub sp, sp, #16 368; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 369; NONEON-NOSVE-NEXT: str h0, [sp, #10] 370; NONEON-NOSVE-NEXT: str h0, [sp, #8] 371; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 372; NONEON-NOSVE-NEXT: add sp, sp, #16 373; NONEON-NOSVE-NEXT: ret 374 %insert = insertelement <2 x half> undef, half %a, i64 0 375 %splat = shufflevector <2 x half> %insert, <2 x half> undef, <2 x i32> zeroinitializer 376 ret <2 x half> %splat 377} 378 379define <4 x half> @splat_v4f16(half %a) { 380; CHECK-LABEL: splat_v4f16: 381; CHECK: // %bb.0: 382; CHECK-NEXT: // kill: def $h0 killed $h0 def $z0 383; CHECK-NEXT: mov z0.h, h0 384; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 385; CHECK-NEXT: ret 386; 387; NONEON-NOSVE-LABEL: splat_v4f16: 388; NONEON-NOSVE: // %bb.0: 389; NONEON-NOSVE-NEXT: sub sp, sp, #16 390; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 391; NONEON-NOSVE-NEXT: str h0, [sp, #14] 392; NONEON-NOSVE-NEXT: str h0, [sp, #12] 393; NONEON-NOSVE-NEXT: str h0, [sp, #10] 394; NONEON-NOSVE-NEXT: str h0, [sp, #8] 395; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 396; NONEON-NOSVE-NEXT: add sp, sp, #16 397; NONEON-NOSVE-NEXT: ret 398 %insert = insertelement <4 x half> undef, half %a, i64 0 399 %splat = shufflevector <4 x half> %insert, <4 x half> undef, <4 x i32> zeroinitializer 400 ret <4 x half> %splat 401} 402 403define <8 x half> @splat_v8f16(half %a) { 404; CHECK-LABEL: splat_v8f16: 405; CHECK: // %bb.0: 406; CHECK-NEXT: // kill: def $h0 killed $h0 def $z0 407; CHECK-NEXT: mov z0.h, h0 408; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 409; CHECK-NEXT: ret 410; 411; NONEON-NOSVE-LABEL: splat_v8f16: 412; NONEON-NOSVE: // %bb.0: 413; NONEON-NOSVE-NEXT: sub sp, sp, #16 414; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 415; NONEON-NOSVE-NEXT: str h0, [sp, #14] 416; NONEON-NOSVE-NEXT: str h0, [sp, #12] 417; NONEON-NOSVE-NEXT: str h0, [sp, #10] 418; NONEON-NOSVE-NEXT: str h0, [sp, #8] 419; NONEON-NOSVE-NEXT: str h0, [sp, #6] 420; NONEON-NOSVE-NEXT: str h0, [sp, #4] 421; NONEON-NOSVE-NEXT: str h0, [sp, #2] 422; NONEON-NOSVE-NEXT: str h0, [sp] 423; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 424; NONEON-NOSVE-NEXT: ret 425 %insert = insertelement <8 x half> undef, half %a, i64 0 426 %splat = shufflevector <8 x half> %insert, <8 x half> undef, <8 x i32> zeroinitializer 427 ret <8 x half> %splat 428} 429 430define void @splat_v16f16(half %a, ptr %b) { 431; CHECK-LABEL: splat_v16f16: 432; CHECK: // %bb.0: 433; CHECK-NEXT: // kill: def $h0 killed $h0 def $z0 434; CHECK-NEXT: mov z0.h, h0 435; CHECK-NEXT: stp q0, q0, [x0] 436; CHECK-NEXT: ret 437; 438; NONEON-NOSVE-LABEL: splat_v16f16: 439; NONEON-NOSVE: // %bb.0: 440; NONEON-NOSVE-NEXT: sub sp, sp, #16 441; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 442; NONEON-NOSVE-NEXT: str h0, [sp, #14] 443; NONEON-NOSVE-NEXT: str h0, [sp, #12] 444; NONEON-NOSVE-NEXT: str h0, [sp, #10] 445; NONEON-NOSVE-NEXT: str h0, [sp, #8] 446; NONEON-NOSVE-NEXT: str h0, [sp, #6] 447; NONEON-NOSVE-NEXT: str h0, [sp, #4] 448; NONEON-NOSVE-NEXT: str h0, [sp, #2] 449; NONEON-NOSVE-NEXT: str h0, [sp] 450; NONEON-NOSVE-NEXT: ldr q0, [sp] 451; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 452; NONEON-NOSVE-NEXT: add sp, sp, #16 453; NONEON-NOSVE-NEXT: ret 454 %insert = insertelement <16 x half> undef, half %a, i64 0 455 %splat = shufflevector <16 x half> %insert, <16 x half> undef, <16 x i32> zeroinitializer 456 store <16 x half> %splat, ptr %b 457 ret void 458} 459 460define <2 x float> @splat_v2f32(float %a, <2 x float> %op2) { 461; CHECK-LABEL: splat_v2f32: 462; CHECK: // %bb.0: 463; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0 464; CHECK-NEXT: mov z0.s, s0 465; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 466; CHECK-NEXT: ret 467; 468; NONEON-NOSVE-LABEL: splat_v2f32: 469; NONEON-NOSVE: // %bb.0: 470; NONEON-NOSVE-NEXT: sub sp, sp, #16 471; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 472; NONEON-NOSVE-NEXT: stp s0, s0, [sp, #8] 473; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 474; NONEON-NOSVE-NEXT: add sp, sp, #16 475; NONEON-NOSVE-NEXT: ret 476 %insert = insertelement <2 x float> undef, float %a, i64 0 477 %splat = shufflevector <2 x float> %insert, <2 x float> undef, <2 x i32> zeroinitializer 478 ret <2 x float> %splat 479} 480 481define <4 x float> @splat_v4f32(float %a, <4 x float> %op2) { 482; CHECK-LABEL: splat_v4f32: 483; CHECK: // %bb.0: 484; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0 485; CHECK-NEXT: mov z0.s, s0 486; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 487; CHECK-NEXT: ret 488; 489; NONEON-NOSVE-LABEL: splat_v4f32: 490; NONEON-NOSVE: // %bb.0: 491; NONEON-NOSVE-NEXT: sub sp, sp, #16 492; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 493; NONEON-NOSVE-NEXT: stp s0, s0, [sp, #8] 494; NONEON-NOSVE-NEXT: stp s0, s0, [sp] 495; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 496; NONEON-NOSVE-NEXT: ret 497 %insert = insertelement <4 x float> undef, float %a, i64 0 498 %splat = shufflevector <4 x float> %insert, <4 x float> undef, <4 x i32> zeroinitializer 499 ret <4 x float> %splat 500} 501 502define void @splat_v8f32(float %a, ptr %b) { 503; CHECK-LABEL: splat_v8f32: 504; CHECK: // %bb.0: 505; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0 506; CHECK-NEXT: mov z0.s, s0 507; CHECK-NEXT: stp q0, q0, [x0] 508; CHECK-NEXT: ret 509; 510; NONEON-NOSVE-LABEL: splat_v8f32: 511; NONEON-NOSVE: // %bb.0: 512; NONEON-NOSVE-NEXT: sub sp, sp, #16 513; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 514; NONEON-NOSVE-NEXT: stp s0, s0, [sp, #8] 515; NONEON-NOSVE-NEXT: stp s0, s0, [sp] 516; NONEON-NOSVE-NEXT: ldr q0, [sp] 517; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 518; NONEON-NOSVE-NEXT: add sp, sp, #16 519; NONEON-NOSVE-NEXT: ret 520 %insert = insertelement <8 x float> undef, float %a, i64 0 521 %splat = shufflevector <8 x float> %insert, <8 x float> undef, <8 x i32> zeroinitializer 522 store <8 x float> %splat, ptr %b 523 ret void 524} 525 526define <1 x double> @splat_v1f64(double %a, <1 x double> %op2) { 527; CHECK-LABEL: splat_v1f64: 528; CHECK: // %bb.0: 529; CHECK-NEXT: ret 530; 531; NONEON-NOSVE-LABEL: splat_v1f64: 532; NONEON-NOSVE: // %bb.0: 533; NONEON-NOSVE-NEXT: sub sp, sp, #16 534; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 535; NONEON-NOSVE-NEXT: str d0, [sp, #8] 536; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 537; NONEON-NOSVE-NEXT: add sp, sp, #16 538; NONEON-NOSVE-NEXT: ret 539 %insert = insertelement <1 x double> undef, double %a, i64 0 540 %splat = shufflevector <1 x double> %insert, <1 x double> undef, <1 x i32> zeroinitializer 541 ret <1 x double> %splat 542} 543 544define <2 x double> @splat_v2f64(double %a, <2 x double> %op2) { 545; CHECK-LABEL: splat_v2f64: 546; CHECK: // %bb.0: 547; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 548; CHECK-NEXT: mov z0.d, d0 549; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 550; CHECK-NEXT: ret 551; 552; NONEON-NOSVE-LABEL: splat_v2f64: 553; NONEON-NOSVE: // %bb.0: 554; NONEON-NOSVE-NEXT: stp d0, d0, [sp, #-16]! 555; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 556; NONEON-NOSVE-NEXT: ldr q0, [sp], #16 557; NONEON-NOSVE-NEXT: ret 558 %insert = insertelement <2 x double> undef, double %a, i64 0 559 %splat = shufflevector <2 x double> %insert, <2 x double> undef, <2 x i32> zeroinitializer 560 ret <2 x double> %splat 561} 562 563define void @splat_v4f64(double %a, ptr %b) { 564; CHECK-LABEL: splat_v4f64: 565; CHECK: // %bb.0: 566; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 567; CHECK-NEXT: mov z0.d, d0 568; CHECK-NEXT: stp q0, q0, [x0] 569; CHECK-NEXT: ret 570; 571; NONEON-NOSVE-LABEL: splat_v4f64: 572; NONEON-NOSVE: // %bb.0: 573; NONEON-NOSVE-NEXT: stp d0, d0, [sp, #-16]! 574; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 575; NONEON-NOSVE-NEXT: ldr q0, [sp] 576; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 577; NONEON-NOSVE-NEXT: add sp, sp, #16 578; NONEON-NOSVE-NEXT: ret 579 %insert = insertelement <4 x double> undef, double %a, i64 0 580 %splat = shufflevector <4 x double> %insert, <4 x double> undef, <4 x i32> zeroinitializer 581 store <4 x double> %splat, ptr %b 582 ret void 583} 584 585; 586; DUP (integer immediate) 587; 588 589define void @splat_imm_v32i8(ptr %a) { 590; CHECK-LABEL: splat_imm_v32i8: 591; CHECK: // %bb.0: 592; CHECK-NEXT: mov z0.b, #1 // =0x1 593; CHECK-NEXT: stp q0, q0, [x0] 594; CHECK-NEXT: ret 595; 596; NONEON-NOSVE-LABEL: splat_imm_v32i8: 597; NONEON-NOSVE: // %bb.0: 598; NONEON-NOSVE-NEXT: adrp x8, .LCPI24_0 599; NONEON-NOSVE-NEXT: ldr q0, [x8, :lo12:.LCPI24_0] 600; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 601; NONEON-NOSVE-NEXT: ret 602 %insert = insertelement <32 x i8> undef, i8 1, i64 0 603 %splat = shufflevector <32 x i8> %insert, <32 x i8> undef, <32 x i32> zeroinitializer 604 store <32 x i8> %splat, ptr %a 605 ret void 606} 607 608define void @splat_imm_v16i16(ptr %a) { 609; CHECK-LABEL: splat_imm_v16i16: 610; CHECK: // %bb.0: 611; CHECK-NEXT: mov z0.h, #2 // =0x2 612; CHECK-NEXT: stp q0, q0, [x0] 613; CHECK-NEXT: ret 614; 615; NONEON-NOSVE-LABEL: splat_imm_v16i16: 616; NONEON-NOSVE: // %bb.0: 617; NONEON-NOSVE-NEXT: adrp x8, .LCPI25_0 618; NONEON-NOSVE-NEXT: ldr q0, [x8, :lo12:.LCPI25_0] 619; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 620; NONEON-NOSVE-NEXT: ret 621 %insert = insertelement <16 x i16> undef, i16 2, i64 0 622 %splat = shufflevector <16 x i16> %insert, <16 x i16> undef, <16 x i32> zeroinitializer 623 store <16 x i16> %splat, ptr %a 624 ret void 625} 626 627define void @splat_imm_v8i32(ptr %a) { 628; CHECK-LABEL: splat_imm_v8i32: 629; CHECK: // %bb.0: 630; CHECK-NEXT: mov z0.s, #3 // =0x3 631; CHECK-NEXT: stp q0, q0, [x0] 632; CHECK-NEXT: ret 633; 634; NONEON-NOSVE-LABEL: splat_imm_v8i32: 635; NONEON-NOSVE: // %bb.0: 636; NONEON-NOSVE-NEXT: adrp x8, .LCPI26_0 637; NONEON-NOSVE-NEXT: ldr q0, [x8, :lo12:.LCPI26_0] 638; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 639; NONEON-NOSVE-NEXT: ret 640 %insert = insertelement <8 x i32> undef, i32 3, i64 0 641 %splat = shufflevector <8 x i32> %insert, <8 x i32> undef, <8 x i32> zeroinitializer 642 store <8 x i32> %splat, ptr %a 643 ret void 644} 645 646define void @splat_imm_v4i64(ptr %a) { 647; CHECK-LABEL: splat_imm_v4i64: 648; CHECK: // %bb.0: 649; CHECK-NEXT: mov z0.d, #4 // =0x4 650; CHECK-NEXT: stp q0, q0, [x0] 651; CHECK-NEXT: ret 652; 653; NONEON-NOSVE-LABEL: splat_imm_v4i64: 654; NONEON-NOSVE: // %bb.0: 655; NONEON-NOSVE-NEXT: adrp x8, .LCPI27_0 656; NONEON-NOSVE-NEXT: ldr q0, [x8, :lo12:.LCPI27_0] 657; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 658; NONEON-NOSVE-NEXT: ret 659 %insert = insertelement <4 x i64> undef, i64 4, i64 0 660 %splat = shufflevector <4 x i64> %insert, <4 x i64> undef, <4 x i32> zeroinitializer 661 store <4 x i64> %splat, ptr %a 662 ret void 663} 664 665; 666; DUP (floating-point immediate) 667; 668 669define void @splat_imm_v16f16(ptr %a) { 670; CHECK-LABEL: splat_imm_v16f16: 671; CHECK: // %bb.0: 672; CHECK-NEXT: fmov z0.h, #5.00000000 673; CHECK-NEXT: stp q0, q0, [x0] 674; CHECK-NEXT: ret 675; 676; NONEON-NOSVE-LABEL: splat_imm_v16f16: 677; NONEON-NOSVE: // %bb.0: 678; NONEON-NOSVE-NEXT: adrp x8, .LCPI28_0 679; NONEON-NOSVE-NEXT: ldr q0, [x8, :lo12:.LCPI28_0] 680; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 681; NONEON-NOSVE-NEXT: ret 682 %insert = insertelement <16 x half> undef, half 5.0, i64 0 683 %splat = shufflevector <16 x half> %insert, <16 x half> undef, <16 x i32> zeroinitializer 684 store <16 x half> %splat, ptr %a 685 ret void 686} 687 688define void @splat_imm_v8f32(ptr %a) { 689; CHECK-LABEL: splat_imm_v8f32: 690; CHECK: // %bb.0: 691; CHECK-NEXT: fmov z0.s, #6.00000000 692; CHECK-NEXT: stp q0, q0, [x0] 693; CHECK-NEXT: ret 694; 695; NONEON-NOSVE-LABEL: splat_imm_v8f32: 696; NONEON-NOSVE: // %bb.0: 697; NONEON-NOSVE-NEXT: adrp x8, .LCPI29_0 698; NONEON-NOSVE-NEXT: ldr q0, [x8, :lo12:.LCPI29_0] 699; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 700; NONEON-NOSVE-NEXT: ret 701 %insert = insertelement <8 x float> undef, float 6.0, i64 0 702 %splat = shufflevector <8 x float> %insert, <8 x float> undef, <8 x i32> zeroinitializer 703 store <8 x float> %splat, ptr %a 704 ret void 705} 706 707define void @splat_imm_v4f64(ptr %a) { 708; CHECK-LABEL: splat_imm_v4f64: 709; CHECK: // %bb.0: 710; CHECK-NEXT: fmov z0.d, #7.00000000 711; CHECK-NEXT: stp q0, q0, [x0] 712; CHECK-NEXT: ret 713; 714; NONEON-NOSVE-LABEL: splat_imm_v4f64: 715; NONEON-NOSVE: // %bb.0: 716; NONEON-NOSVE-NEXT: adrp x8, .LCPI30_0 717; NONEON-NOSVE-NEXT: ldr q0, [x8, :lo12:.LCPI30_0] 718; NONEON-NOSVE-NEXT: stp q0, q0, [x0] 719; NONEON-NOSVE-NEXT: ret 720 %insert = insertelement <4 x double> undef, double 7.0, i64 0 721 %splat = shufflevector <4 x double> %insert, <4 x double> undef, <4 x i32> zeroinitializer 722 store <4 x double> %splat, ptr %a 723 ret void 724} 725