brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.7 KiB · 49fb6c9 Raw
711 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5define <8 x i8> @v_dup8(i8 %A) nounwind {6; CHECK-LABEL: v_dup8:7; CHECK:       // %bb.0:8; CHECK-NEXT:    dup.8b v0, w09; CHECK-NEXT:    ret10  %tmp1 = insertelement <8 x i8> zeroinitializer, i8 %A, i32 011  %tmp2 = insertelement <8 x i8> %tmp1, i8 %A, i32 112  %tmp3 = insertelement <8 x i8> %tmp2, i8 %A, i32 213  %tmp4 = insertelement <8 x i8> %tmp3, i8 %A, i32 314  %tmp5 = insertelement <8 x i8> %tmp4, i8 %A, i32 415  %tmp6 = insertelement <8 x i8> %tmp5, i8 %A, i32 516  %tmp7 = insertelement <8 x i8> %tmp6, i8 %A, i32 617  %tmp8 = insertelement <8 x i8> %tmp7, i8 %A, i32 718  ret <8 x i8> %tmp819}20 21define <4 x i16> @v_dup16(i16 %A) nounwind {22; CHECK-LABEL: v_dup16:23; CHECK:       // %bb.0:24; CHECK-NEXT:    dup.4h v0, w025; CHECK-NEXT:    ret26  %tmp1 = insertelement <4 x i16> zeroinitializer, i16 %A, i32 027  %tmp2 = insertelement <4 x i16> %tmp1, i16 %A, i32 128  %tmp3 = insertelement <4 x i16> %tmp2, i16 %A, i32 229  %tmp4 = insertelement <4 x i16> %tmp3, i16 %A, i32 330  ret <4 x i16> %tmp431}32 33define <2 x i32> @v_dup32(i32 %A) nounwind {34; CHECK-LABEL: v_dup32:35; CHECK:       // %bb.0:36; CHECK-NEXT:    dup.2s v0, w037; CHECK-NEXT:    ret38  %tmp1 = insertelement <2 x i32> zeroinitializer, i32 %A, i32 039  %tmp2 = insertelement <2 x i32> %tmp1, i32 %A, i32 140  ret <2 x i32> %tmp241}42 43define <2 x float> @v_dupfloat(float %A) nounwind {44; CHECK-LABEL: v_dupfloat:45; CHECK:       // %bb.0:46; CHECK-NEXT:    // kill: def $s0 killed $s0 def $q047; CHECK-NEXT:    dup.2s v0, v0[0]48; CHECK-NEXT:    ret49  %tmp1 = insertelement <2 x float> zeroinitializer, float %A, i32 050  %tmp2 = insertelement <2 x float> %tmp1, float %A, i32 151  ret <2 x float> %tmp252}53 54define <16 x i8> @v_dupQ8(i8 %A) nounwind {55; CHECK-LABEL: v_dupQ8:56; CHECK:       // %bb.0:57; CHECK-NEXT:    dup.16b v0, w058; CHECK-NEXT:    ret59  %tmp1 = insertelement <16 x i8> zeroinitializer, i8 %A, i32 060  %tmp2 = insertelement <16 x i8> %tmp1, i8 %A, i32 161  %tmp3 = insertelement <16 x i8> %tmp2, i8 %A, i32 262  %tmp4 = insertelement <16 x i8> %tmp3, i8 %A, i32 363  %tmp5 = insertelement <16 x i8> %tmp4, i8 %A, i32 464  %tmp6 = insertelement <16 x i8> %tmp5, i8 %A, i32 565  %tmp7 = insertelement <16 x i8> %tmp6, i8 %A, i32 666  %tmp8 = insertelement <16 x i8> %tmp7, i8 %A, i32 767  %tmp9 = insertelement <16 x i8> %tmp8, i8 %A, i32 868  %tmp10 = insertelement <16 x i8> %tmp9, i8 %A, i32 969  %tmp11 = insertelement <16 x i8> %tmp10, i8 %A, i32 1070  %tmp12 = insertelement <16 x i8> %tmp11, i8 %A, i32 1171  %tmp13 = insertelement <16 x i8> %tmp12, i8 %A, i32 1272  %tmp14 = insertelement <16 x i8> %tmp13, i8 %A, i32 1373  %tmp15 = insertelement <16 x i8> %tmp14, i8 %A, i32 1474  %tmp16 = insertelement <16 x i8> %tmp15, i8 %A, i32 1575  ret <16 x i8> %tmp1676}77 78define <8 x i16> @v_dupQ16(i16 %A) nounwind {79; CHECK-LABEL: v_dupQ16:80; CHECK:       // %bb.0:81; CHECK-NEXT:    dup.8h v0, w082; CHECK-NEXT:    ret83  %tmp1 = insertelement <8 x i16> zeroinitializer, i16 %A, i32 084  %tmp2 = insertelement <8 x i16> %tmp1, i16 %A, i32 185  %tmp3 = insertelement <8 x i16> %tmp2, i16 %A, i32 286  %tmp4 = insertelement <8 x i16> %tmp3, i16 %A, i32 387  %tmp5 = insertelement <8 x i16> %tmp4, i16 %A, i32 488  %tmp6 = insertelement <8 x i16> %tmp5, i16 %A, i32 589  %tmp7 = insertelement <8 x i16> %tmp6, i16 %A, i32 690  %tmp8 = insertelement <8 x i16> %tmp7, i16 %A, i32 791  ret <8 x i16> %tmp892}93 94define <4 x i32> @v_dupQ32(i32 %A) nounwind {95; CHECK-LABEL: v_dupQ32:96; CHECK:       // %bb.0:97; CHECK-NEXT:    dup.4s v0, w098; CHECK-NEXT:    ret99  %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %A, i32 0100  %tmp2 = insertelement <4 x i32> %tmp1, i32 %A, i32 1101  %tmp3 = insertelement <4 x i32> %tmp2, i32 %A, i32 2102  %tmp4 = insertelement <4 x i32> %tmp3, i32 %A, i32 3103  ret <4 x i32> %tmp4104}105 106define <4 x i16> @v_dup16_const(i16 %y, ptr %p) {107; CHECK-LABEL: v_dup16_const:108; CHECK:       // %bb.0:109; CHECK-NEXT:    movi.4h v0, #10110; CHECK-NEXT:    mov w8, #10 // =0xa111; CHECK-NEXT:    strh w8, [x1]112; CHECK-NEXT:    ret113    %i = insertelement <4 x i16> undef, i16 10, i32 0114    %lo = shufflevector <4 x i16> %i, <4 x i16> undef, <4 x i32> zeroinitializer115    store i16 10, ptr %p116    ret <4 x i16> %lo117}118 119define <4 x float> @v_dupQfloat(float %A) nounwind {120; CHECK-LABEL: v_dupQfloat:121; CHECK:       // %bb.0:122; CHECK-NEXT:    // kill: def $s0 killed $s0 def $q0123; CHECK-NEXT:    dup.4s v0, v0[0]124; CHECK-NEXT:    ret125  %tmp1 = insertelement <4 x float> zeroinitializer, float %A, i32 0126  %tmp2 = insertelement <4 x float> %tmp1, float %A, i32 1127  %tmp3 = insertelement <4 x float> %tmp2, float %A, i32 2128  %tmp4 = insertelement <4 x float> %tmp3, float %A, i32 3129  ret <4 x float> %tmp4130}131 132; Check to make sure it works with shuffles, too.133 134define <8 x i8> @v_shuffledup8(i8 %A) nounwind {135; CHECK-LABEL: v_shuffledup8:136; CHECK:       // %bb.0:137; CHECK-NEXT:    dup.8b v0, w0138; CHECK-NEXT:    ret139  %tmp1 = insertelement <8 x i8> undef, i8 %A, i32 0140  %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> zeroinitializer141  ret <8 x i8> %tmp2142}143 144define <4 x i16> @v_shuffledup16(i16 %A) nounwind {145; CHECK-LABEL: v_shuffledup16:146; CHECK:       // %bb.0:147; CHECK-NEXT:    dup.4h v0, w0148; CHECK-NEXT:    ret149  %tmp1 = insertelement <4 x i16> undef, i16 %A, i32 0150  %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> zeroinitializer151  ret <4 x i16> %tmp2152}153 154define <2 x i32> @v_shuffledup32(i32 %A) nounwind {155; CHECK-LABEL: v_shuffledup32:156; CHECK:       // %bb.0:157; CHECK-NEXT:    dup.2s v0, w0158; CHECK-NEXT:    ret159  %tmp1 = insertelement <2 x i32> undef, i32 %A, i32 0160  %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> zeroinitializer161  ret <2 x i32> %tmp2162}163 164define <2 x float> @v_shuffledupfloat(float %A) nounwind {165; CHECK-LABEL: v_shuffledupfloat:166; CHECK:       // %bb.0:167; CHECK-NEXT:    // kill: def $s0 killed $s0 def $q0168; CHECK-NEXT:    dup.2s v0, v0[0]169; CHECK-NEXT:    ret170  %tmp1 = insertelement <2 x float> undef, float %A, i32 0171  %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <2 x i32> zeroinitializer172  ret <2 x float> %tmp2173}174 175define <16 x i8> @v_shuffledupQ8(i8 %A) nounwind {176; CHECK-LABEL: v_shuffledupQ8:177; CHECK:       // %bb.0:178; CHECK-NEXT:    dup.16b v0, w0179; CHECK-NEXT:    ret180  %tmp1 = insertelement <16 x i8> undef, i8 %A, i32 0181  %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> zeroinitializer182  ret <16 x i8> %tmp2183}184 185define <8 x i16> @v_shuffledupQ16(i16 %A) nounwind {186; CHECK-LABEL: v_shuffledupQ16:187; CHECK:       // %bb.0:188; CHECK-NEXT:    dup.8h v0, w0189; CHECK-NEXT:    ret190  %tmp1 = insertelement <8 x i16> undef, i16 %A, i32 0191  %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> zeroinitializer192  ret <8 x i16> %tmp2193}194 195define <4 x i32> @v_shuffledupQ32(i32 %A) nounwind {196; CHECK-LABEL: v_shuffledupQ32:197; CHECK:       // %bb.0:198; CHECK-NEXT:    dup.4s v0, w0199; CHECK-NEXT:    ret200  %tmp1 = insertelement <4 x i32> undef, i32 %A, i32 0201  %tmp2 = shufflevector <4 x i32> %tmp1, <4 x i32> undef, <4 x i32> zeroinitializer202  ret <4 x i32> %tmp2203}204 205define <4 x float> @v_shuffledupQfloat(float %A) nounwind {206; CHECK-LABEL: v_shuffledupQfloat:207; CHECK:       // %bb.0:208; CHECK-NEXT:    // kill: def $s0 killed $s0 def $q0209; CHECK-NEXT:    dup.4s v0, v0[0]210; CHECK-NEXT:    ret211  %tmp1 = insertelement <4 x float> undef, float %A, i32 0212  %tmp2 = shufflevector <4 x float> %tmp1, <4 x float> undef, <4 x i32> zeroinitializer213  ret <4 x float> %tmp2214}215 216define <8 x i8> @vduplane8(<8 x i8> %A) nounwind {217; CHECK-LABEL: vduplane8:218; CHECK:       // %bb.0:219; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0220; CHECK-NEXT:    dup.8b v0, v0[1]221; CHECK-NEXT:    ret222  %tmp2 = shufflevector <8 x i8> %A, <8 x i8> undef, <8 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >223  ret <8 x i8> %tmp2224}225 226define <4 x i16> @vduplane16(<4 x i16> %A) nounwind {227; CHECK-LABEL: vduplane16:228; CHECK:       // %bb.0:229; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0230; CHECK-NEXT:    dup.4h v0, v0[1]231; CHECK-NEXT:    ret232  %tmp2 = shufflevector <4 x i16> %A, <4 x i16> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >233  ret <4 x i16> %tmp2234}235 236define <2 x i32> @vduplane32(<2 x i32> %A) nounwind {237; CHECK-LABEL: vduplane32:238; CHECK:       // %bb.0:239; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0240; CHECK-NEXT:    dup.2s v0, v0[1]241; CHECK-NEXT:    ret242  %tmp2 = shufflevector <2 x i32> %A, <2 x i32> undef, <2 x i32> < i32 1, i32 1 >243  ret <2 x i32> %tmp2244}245 246define <2 x float> @vduplanefloat(<2 x float> %A) nounwind {247; CHECK-LABEL: vduplanefloat:248; CHECK:       // %bb.0:249; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0250; CHECK-NEXT:    dup.2s v0, v0[1]251; CHECK-NEXT:    ret252  %tmp2 = shufflevector <2 x float> %A, <2 x float> undef, <2 x i32> < i32 1, i32 1 >253  ret <2 x float> %tmp2254}255 256define <16 x i8> @vduplaneQ8(<8 x i8> %A) nounwind {257; CHECK-LABEL: vduplaneQ8:258; CHECK:       // %bb.0:259; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0260; CHECK-NEXT:    dup.16b v0, v0[1]261; CHECK-NEXT:    ret262  %tmp2 = shufflevector <8 x i8> %A, <8 x i8> undef, <16 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >263  ret <16 x i8> %tmp2264}265 266define <8 x i16> @vduplaneQ16(<4 x i16> %A) nounwind {267; CHECK-LABEL: vduplaneQ16:268; CHECK:       // %bb.0:269; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0270; CHECK-NEXT:    dup.8h v0, v0[1]271; CHECK-NEXT:    ret272  %tmp2 = shufflevector <4 x i16> %A, <4 x i16> undef, <8 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >273  ret <8 x i16> %tmp2274}275 276define <4 x i32> @vduplaneQ32(<2 x i32> %A) nounwind {277; CHECK-LABEL: vduplaneQ32:278; CHECK:       // %bb.0:279; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0280; CHECK-NEXT:    dup.4s v0, v0[1]281; CHECK-NEXT:    ret282  %tmp2 = shufflevector <2 x i32> %A, <2 x i32> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >283  ret <4 x i32> %tmp2284}285 286define <4 x float> @vduplaneQfloat(<2 x float> %A) nounwind {287; CHECK-LABEL: vduplaneQfloat:288; CHECK:       // %bb.0:289; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0290; CHECK-NEXT:    dup.4s v0, v0[1]291; CHECK-NEXT:    ret292  %tmp2 = shufflevector <2 x float> %A, <2 x float> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >293  ret <4 x float> %tmp2294}295 296define <2 x i64> @foo(<2 x i64> %arg0_int64x1_t) nounwind readnone {297; CHECK-LABEL: foo:298; CHECK:       // %bb.0: // %entry299; CHECK-NEXT:    dup.2d v0, v0[1]300; CHECK-NEXT:    ret301entry:302  %0 = shufflevector <2 x i64> %arg0_int64x1_t, <2 x i64> undef, <2 x i32> <i32 1, i32 1>303  ret <2 x i64> %0304}305 306define <2 x i64> @bar(<2 x i64> %arg0_int64x1_t) nounwind readnone {307; CHECK-LABEL: bar:308; CHECK:       // %bb.0: // %entry309; CHECK-NEXT:    dup.2d v0, v0[0]310; CHECK-NEXT:    ret311entry:312  %0 = shufflevector <2 x i64> %arg0_int64x1_t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>313  ret <2 x i64> %0314}315 316define <2 x double> @baz(<2 x double> %arg0_int64x1_t) nounwind readnone {317; CHECK-LABEL: baz:318; CHECK:       // %bb.0: // %entry319; CHECK-NEXT:    dup.2d v0, v0[1]320; CHECK-NEXT:    ret321entry:322  %0 = shufflevector <2 x double> %arg0_int64x1_t, <2 x double> undef, <2 x i32> <i32 1, i32 1>323  ret <2 x double> %0324}325 326define <2 x double> @qux(<2 x double> %arg0_int64x1_t) nounwind readnone {327; CHECK-LABEL: qux:328; CHECK:       // %bb.0: // %entry329; CHECK-NEXT:    dup.2d v0, v0[0]330; CHECK-NEXT:    ret331entry:332  %0 = shufflevector <2 x double> %arg0_int64x1_t, <2 x double> undef, <2 x i32> <i32 0, i32 0>333  ret <2 x double> %0334}335 336define <2 x i32> @f(i32 %a, i32 %b) nounwind readnone  {337; CHECK-LABEL: f:338; CHECK:       // %bb.0:339; CHECK-NEXT:    fmov s0, w0340; CHECK-NEXT:    mov.s v0[1], w1341; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0342; CHECK-NEXT:    ret343  %vecinit = insertelement <2 x i32> undef, i32 %a, i32 0344  %vecinit1 = insertelement <2 x i32> %vecinit, i32 %b, i32 1345  ret <2 x i32> %vecinit1346}347 348define <4 x i32> @g(i32 %a, i32 %b) nounwind readnone  {349; CHECK-LABEL: g:350; CHECK:       // %bb.0:351; CHECK-NEXT:    fmov s0, w0352; CHECK-NEXT:    mov.s v0[1], w1353; CHECK-NEXT:    mov.s v0[2], w1354; CHECK-NEXT:    mov.s v0[3], w0355; CHECK-NEXT:    ret356  %vecinit = insertelement <4 x i32> undef, i32 %a, i32 0357  %vecinit1 = insertelement <4 x i32> %vecinit, i32 %b, i32 1358  %vecinit2 = insertelement <4 x i32> %vecinit1, i32 %b, i32 2359  %vecinit3 = insertelement <4 x i32> %vecinit2, i32 %a, i32 3360  ret <4 x i32> %vecinit3361}362 363define <2 x i64> @h(i64 %a, i64 %b) nounwind readnone  {364; CHECK-LABEL: h:365; CHECK:       // %bb.0:366; CHECK-NEXT:    fmov d0, x0367; CHECK-NEXT:    mov.d v0[1], x1368; CHECK-NEXT:    ret369  %vecinit = insertelement <2 x i64> undef, i64 %a, i32 0370  %vecinit1 = insertelement <2 x i64> %vecinit, i64 %b, i32 1371  ret <2 x i64> %vecinit1372}373 374; We used to spot this as a BUILD_VECTOR implementable by dup, but assume that375; the single value needed was of the same type as the vector. This is false if376; the scalar corresponding to the vector type is illegal (e.g. a <4 x i16>377; BUILD_VECTOR will have an i32 as its source). In that case, the operation is378; not a simple "dup vD.4h, vN.h[idx]" after all, and we crashed.379;380; *However*, it is a dup vD.4h, vN.h[2*idx].381define <4 x i16> @test_build_illegal(<4 x i32> %in) {382; CHECK-SD-LABEL: test_build_illegal:383; CHECK-SD:       // %bb.0:384; CHECK-SD-NEXT:    dup.4h v0, v0[6]385; CHECK-SD-NEXT:    ret386;387; CHECK-GI-LABEL: test_build_illegal:388; CHECK-GI:       // %bb.0:389; CHECK-GI-NEXT:    mov.s w8, v0[3]390; CHECK-GI-NEXT:    mov.h v0[3], w8391; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0392; CHECK-GI-NEXT:    ret393  %val = extractelement <4 x i32> %in, i32 3394  %smallval = trunc i32 %val to i16395  %vec = insertelement <4x i16> undef, i16 %smallval, i32 3396 397  ret <4 x i16> %vec398}399 400; We used to inherit an already extract_subvectored v4i16 from401; SelectionDAGBuilder here. We then added a DUPLANE on top of that, preventing402; the formation of an indexed-by-7 MLS.403define <4 x i16> @test_high_splat(<4 x i16> %a, <4 x i16> %b, <8 x i16> %v) #0 {404; CHECK-LABEL: test_high_splat:405; CHECK:       // %bb.0: // %entry406; CHECK-NEXT:    mls.4h v0, v1, v2[7]407; CHECK-NEXT:    ret408entry:409  %shuffle = shufflevector <8 x i16> %v, <8 x i16> undef, <4 x i32> <i32 7, i32 7, i32 7, i32 7>410  %mul = mul <4 x i16> %shuffle, %b411  %sub = sub <4 x i16> %a, %mul412  ret <4 x i16> %sub413}414 415; Also test the DUP path in the PerfectShuffle generator.416 417define <4 x i16> @test_perfectshuffle_dupext_v4i16(<4 x i16> %a, <4 x i16> %b) nounwind {418; CHECK-SD-LABEL: test_perfectshuffle_dupext_v4i16:419; CHECK-SD:       // %bb.0:420; CHECK-SD-NEXT:    trn1.4h v0, v0, v0421; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1422; CHECK-SD-NEXT:    mov.s v0[1], v1[0]423; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0424; CHECK-SD-NEXT:    ret425;426; CHECK-GI-LABEL: test_perfectshuffle_dupext_v4i16:427; CHECK-GI:       // %bb.0:428; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0429; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 def $q1430; CHECK-GI-NEXT:    adrp x8, .LCPI34_0431; CHECK-GI-NEXT:    mov.d v0[1], v1[0]432; CHECK-GI-NEXT:    ldr d1, [x8, :lo12:.LCPI34_0]433; CHECK-GI-NEXT:    tbl.16b v0, { v0 }, v1434; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0435; CHECK-GI-NEXT:    ret436  %r = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 0, i32 0, i32 4, i32 5>437  ret <4 x i16> %r438}439 440define <4 x half> @test_perfectshuffle_dupext_v4f16(<4 x half> %a, <4 x half> %b) nounwind {441; CHECK-SD-LABEL: test_perfectshuffle_dupext_v4f16:442; CHECK-SD:       // %bb.0:443; CHECK-SD-NEXT:    trn1.4h v0, v0, v0444; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1445; CHECK-SD-NEXT:    mov.s v0[1], v1[0]446; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0447; CHECK-SD-NEXT:    ret448;449; CHECK-GI-LABEL: test_perfectshuffle_dupext_v4f16:450; CHECK-GI:       // %bb.0:451; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 def $q0452; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 def $q1453; CHECK-GI-NEXT:    adrp x8, .LCPI35_0454; CHECK-GI-NEXT:    mov.d v0[1], v1[0]455; CHECK-GI-NEXT:    ldr d1, [x8, :lo12:.LCPI35_0]456; CHECK-GI-NEXT:    tbl.16b v0, { v0 }, v1457; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0458; CHECK-GI-NEXT:    ret459  %r = shufflevector <4 x half> %a, <4 x half> %b, <4 x i32> <i32 0, i32 0, i32 4, i32 5>460  ret <4 x half> %r461}462 463define <4 x i32> @test_perfectshuffle_dupext_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {464; CHECK-SD-LABEL: test_perfectshuffle_dupext_v4i32:465; CHECK-SD:       // %bb.0:466; CHECK-SD-NEXT:    trn1.4s v0, v0, v0467; CHECK-SD-NEXT:    mov.d v0[1], v1[0]468; CHECK-SD-NEXT:    ret469;470; CHECK-GI-LABEL: test_perfectshuffle_dupext_v4i32:471; CHECK-GI:       // %bb.0:472; CHECK-GI-NEXT:    adrp x8, .LCPI36_0473; CHECK-GI-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1474; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI36_0]475; CHECK-GI-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1476; CHECK-GI-NEXT:    tbl.16b v0, { v0, v1 }, v2477; CHECK-GI-NEXT:    ret478  %r = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 0, i32 4, i32 5>479  ret <4 x i32> %r480}481 482define <4 x float> @test_perfectshuffle_dupext_v4f32(<4 x float> %a, <4 x float> %b) nounwind {483; CHECK-SD-LABEL: test_perfectshuffle_dupext_v4f32:484; CHECK-SD:       // %bb.0:485; CHECK-SD-NEXT:    trn1.4s v0, v0, v0486; CHECK-SD-NEXT:    mov.d v0[1], v1[0]487; CHECK-SD-NEXT:    ret488;489; CHECK-GI-LABEL: test_perfectshuffle_dupext_v4f32:490; CHECK-GI:       // %bb.0:491; CHECK-GI-NEXT:    adrp x8, .LCPI37_0492; CHECK-GI-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1493; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI37_0]494; CHECK-GI-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1495; CHECK-GI-NEXT:    tbl.16b v0, { v0, v1 }, v2496; CHECK-GI-NEXT:    ret497  %r = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 0, i32 0, i32 4, i32 5>498  ret <4 x float> %r499}500 501define void @disguised_dup(<4 x float> %x, ptr %p1, ptr %p2) {502; CHECK-SD-LABEL: disguised_dup:503; CHECK-SD:       // %bb.0:504; CHECK-SD-NEXT:    ext.16b v1, v0, v0, #4505; CHECK-SD-NEXT:    mov.s v1[2], v0[0]506; CHECK-SD-NEXT:    dup.4s v0, v0[0]507; CHECK-SD-NEXT:    str q1, [x0]508; CHECK-SD-NEXT:    str q0, [x1]509; CHECK-SD-NEXT:    ret510;511; CHECK-GI-LABEL: disguised_dup:512; CHECK-GI:       // %bb.0:513; CHECK-GI-NEXT:    adrp x8, .LCPI38_1514; CHECK-GI-NEXT:    // kill: def $q0 killed $q0 def $q0_q1515; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI38_1]516; CHECK-GI-NEXT:    adrp x8, .LCPI38_0517; CHECK-GI-NEXT:    tbl.16b v0, { v0, v1 }, v2518; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI38_0]519; CHECK-GI-NEXT:    tbl.16b v2, { v0, v1 }, v2520; CHECK-GI-NEXT:    str q0, [x0]521; CHECK-GI-NEXT:    str q2, [x1]522; CHECK-GI-NEXT:    ret523  %shuf = shufflevector <4 x float> %x, <4 x float> undef, <4 x i32> <i32 1, i32 2, i32 0, i32 0>524  %dup = shufflevector <4 x float> %shuf, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 2, i32 3>525  store <4 x float> %shuf, ptr %p1, align 8526  store <4 x float> %dup, ptr %p2, align 8527  ret void528}529 530define <2 x i32> @dup_const2(<2 x i32> %A) nounwind {531; CHECK-SD-LABEL: dup_const2:532; CHECK-SD:       // %bb.0:533; CHECK-SD-NEXT:    mov w8, #32770 // =0x8002534; CHECK-SD-NEXT:    movk w8, #128, lsl #16535; CHECK-SD-NEXT:    dup.2s v1, w8536; CHECK-SD-NEXT:    add.2s v0, v0, v1537; CHECK-SD-NEXT:    ret538;539; CHECK-GI-LABEL: dup_const2:540; CHECK-GI:       // %bb.0:541; CHECK-GI-NEXT:    adrp x8, .LCPI39_0542; CHECK-GI-NEXT:    ldr d1, [x8, :lo12:.LCPI39_0]543; CHECK-GI-NEXT:    add.2s v0, v0, v1544; CHECK-GI-NEXT:    ret545  %tmp2 = add <2 x i32> %A, <i32 8421378, i32 8421378>546  ret <2 x i32> %tmp2547}548 549define <2 x i32> @dup_const4_ext(<4 x i32> %A) nounwind {550; CHECK-SD-LABEL: dup_const4_ext:551; CHECK-SD:       // %bb.0:552; CHECK-SD-NEXT:    mov w8, #32769 // =0x8001553; CHECK-SD-NEXT:    movk w8, #128, lsl #16554; CHECK-SD-NEXT:    dup.2s v1, w8555; CHECK-SD-NEXT:    add.2s v0, v0, v1556; CHECK-SD-NEXT:    ret557;558; CHECK-GI-LABEL: dup_const4_ext:559; CHECK-GI:       // %bb.0:560; CHECK-GI-NEXT:    adrp x8, .LCPI40_0561; CHECK-GI-NEXT:    ldr q1, [x8, :lo12:.LCPI40_0]562; CHECK-GI-NEXT:    add.4s v0, v0, v1563; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0564; CHECK-GI-NEXT:    ret565  %tmp1 = add <4 x i32> %A, <i32 8421377, i32 8421377, i32 8421377, i32 8421377>566  %tmp2 = shufflevector <4 x i32> %tmp1, <4 x i32> undef, <2 x i32> <i32 0, i32 1>567  ret <2 x i32> %tmp2568}569 570define <4 x i32> @dup_const24(<2 x i32> %A, <2 x i32> %B, <4 x i32> %C) nounwind {571; CHECK-SD-LABEL: dup_const24:572; CHECK-SD:       // %bb.0:573; CHECK-SD-NEXT:    mov w8, #32768 // =0x8000574; CHECK-SD-NEXT:    // kill: def $d1 killed $d1 def $q1575; CHECK-SD-NEXT:    movk w8, #128, lsl #16576; CHECK-SD-NEXT:    dup.4s v3, w8577; CHECK-SD-NEXT:    add.2s v0, v0, v3578; CHECK-SD-NEXT:    mov.d v0[1], v1[0]579; CHECK-SD-NEXT:    add.4s v1, v2, v3580; CHECK-SD-NEXT:    eor.16b v0, v1, v0581; CHECK-SD-NEXT:    ret582;583; CHECK-GI-LABEL: dup_const24:584; CHECK-GI:       // %bb.0:585; CHECK-GI-NEXT:    adrp x8, .LCPI41_1586; CHECK-GI-NEXT:    // kill: def $d1 killed $d1 def $q1587; CHECK-GI-NEXT:    ldr d3, [x8, :lo12:.LCPI41_1]588; CHECK-GI-NEXT:    adrp x8, .LCPI41_0589; CHECK-GI-NEXT:    add.2s v0, v0, v3590; CHECK-GI-NEXT:    ldr q3, [x8, :lo12:.LCPI41_0]591; CHECK-GI-NEXT:    mov.d v0[1], v1[0]592; CHECK-GI-NEXT:    add.4s v1, v2, v3593; CHECK-GI-NEXT:    eor.16b v0, v1, v0594; CHECK-GI-NEXT:    ret595  %tmp1 = add <2 x i32> %A, <i32 8421376, i32 8421376>596  %tmp4 = shufflevector <2 x i32> %tmp1, <2 x i32> %B, <4 x i32> <i32 0, i32 1, i32 2, i32 3>597  %tmp3 = add <4 x i32> %C, <i32 8421376, i32 8421376, i32 8421376, i32 8421376>598  %tmp5 = xor <4 x i32> %tmp3, %tmp4599  ret <4 x i32> %tmp5600}601 602define <8 x i16> @bitcast_i64_v8i16(i64 %a) {603; CHECK-SD-LABEL: bitcast_i64_v8i16:604; CHECK-SD:       // %bb.0:605; CHECK-SD-NEXT:    dup.8h v0, w0606; CHECK-SD-NEXT:    ret607;608; CHECK-GI-LABEL: bitcast_i64_v8i16:609; CHECK-GI:       // %bb.0:610; CHECK-GI-NEXT:    fmov d0, x0611; CHECK-GI-NEXT:    dup.8h v0, v0[0]612; CHECK-GI-NEXT:    ret613  %b = bitcast i64 %a to <4 x i16>614  %r = shufflevector <4 x i16> %b, <4 x i16> poison, <8 x i32> zeroinitializer615  ret <8 x i16> %r616}617 618define <8 x i16> @bitcast_i64_v8i16_lane1(i64 %a) {619; CHECK-LABEL: bitcast_i64_v8i16_lane1:620; CHECK:       // %bb.0:621; CHECK-NEXT:    fmov d0, x0622; CHECK-NEXT:    dup.8h v0, v0[1]623; CHECK-NEXT:    ret624  %b = bitcast i64 %a to <4 x i16>625  %r = shufflevector <4 x i16> %b, <4 x i16> poison, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>626  ret <8 x i16> %r627}628 629define <8 x i16> @bitcast_f64_v8i16(double %a) {630; CHECK-LABEL: bitcast_f64_v8i16:631; CHECK:       // %bb.0:632; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0633; CHECK-NEXT:    dup.8h v0, v0[0]634; CHECK-NEXT:    ret635  %b = bitcast double %a to <4 x i16>636  %r = shufflevector <4 x i16> %b, <4 x i16> poison, <8 x i32> zeroinitializer637  ret <8 x i16> %r638}639 640define <8 x half> @bitcast_i64_v8f16(i64 %a) {641; CHECK-LABEL: bitcast_i64_v8f16:642; CHECK:       // %bb.0:643; CHECK-NEXT:    fmov d0, x0644; CHECK-NEXT:    dup.8h v0, v0[0]645; CHECK-NEXT:    ret646  %b = bitcast i64 %a to <4 x half>647  %r = shufflevector <4 x half> %b, <4 x half> poison, <8 x i32> zeroinitializer648  ret <8 x half> %r649}650 651define <2 x i64> @bitcast_i64_v2f64(i64 %a) {652; CHECK-SD-LABEL: bitcast_i64_v2f64:653; CHECK-SD:       // %bb.0:654; CHECK-SD-NEXT:    fmov d0, x0655; CHECK-SD-NEXT:    dup.2d v0, v0[0]656; CHECK-SD-NEXT:    ret657;658; CHECK-GI-LABEL: bitcast_i64_v2f64:659; CHECK-GI:       // %bb.0:660; CHECK-GI-NEXT:    dup.2d v0, x0661; CHECK-GI-NEXT:    ret662  %b = bitcast i64 %a to <1 x i64>663  %r = shufflevector <1 x i64> %b, <1 x i64> poison, <2 x i32> zeroinitializer664  ret <2 x i64> %r665}666 667define <2 x i64> @bitcast_v2f64_v2i64(<2 x double> %a) {668; CHECK-LABEL: bitcast_v2f64_v2i64:669; CHECK:       // %bb.0:670; CHECK-NEXT:    dup.2d v0, v0[0]671; CHECK-NEXT:    ret672  %b = bitcast <2 x double> %a to <2 x i64>673  %r = shufflevector <2 x i64> %b, <2 x i64> poison, <2 x i32> zeroinitializer674  ret <2 x i64> %r675}676 677define <2 x i64> @bitcast_v8i16_v2i64(<8 x i16> %a) {678; CHECK-LABEL: bitcast_v8i16_v2i64:679; CHECK:       // %bb.0:680; CHECK-NEXT:    dup.2d v0, v0[0]681; CHECK-NEXT:    ret682  %b = bitcast <8 x i16> %a to <2 x i64>683  %r = shufflevector <2 x i64> %b, <2 x i64> poison, <2 x i32> zeroinitializer684  ret <2 x i64> %r685}686 687define <8 x i16> @bitcast_v2f64_v8i16(<2 x i64> %a) {688; CHECK-LABEL: bitcast_v2f64_v8i16:689; CHECK:       // %bb.0:690; CHECK-NEXT:    dup.8h v0, v0[0]691; CHECK-NEXT:    ret692  %b = bitcast <2 x i64> %a to <8 x i16>693  %r = shufflevector <8 x i16> %b, <8 x i16> poison, <8 x i32> zeroinitializer694  ret <8 x i16> %r695}696 697define <4 x i16> @dup_i16_v4i16_constant() {698; CHECK-SD-LABEL: dup_i16_v4i16_constant:699; CHECK-SD:       // %bb.0:700; CHECK-SD-NEXT:    mov w8, #9211 // =0x23fb701; CHECK-SD-NEXT:    dup.4h v0, w8702; CHECK-SD-NEXT:    ret703;704; CHECK-GI-LABEL: dup_i16_v4i16_constant:705; CHECK-GI:       // %bb.0:706; CHECK-GI-NEXT:    adrp x8, .LCPI50_0707; CHECK-GI-NEXT:    ldr d0, [x8, :lo12:.LCPI50_0]708; CHECK-GI-NEXT:    ret709  ret <4 x i16> <i16 9211, i16 9211, i16 9211, i16 9211>710}711