738 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 42; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5; ===== Legal Vector Types =====6 7define <8 x i8> @shufflevector_v8i8(<8 x i8> %a, <8 x i8> %b) {8; CHECK-SD-LABEL: shufflevector_v8i8:9; CHECK-SD: // %bb.0:10; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q011; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q112; CHECK-SD-NEXT: adrp x8, .LCPI0_013; CHECK-SD-NEXT: mov v0.d[1], v1.d[0]14; CHECK-SD-NEXT: ldr d1, [x8, :lo12:.LCPI0_0]15; CHECK-SD-NEXT: tbl v0.8b, { v0.16b }, v1.8b16; CHECK-SD-NEXT: ret17;18; CHECK-GI-LABEL: shufflevector_v8i8:19; CHECK-GI: // %bb.0:20; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q021; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q122; CHECK-GI-NEXT: adrp x8, .LCPI0_023; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]24; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI0_0]25; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b26; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q027; CHECK-GI-NEXT: ret28 %c = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12, i32 15>29 ret <8 x i8> %c30}31 32define <16 x i8> @shufflevector_v16i8(<16 x i8> %a, <16 x i8> %b) {33; CHECK-SD-LABEL: shufflevector_v16i8:34; CHECK-SD: // %bb.0:35; CHECK-SD-NEXT: adrp x8, .LCPI1_036; CHECK-SD-NEXT: // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q137; CHECK-SD-NEXT: ldr q2, [x8, :lo12:.LCPI1_0]38; CHECK-SD-NEXT: // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q139; CHECK-SD-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b40; CHECK-SD-NEXT: ret41;42; CHECK-GI-LABEL: shufflevector_v16i8:43; CHECK-GI: // %bb.0:44; CHECK-GI-NEXT: adrp x8, .LCPI1_045; CHECK-GI-NEXT: // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q146; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI1_0]47; CHECK-GI-NEXT: // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q148; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b49; CHECK-GI-NEXT: ret50 %c = shufflevector <16 x i8> %a, <16 x i8> %b, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12, i32 15, i32 2, i32 4, i32 6, i32 8, i32 25, i32 30, i32 31, i32 31>51 ret <16 x i8> %c52}53 54define <4 x i16> @shufflevector_v4i16(<4 x i16> %a, <4 x i16> %b) {55; CHECK-LABEL: shufflevector_v4i16:56; CHECK: // %bb.0:57; CHECK-NEXT: uzp2 v0.4h, v0.4h, v1.4h58; CHECK-NEXT: ret59 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 1, i32 3, i32 5, i32 7>60 ret <4 x i16> %c61}62 63define <8 x i16> @shufflevector_v8i16(<8 x i16> %a, <8 x i16> %b) {64; CHECK-SD-LABEL: shufflevector_v8i16:65; CHECK-SD: // %bb.0:66; CHECK-SD-NEXT: adrp x8, .LCPI3_067; CHECK-SD-NEXT: // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q168; CHECK-SD-NEXT: ldr q2, [x8, :lo12:.LCPI3_0]69; CHECK-SD-NEXT: // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q170; CHECK-SD-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b71; CHECK-SD-NEXT: ret72;73; CHECK-GI-LABEL: shufflevector_v8i16:74; CHECK-GI: // %bb.0:75; CHECK-GI-NEXT: adrp x8, .LCPI3_076; CHECK-GI-NEXT: // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q177; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI3_0]78; CHECK-GI-NEXT: // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q179; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b80; CHECK-GI-NEXT: ret81 %c = shufflevector <8 x i16> %a, <8 x i16> %b, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12, i32 15>82 ret <8 x i16> %c83}84 85define <2 x i32> @shufflevector_v2i32(<2 x i32> %a, <2 x i32> %b) {86; CHECK-LABEL: shufflevector_v2i32:87; CHECK: // %bb.0:88; CHECK-NEXT: zip2 v0.2s, v0.2s, v1.2s89; CHECK-NEXT: ret90 %c = shufflevector <2 x i32> %a, <2 x i32> %b, <2 x i32> <i32 1, i32 3>91 ret <2 x i32> %c92}93 94define <4 x i32> @shufflevector_v4i32(<4 x i32> %a, <4 x i32> %b) {95; CHECK-LABEL: shufflevector_v4i32:96; CHECK: // %bb.0:97; CHECK-NEXT: uzp2 v0.4s, v0.4s, v1.4s98; CHECK-NEXT: ret99 %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 1, i32 3, i32 5, i32 7>100 ret <4 x i32> %c101}102 103define <2 x i64> @shufflevector_v2i64(<2 x i64> %a, <2 x i64> %b) {104; CHECK-LABEL: shufflevector_v2i64:105; CHECK: // %bb.0:106; CHECK-NEXT: zip2 v0.2d, v0.2d, v1.2d107; CHECK-NEXT: ret108 %c = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 1, i32 3>109 ret <2 x i64> %c110}111 112define <2 x ptr> @shufflevector_v2p0(<2 x ptr> %a, <2 x ptr> %b) {113; CHECK-LABEL: shufflevector_v2p0:114; CHECK: // %bb.0:115; CHECK-NEXT: zip2 v0.2d, v0.2d, v1.2d116; CHECK-NEXT: ret117 %c = shufflevector <2 x ptr> %a, <2 x ptr> %b, <2 x i32> <i32 1, i32 3>118 ret <2 x ptr> %c119}120 121; ===== Legal Vector Types with Zero Masks =====122 123define <8 x i8> @shufflevector_v8i8_zeroes(<8 x i8> %a, <8 x i8> %b) {124; CHECK-LABEL: shufflevector_v8i8_zeroes:125; CHECK: // %bb.0:126; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0127; CHECK-NEXT: dup v0.8b, v0.b[0]128; CHECK-NEXT: ret129 %c = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>130 ret <8 x i8> %c131}132 133define <16 x i8> @shufflevector_v16i8_zeroes(<16 x i8> %a, <16 x i8> %b) {134; CHECK-LABEL: shufflevector_v16i8_zeroes:135; CHECK: // %bb.0:136; CHECK-NEXT: dup v0.16b, v0.b[0]137; CHECK-NEXT: ret138 %c = shufflevector <16 x i8> %a, <16 x i8> %b, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>139 ret <16 x i8> %c140}141 142define <4 x i16> @shufflevector_v4i16_zeroes(<4 x i16> %a, <4 x i16> %b) {143; CHECK-LABEL: shufflevector_v4i16_zeroes:144; CHECK: // %bb.0:145; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0146; CHECK-NEXT: dup v0.4h, v0.h[0]147; CHECK-NEXT: ret148 %c = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 0, i32 0, i32 0, i32 0>149 ret <4 x i16> %c150}151 152define <8 x i16> @shufflevector_v8i16_zeroes(<8 x i16> %a, <8 x i16> %b) {153; CHECK-LABEL: shufflevector_v8i16_zeroes:154; CHECK: // %bb.0:155; CHECK-NEXT: dup v0.8h, v0.h[0]156; CHECK-NEXT: ret157 %c = shufflevector <8 x i16> %a, <8 x i16> %b, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>158 ret <8 x i16> %c159}160 161define <2 x i32> @shufflevector_v2i32_zeroes(<2 x i32> %a, <2 x i32> %b) {162; CHECK-LABEL: shufflevector_v2i32_zeroes:163; CHECK: // %bb.0:164; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0165; CHECK-NEXT: dup v0.2s, v0.s[0]166; CHECK-NEXT: ret167 %c = shufflevector <2 x i32> %a, <2 x i32> %b, <2 x i32> <i32 0, i32 0>168 ret <2 x i32> %c169}170 171define <4 x i32> @shufflevector_v4i32_zeroes(<4 x i32> %a, <4 x i32> %b) {172; CHECK-LABEL: shufflevector_v4i32_zeroes:173; CHECK: // %bb.0:174; CHECK-NEXT: dup v0.4s, v0.s[0]175; CHECK-NEXT: ret176 %c = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 0, i32 0, i32 0>177 ret <4 x i32> %c178}179 180define <2 x i64> @shufflevector_v2i64_zeroes(<2 x i64> %a, <2 x i64> %b) {181; CHECK-LABEL: shufflevector_v2i64_zeroes:182; CHECK: // %bb.0:183; CHECK-NEXT: dup v0.2d, v0.d[0]184; CHECK-NEXT: ret185 %c = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 0, i32 0>186 ret <2 x i64> %c187}188 189define <2 x ptr> @shufflevector_v2p0_zeroes(<2 x ptr> %a, <2 x ptr> %b) {190; CHECK-LABEL: shufflevector_v2p0_zeroes:191; CHECK: // %bb.0:192; CHECK-NEXT: dup v0.2d, v0.d[0]193; CHECK-NEXT: ret194 %c = shufflevector <2 x ptr> %a, <2 x ptr> %b, <2 x i32> <i32 0, i32 0>195 ret <2 x ptr> %c196}197 198; ===== Smaller/Larger Width Vectors with Legal Element Sizes =====199 200define <2 x i1> @shufflevector_v2i1(<2 x i1> %a, <2 x i1> %b){201; CHECK-SD-LABEL: shufflevector_v2i1:202; CHECK-SD: // %bb.0:203; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0204; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1205; CHECK-SD-NEXT: mov v0.s[1], v1.s[1]206; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0207; CHECK-SD-NEXT: ret208;209; CHECK-GI-LABEL: shufflevector_v2i1:210; CHECK-GI: // %bb.0:211; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0212; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1213; CHECK-GI-NEXT: mov w8, v0.s[1]214; CHECK-GI-NEXT: mov w9, v1.s[1]215; CHECK-GI-NEXT: mov v0.b[1], w8216; CHECK-GI-NEXT: mov v1.b[1], w9217; CHECK-GI-NEXT: mov v0.b[1], v1.b[1]218; CHECK-GI-NEXT: umov w8, v0.b[0]219; CHECK-GI-NEXT: umov w9, v0.b[1]220; CHECK-GI-NEXT: fmov s0, w8221; CHECK-GI-NEXT: mov v0.s[1], w9222; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0223; CHECK-GI-NEXT: ret224 %c = shufflevector <2 x i1> %a, <2 x i1> %b, <2 x i32> <i32 0, i32 3>225 ret <2 x i1> %c226}227 228define i32 @shufflevector_v4i8(<4 x i8> %a, <4 x i8> %b){229; CHECK-SD-LABEL: shufflevector_v4i8:230; CHECK-SD: // %bb.0:231; CHECK-SD-NEXT: sub sp, sp, #16232; CHECK-SD-NEXT: .cfi_def_cfa_offset 16233; CHECK-SD-NEXT: ext v0.8b, v1.8b, v0.8b, #6234; CHECK-SD-NEXT: zip1 v1.4h, v1.4h, v0.4h235; CHECK-SD-NEXT: ext v0.8b, v0.8b, v1.8b, #4236; CHECK-SD-NEXT: uzp1 v0.8b, v0.8b, v0.8b237; CHECK-SD-NEXT: fmov w0, s0238; CHECK-SD-NEXT: add sp, sp, #16239; CHECK-SD-NEXT: ret240;241; CHECK-GI-LABEL: shufflevector_v4i8:242; CHECK-GI: // %bb.0:243; CHECK-GI-NEXT: uzp1 v0.8b, v0.8b, v0.8b244; CHECK-GI-NEXT: adrp x8, .LCPI17_0245; CHECK-GI-NEXT: uzp1 v1.8b, v1.8b, v0.8b246; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]247; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI17_0]248; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b249; CHECK-GI-NEXT: fmov w0, s0250; CHECK-GI-NEXT: ret251 %c = shufflevector <4 x i8> %a, <4 x i8> %b, <4 x i32> <i32 1, i32 2, i32 4, i32 7>252 %d = bitcast <4 x i8> %c to i32253 ret i32 %d254}255 256define <32 x i8> @shufflevector_v32i8(<32 x i8> %a, <32 x i8> %b){257; CHECK-SD-LABEL: shufflevector_v32i8:258; CHECK-SD: // %bb.0:259; CHECK-SD-NEXT: // kill: def $q2 killed $q2 def $q1_q2260; CHECK-SD-NEXT: adrp x8, .LCPI18_0261; CHECK-SD-NEXT: adrp x9, .LCPI18_1262; CHECK-SD-NEXT: mov v1.16b, v0.16b263; CHECK-SD-NEXT: ldr q3, [x8, :lo12:.LCPI18_0]264; CHECK-SD-NEXT: ldr q4, [x9, :lo12:.LCPI18_1]265; CHECK-SD-NEXT: tbl v0.16b, { v1.16b, v2.16b }, v3.16b266; CHECK-SD-NEXT: tbl v1.16b, { v1.16b, v2.16b }, v4.16b267; CHECK-SD-NEXT: ret268;269; CHECK-GI-LABEL: shufflevector_v32i8:270; CHECK-GI: // %bb.0:271; CHECK-GI-NEXT: mov v3.16b, v0.16b272; CHECK-GI-NEXT: adrp x8, .LCPI18_1273; CHECK-GI-NEXT: adrp x9, .LCPI18_0274; CHECK-GI-NEXT: mov v4.16b, v2.16b275; CHECK-GI-NEXT: ldr q0, [x8, :lo12:.LCPI18_1]276; CHECK-GI-NEXT: ldr q1, [x9, :lo12:.LCPI18_0]277; CHECK-GI-NEXT: tbl v0.16b, { v3.16b, v4.16b }, v0.16b278; CHECK-GI-NEXT: tbl v1.16b, { v3.16b, v4.16b }, v1.16b279; CHECK-GI-NEXT: ret280 %c = shufflevector <32 x i8> %a, <32 x i8> %b, <32 x i32> <i32 0, i32 32, i32 32, i32 32, i32 1, i32 32, i32 32, i32 32, i32 2, i32 32, i32 32, i32 32, i32 3, i32 32, i32 32, i32 32, i32 4, i32 32, i32 32, i32 32, i32 5, i32 32, i32 32, i32 32, i32 6, i32 32, i32 32, i32 32, i32 7, i32 32, i32 32, i32 32>281 ret <32 x i8> %c282}283 284define i32 @shufflevector_v2i16(<2 x i16> %a, <2 x i16> %b){285; CHECK-SD-LABEL: shufflevector_v2i16:286; CHECK-SD: // %bb.0:287; CHECK-SD-NEXT: sub sp, sp, #16288; CHECK-SD-NEXT: .cfi_def_cfa_offset 16289; CHECK-SD-NEXT: ext v0.8b, v0.8b, v1.8b, #4290; CHECK-SD-NEXT: mov s1, v0.s[1]291; CHECK-SD-NEXT: str h0, [sp, #12]292; CHECK-SD-NEXT: str h1, [sp, #14]293; CHECK-SD-NEXT: ldr w0, [sp, #12]294; CHECK-SD-NEXT: add sp, sp, #16295; CHECK-SD-NEXT: ret296;297; CHECK-GI-LABEL: shufflevector_v2i16:298; CHECK-GI: // %bb.0:299; CHECK-GI-NEXT: uzp1 v0.4h, v0.4h, v0.4h300; CHECK-GI-NEXT: adrp x8, .LCPI19_0301; CHECK-GI-NEXT: uzp1 v1.4h, v1.4h, v0.4h302; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]303; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI19_0]304; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b305; CHECK-GI-NEXT: fmov w0, s0306; CHECK-GI-NEXT: ret307 %c = shufflevector <2 x i16> %a, <2 x i16> %b, <2 x i32> <i32 1, i32 2>308 %d = bitcast <2 x i16> %c to i32309 ret i32 %d310}311 312define <16 x i16> @shufflevector_v16i16(<16 x i16> %a, <16 x i16> %b){313; CHECK-SD-LABEL: shufflevector_v16i16:314; CHECK-SD: // %bb.0:315; CHECK-SD-NEXT: // kill: def $q2 killed $q2 def $q1_q2316; CHECK-SD-NEXT: adrp x8, .LCPI20_0317; CHECK-SD-NEXT: adrp x9, .LCPI20_1318; CHECK-SD-NEXT: mov v1.16b, v0.16b319; CHECK-SD-NEXT: ldr q3, [x8, :lo12:.LCPI20_0]320; CHECK-SD-NEXT: ldr q4, [x9, :lo12:.LCPI20_1]321; CHECK-SD-NEXT: tbl v0.16b, { v1.16b, v2.16b }, v3.16b322; CHECK-SD-NEXT: tbl v1.16b, { v1.16b, v2.16b }, v4.16b323; CHECK-SD-NEXT: ret324;325; CHECK-GI-LABEL: shufflevector_v16i16:326; CHECK-GI: // %bb.0:327; CHECK-GI-NEXT: mov v3.16b, v0.16b328; CHECK-GI-NEXT: adrp x8, .LCPI20_1329; CHECK-GI-NEXT: adrp x9, .LCPI20_0330; CHECK-GI-NEXT: mov v4.16b, v2.16b331; CHECK-GI-NEXT: ldr q0, [x8, :lo12:.LCPI20_1]332; CHECK-GI-NEXT: ldr q1, [x9, :lo12:.LCPI20_0]333; CHECK-GI-NEXT: tbl v0.16b, { v3.16b, v4.16b }, v0.16b334; CHECK-GI-NEXT: tbl v1.16b, { v3.16b, v4.16b }, v1.16b335; CHECK-GI-NEXT: ret336 %c = shufflevector <16 x i16> %a, <16 x i16> %b, <16 x i32> <i32 0, i32 16, i32 16, i32 16, i32 1, i32 16, i32 16, i32 16, i32 1, i32 16, i32 16, i32 16, i32 3, i32 16, i32 16, i32 16>337 ret <16 x i16> %c338}339 340define <1 x i32> @shufflevector_v1i32(<1 x i32> %a, <1 x i32> %b) {341; CHECK-LABEL: shufflevector_v1i32:342; CHECK: // %bb.0:343; CHECK-NEXT: fmov d0, d1344; CHECK-NEXT: ret345 %c = shufflevector <1 x i32> %a, <1 x i32> %b, <1 x i32> <i32 1>346 ret <1 x i32> %c347}348 349define <8 x i32> @shufflevector_v8i32(<8 x i32> %a, <8 x i32> %b) {350; CHECK-SD-LABEL: shufflevector_v8i32:351; CHECK-SD: // %bb.0:352; CHECK-SD-NEXT: uzp1 v2.4s, v2.4s, v3.4s353; CHECK-SD-NEXT: uzp2 v0.4s, v0.4s, v1.4s354; CHECK-SD-NEXT: mov v2.s[3], v3.s[3]355; CHECK-SD-NEXT: mov v1.16b, v2.16b356; CHECK-SD-NEXT: ret357;358; CHECK-GI-LABEL: shufflevector_v8i32:359; CHECK-GI: // %bb.0:360; CHECK-GI-NEXT: adrp x8, .LCPI22_0361; CHECK-GI-NEXT: // kill: def $q2 killed $q2 killed $q2_q3 def $q2_q3362; CHECK-GI-NEXT: uzp2 v0.4s, v0.4s, v1.4s363; CHECK-GI-NEXT: ldr q4, [x8, :lo12:.LCPI22_0]364; CHECK-GI-NEXT: // kill: def $q3 killed $q3 killed $q2_q3 def $q2_q3365; CHECK-GI-NEXT: tbl v1.16b, { v2.16b, v3.16b }, v4.16b366; CHECK-GI-NEXT: ret367 %c = shufflevector <8 x i32> %a, <8 x i32> %b, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12, i32 15>368 ret <8 x i32> %c369}370 371define <4 x i64> @shufflevector_v4i64(<4 x i64> %a, <4 x i64> %b) {372; CHECK-SD-LABEL: shufflevector_v4i64:373; CHECK-SD: // %bb.0:374; CHECK-SD-NEXT: zip2 v2.2d, v2.2d, v3.2d375; CHECK-SD-NEXT: zip2 v0.2d, v0.2d, v1.2d376; CHECK-SD-NEXT: mov v1.16b, v2.16b377; CHECK-SD-NEXT: ret378;379; CHECK-GI-LABEL: shufflevector_v4i64:380; CHECK-GI: // %bb.0:381; CHECK-GI-NEXT: zip2 v0.2d, v0.2d, v1.2d382; CHECK-GI-NEXT: zip2 v1.2d, v2.2d, v3.2d383; CHECK-GI-NEXT: ret384 %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 1, i32 3, i32 5, i32 7>385 ret <4 x i64> %c386}387 388define <3 x ptr> @shufflevector_v3p0(<3 x ptr> %a, <3 x ptr> %b) {389; CHECK-SD-LABEL: shufflevector_v3p0:390; CHECK-SD: // %bb.0:391; CHECK-SD-NEXT: fmov d2, d5392; CHECK-SD-NEXT: fmov d0, d1393; CHECK-SD-NEXT: fmov d1, d3394; CHECK-SD-NEXT: ret395;396; CHECK-GI-LABEL: shufflevector_v3p0:397; CHECK-GI: // %bb.0:398; CHECK-GI-NEXT: fmov x8, d1399; CHECK-GI-NEXT: fmov x9, d4400; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0401; CHECK-GI-NEXT: // kill: def $d3 killed $d3 def $q3402; CHECK-GI-NEXT: // kill: def $d5 killed $d5 def $q5403; CHECK-GI-NEXT: dup v2.2d, v5.d[0]404; CHECK-GI-NEXT: mov v0.d[1], x8405; CHECK-GI-NEXT: mov v3.d[1], x9406; CHECK-GI-NEXT: ext v0.16b, v0.16b, v3.16b, #8407; CHECK-GI-NEXT: mov d1, v0.d[1]408; CHECK-GI-NEXT: ret409 %c = shufflevector <3 x ptr> %a, <3 x ptr> %b, <3 x i32> <i32 1, i32 3, i32 5>410 ret <3 x ptr> %c411}412 413define <4 x ptr> @shufflevector_v4p0(<4 x ptr> %a, <4 x ptr> %b) {414; CHECK-SD-LABEL: shufflevector_v4p0:415; CHECK-SD: // %bb.0:416; CHECK-SD-NEXT: zip2 v2.2d, v2.2d, v3.2d417; CHECK-SD-NEXT: zip2 v0.2d, v0.2d, v1.2d418; CHECK-SD-NEXT: mov v1.16b, v2.16b419; CHECK-SD-NEXT: ret420;421; CHECK-GI-LABEL: shufflevector_v4p0:422; CHECK-GI: // %bb.0:423; CHECK-GI-NEXT: zip2 v0.2d, v0.2d, v1.2d424; CHECK-GI-NEXT: zip2 v1.2d, v2.2d, v3.2d425; CHECK-GI-NEXT: ret426 %c = shufflevector <4 x ptr> %a, <4 x ptr> %b, <4 x i32> <i32 1, i32 3, i32 5, i32 7>427 ret <4 x ptr> %c428}429 430; ===== Smaller/Larger Width Vectors with Zero Masks =====431 432define <2 x i1> @shufflevector_v2i1_zeroes(<2 x i1> %a, <2 x i1> %b){433; CHECK-SD-LABEL: shufflevector_v2i1_zeroes:434; CHECK-SD: // %bb.0:435; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0436; CHECK-SD-NEXT: dup v0.2s, v0.s[0]437; CHECK-SD-NEXT: ret438;439; CHECK-GI-LABEL: shufflevector_v2i1_zeroes:440; CHECK-GI: // %bb.0:441; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0442; CHECK-GI-NEXT: mov w8, v0.s[1]443; CHECK-GI-NEXT: mov v0.b[1], w8444; CHECK-GI-NEXT: dup v0.8b, v0.b[0]445; CHECK-GI-NEXT: umov w8, v0.b[0]446; CHECK-GI-NEXT: umov w9, v0.b[1]447; CHECK-GI-NEXT: fmov s0, w8448; CHECK-GI-NEXT: mov v0.s[1], w9449; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0450; CHECK-GI-NEXT: ret451 %c = shufflevector <2 x i1> %a, <2 x i1> %b, <2 x i32> <i32 0, i32 0>452 ret <2 x i1> %c453}454 455define i32 @shufflevector_v4i8_zeroes(<4 x i8> %a, <4 x i8> %b){456; CHECK-SD-LABEL: shufflevector_v4i8_zeroes:457; CHECK-SD: // %bb.0:458; CHECK-SD-NEXT: sub sp, sp, #16459; CHECK-SD-NEXT: .cfi_def_cfa_offset 16460; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0461; CHECK-SD-NEXT: dup v0.4h, v0.h[0]462; CHECK-SD-NEXT: uzp1 v0.8b, v0.8b, v0.8b463; CHECK-SD-NEXT: fmov w0, s0464; CHECK-SD-NEXT: add sp, sp, #16465; CHECK-SD-NEXT: ret466;467; CHECK-GI-LABEL: shufflevector_v4i8_zeroes:468; CHECK-GI: // %bb.0:469; CHECK-GI-NEXT: uzp1 v0.8b, v0.8b, v0.8b470; CHECK-GI-NEXT: dup v0.8b, v0.b[0]471; CHECK-GI-NEXT: fmov w0, s0472; CHECK-GI-NEXT: ret473 %c = shufflevector <4 x i8> %a, <4 x i8> %b, <4 x i32> <i32 0, i32 0, i32 0, i32 0>474 %d = bitcast <4 x i8> %c to i32475 ret i32 %d476}477 478define <32 x i8> @shufflevector_v32i8_zeroes(<32 x i8> %a, <32 x i8> %b){479; CHECK-LABEL: shufflevector_v32i8_zeroes:480; CHECK: // %bb.0:481; CHECK-NEXT: dup v0.16b, v0.b[0]482; CHECK-NEXT: mov v1.16b, v0.16b483; CHECK-NEXT: ret484 %c = shufflevector <32 x i8> %a, <32 x i8> %b, <32 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>485 ret <32 x i8> %c486}487 488define i32 @shufflevector_v2i16_zeroes(<2 x i16> %a, <2 x i16> %b){489; CHECK-SD-LABEL: shufflevector_v2i16_zeroes:490; CHECK-SD: // %bb.0:491; CHECK-SD-NEXT: sub sp, sp, #16492; CHECK-SD-NEXT: .cfi_def_cfa_offset 16493; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0494; CHECK-SD-NEXT: dup v1.2s, v0.s[0]495; CHECK-SD-NEXT: str h0, [sp, #12]496; CHECK-SD-NEXT: mov s1, v1.s[1]497; CHECK-SD-NEXT: str h1, [sp, #14]498; CHECK-SD-NEXT: ldr w0, [sp, #12]499; CHECK-SD-NEXT: add sp, sp, #16500; CHECK-SD-NEXT: ret501;502; CHECK-GI-LABEL: shufflevector_v2i16_zeroes:503; CHECK-GI: // %bb.0:504; CHECK-GI-NEXT: uzp1 v0.4h, v0.4h, v0.4h505; CHECK-GI-NEXT: dup v0.4h, v0.h[0]506; CHECK-GI-NEXT: fmov w0, s0507; CHECK-GI-NEXT: ret508 %c = shufflevector <2 x i16> %a, <2 x i16> %b, <2 x i32> <i32 0, i32 0>509 %d = bitcast <2 x i16> %c to i32510 ret i32 %d511}512 513define <16 x i16> @shufflevector_v16i16_zeroes(<16 x i16> %a, <16 x i16> %b){514; CHECK-LABEL: shufflevector_v16i16_zeroes:515; CHECK: // %bb.0:516; CHECK-NEXT: dup v0.8h, v0.h[0]517; CHECK-NEXT: mov v1.16b, v0.16b518; CHECK-NEXT: ret519 %c = shufflevector <16 x i16> %a, <16 x i16> %b, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>520 ret <16 x i16> %c521}522 523define <1 x i32> @shufflevector_v1i32_zeroes(<1 x i32> %a, <1 x i32> %b) {524; CHECK-LABEL: shufflevector_v1i32_zeroes:525; CHECK: // %bb.0:526; CHECK-NEXT: ret527 %c = shufflevector <1 x i32> %a, <1 x i32> %b, <1 x i32> <i32 0>528 ret <1 x i32> %c529}530 531define <8 x i32> @shufflevector_v8i32_zeroes(<8 x i32> %a, <8 x i32> %b) {532; CHECK-LABEL: shufflevector_v8i32_zeroes:533; CHECK: // %bb.0:534; CHECK-NEXT: dup v0.4s, v0.s[0]535; CHECK-NEXT: mov v1.16b, v0.16b536; CHECK-NEXT: ret537 %c = shufflevector <8 x i32> %a, <8 x i32> %b, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>538 ret <8 x i32> %c539}540 541define <4 x i64> @shufflevector_v4i64_zeroes(<4 x i64> %a, <4 x i64> %b) {542; CHECK-LABEL: shufflevector_v4i64_zeroes:543; CHECK: // %bb.0:544; CHECK-NEXT: dup v0.2d, v0.d[0]545; CHECK-NEXT: mov v1.16b, v0.16b546; CHECK-NEXT: ret547 %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 0, i32 0, i32 0, i32 0>548 ret <4 x i64> %c549}550 551define <4 x ptr> @shufflevector_v4p0_zeroes(<4 x ptr> %a, <4 x ptr> %b) {552; CHECK-LABEL: shufflevector_v4p0_zeroes:553; CHECK: // %bb.0:554; CHECK-NEXT: dup v0.2d, v0.d[0]555; CHECK-NEXT: mov v1.16b, v0.16b556; CHECK-NEXT: ret557 %c = shufflevector <4 x ptr> %a, <4 x ptr> %b, <4 x i32> <i32 0, i32 0, i32 0, i32 0>558 ret <4 x ptr> %c559}560 561; ===== Vectors with Non-Pow 2 Widths =====562 563define <3 x i8> @shufflevector_v3i8(<3 x i8> %a, <3 x i8> %b) {564; CHECK-SD-LABEL: shufflevector_v3i8:565; CHECK-SD: // %bb.0:566; CHECK-SD-NEXT: mov w0, w1567; CHECK-SD-NEXT: mov w1, w2568; CHECK-SD-NEXT: mov w2, w4569; CHECK-SD-NEXT: ret570;571; CHECK-GI-LABEL: shufflevector_v3i8:572; CHECK-GI: // %bb.0:573; CHECK-GI-NEXT: fmov s0, w0574; CHECK-GI-NEXT: fmov s1, w3575; CHECK-GI-NEXT: adrp x8, .LCPI35_0576; CHECK-GI-NEXT: mov v0.b[1], w1577; CHECK-GI-NEXT: mov v1.b[1], w4578; CHECK-GI-NEXT: mov v0.b[2], w2579; CHECK-GI-NEXT: mov v1.b[2], w5580; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]581; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI35_0]582; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b583; CHECK-GI-NEXT: umov w0, v0.b[0]584; CHECK-GI-NEXT: umov w1, v0.b[1]585; CHECK-GI-NEXT: umov w2, v0.b[2]586; CHECK-GI-NEXT: ret587 %c = shufflevector <3 x i8> %a, <3 x i8> %b, <3 x i32> <i32 1, i32 2, i32 4>588 ret <3 x i8> %c589}590 591define <7 x i8> @shufflevector_v7i8(<7 x i8> %a, <7 x i8> %b) {592; CHECK-SD-LABEL: shufflevector_v7i8:593; CHECK-SD: // %bb.0:594; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0595; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1596; CHECK-SD-NEXT: adrp x8, .LCPI36_0597; CHECK-SD-NEXT: mov v0.d[1], v1.d[0]598; CHECK-SD-NEXT: ldr d1, [x8, :lo12:.LCPI36_0]599; CHECK-SD-NEXT: tbl v0.8b, { v0.16b }, v1.8b600; CHECK-SD-NEXT: ret601;602; CHECK-GI-LABEL: shufflevector_v7i8:603; CHECK-GI: // %bb.0:604; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0605; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1606; CHECK-GI-NEXT: adrp x8, .LCPI36_0607; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]608; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI36_0]609; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b610; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0611; CHECK-GI-NEXT: ret612 %c = shufflevector <7 x i8> %a, <7 x i8> %b, <7 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12>613 ret <7 x i8> %c614}615 616define <3 x i16> @shufflevector_v3i16(<3 x i16> %a, <3 x i16> %b) {617; CHECK-SD-LABEL: shufflevector_v3i16:618; CHECK-SD: // %bb.0:619; CHECK-SD-NEXT: zip1 v1.4h, v0.4h, v1.4h620; CHECK-SD-NEXT: zip2 v0.4h, v1.4h, v0.4h621; CHECK-SD-NEXT: ret622;623; CHECK-GI-LABEL: shufflevector_v3i16:624; CHECK-GI: // %bb.0:625; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0626; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1627; CHECK-GI-NEXT: adrp x8, .LCPI37_0628; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]629; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI37_0]630; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b631; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0632; CHECK-GI-NEXT: ret633 %c = shufflevector <3 x i16> %a, <3 x i16> %b, <3 x i32> <i32 1, i32 2, i32 4>634 ret <3 x i16> %c635}636 637define <7 x i16> @shufflevector_v7i16(<7 x i16> %a, <7 x i16> %b) {638; CHECK-SD-LABEL: shufflevector_v7i16:639; CHECK-SD: // %bb.0:640; CHECK-SD-NEXT: adrp x8, .LCPI38_0641; CHECK-SD-NEXT: // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1642; CHECK-SD-NEXT: ldr q2, [x8, :lo12:.LCPI38_0]643; CHECK-SD-NEXT: // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1644; CHECK-SD-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b645; CHECK-SD-NEXT: ret646;647; CHECK-GI-LABEL: shufflevector_v7i16:648; CHECK-GI: // %bb.0:649; CHECK-GI-NEXT: adrp x8, .LCPI38_0650; CHECK-GI-NEXT: // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1651; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI38_0]652; CHECK-GI-NEXT: // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1653; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b654; CHECK-GI-NEXT: ret655 %c = shufflevector <7 x i16> %a, <7 x i16> %b, <7 x i32> <i32 1, i32 3, i32 5, i32 7, i32 8, i32 10, i32 12>656 ret <7 x i16> %c657}658 659define <3 x i32> @shufflevector_v3i32(<3 x i32> %a, <3 x i32> %b) {660; CHECK-SD-LABEL: shufflevector_v3i32:661; CHECK-SD: // %bb.0:662; CHECK-SD-NEXT: zip1 v1.4s, v0.4s, v1.4s663; CHECK-SD-NEXT: zip2 v0.4s, v1.4s, v0.4s664; CHECK-SD-NEXT: ret665;666; CHECK-GI-LABEL: shufflevector_v3i32:667; CHECK-GI: // %bb.0:668; CHECK-GI-NEXT: adrp x8, .LCPI39_0669; CHECK-GI-NEXT: // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1670; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI39_0]671; CHECK-GI-NEXT: // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1672; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b673; CHECK-GI-NEXT: ret674 %c = shufflevector <3 x i32> %a, <3 x i32> %b, <3 x i32> <i32 1, i32 2, i32 4>675 ret <3 x i32> %c676}677 678; ===== Vectors with Non-Pow 2 Widths with Zero Masks =====679 680define <3 x i8> @shufflevector_v3i8_zeroes(<3 x i8> %a, <3 x i8> %b) {681; CHECK-SD-LABEL: shufflevector_v3i8_zeroes:682; CHECK-SD: // %bb.0:683; CHECK-SD-NEXT: mov w1, w0684; CHECK-SD-NEXT: mov w2, w0685; CHECK-SD-NEXT: ret686;687; CHECK-GI-LABEL: shufflevector_v3i8_zeroes:688; CHECK-GI: // %bb.0:689; CHECK-GI-NEXT: fmov s0, w0690; CHECK-GI-NEXT: mov v0.b[1], w1691; CHECK-GI-NEXT: mov v0.b[2], w2692; CHECK-GI-NEXT: dup v0.8b, v0.b[0]693; CHECK-GI-NEXT: umov w0, v0.b[0]694; CHECK-GI-NEXT: umov w1, v0.b[1]695; CHECK-GI-NEXT: umov w2, v0.b[2]696; CHECK-GI-NEXT: ret697 %c = shufflevector <3 x i8> %a, <3 x i8> %b, <3 x i32> <i32 0, i32 0, i32 0>698 ret <3 x i8> %c699}700 701define <7 x i8> @shufflevector_v7i8_zeroes(<7 x i8> %a, <7 x i8> %b) {702; CHECK-LABEL: shufflevector_v7i8_zeroes:703; CHECK: // %bb.0:704; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0705; CHECK-NEXT: dup v0.8b, v0.b[0]706; CHECK-NEXT: ret707 %c = shufflevector <7 x i8> %a, <7 x i8> %b, <7 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>708 ret <7 x i8> %c709}710 711define <3 x i16> @shufflevector_v3i16_zeroes(<3 x i16> %a, <3 x i16> %b) {712; CHECK-LABEL: shufflevector_v3i16_zeroes:713; CHECK: // %bb.0:714; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0715; CHECK-NEXT: dup v0.4h, v0.h[0]716; CHECK-NEXT: ret717 %c = shufflevector <3 x i16> %a, <3 x i16> %b, <3 x i32> <i32 0, i32 0, i32 0>718 ret <3 x i16> %c719}720 721define <7 x i16> @shufflevector_v7i16_zeroes(<7 x i16> %a, <7 x i16> %b) {722; CHECK-LABEL: shufflevector_v7i16_zeroes:723; CHECK: // %bb.0:724; CHECK-NEXT: dup v0.8h, v0.h[0]725; CHECK-NEXT: ret726 %c = shufflevector <7 x i16> %a, <7 x i16> %b, <7 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>727 ret <7 x i16> %c728}729 730define <3 x i32> @shufflevector_v3i32_zeroes(<3 x i32> %a, <3 x i32> %b) {731; CHECK-LABEL: shufflevector_v3i32_zeroes:732; CHECK: // %bb.0:733; CHECK-NEXT: dup v0.4s, v0.s[0]734; CHECK-NEXT: ret735 %c = shufflevector <3 x i32> %a, <3 x i32> %b, <3 x i32> <i32 0, i32 0, i32 0>736 ret <3 x i32> %c737}738