541 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=arm-eabi -float-abi=soft -mattr=+neon -verify-machineinstrs | FileCheck %s3 4define <8 x i8> @v_dup8(i8 %A) nounwind {5; CHECK-LABEL: v_dup8:6; CHECK: @ %bb.0:7; CHECK-NEXT: vdup.8 d16, r08; CHECK-NEXT: vmov r0, r1, d169; CHECK-NEXT: mov pc, lr10 %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: vdup.16 d16, r025; CHECK-NEXT: vmov r0, r1, d1626; CHECK-NEXT: mov pc, lr27 %tmp1 = insertelement <4 x i16> zeroinitializer, i16 %A, i32 028 %tmp2 = insertelement <4 x i16> %tmp1, i16 %A, i32 129 %tmp3 = insertelement <4 x i16> %tmp2, i16 %A, i32 230 %tmp4 = insertelement <4 x i16> %tmp3, i16 %A, i32 331 ret <4 x i16> %tmp432}33 34define <2 x i32> @v_dup32(i32 %A) nounwind {35; CHECK-LABEL: v_dup32:36; CHECK: @ %bb.0:37; CHECK-NEXT: vdup.32 d16, r038; CHECK-NEXT: vmov r0, r1, d1639; CHECK-NEXT: mov pc, lr40 %tmp1 = insertelement <2 x i32> zeroinitializer, i32 %A, i32 041 %tmp2 = insertelement <2 x i32> %tmp1, i32 %A, i32 142 ret <2 x i32> %tmp243}44 45define <2 x float> @v_dupfloat(float %A) nounwind {46; CHECK-LABEL: v_dupfloat:47; CHECK: @ %bb.0:48; CHECK-NEXT: vdup.32 d16, r049; CHECK-NEXT: vmov r0, r1, d1650; CHECK-NEXT: mov pc, lr51 %tmp1 = insertelement <2 x float> zeroinitializer, float %A, i32 052 %tmp2 = insertelement <2 x float> %tmp1, float %A, i32 153 ret <2 x float> %tmp254}55 56define <16 x i8> @v_dupQ8(i8 %A) nounwind {57; CHECK-LABEL: v_dupQ8:58; CHECK: @ %bb.0:59; CHECK-NEXT: vdup.8 q8, r060; CHECK-NEXT: vmov r0, r1, d1661; CHECK-NEXT: vmov r2, r3, d1762; CHECK-NEXT: mov pc, lr63 %tmp1 = insertelement <16 x i8> zeroinitializer, i8 %A, i32 064 %tmp2 = insertelement <16 x i8> %tmp1, i8 %A, i32 165 %tmp3 = insertelement <16 x i8> %tmp2, i8 %A, i32 266 %tmp4 = insertelement <16 x i8> %tmp3, i8 %A, i32 367 %tmp5 = insertelement <16 x i8> %tmp4, i8 %A, i32 468 %tmp6 = insertelement <16 x i8> %tmp5, i8 %A, i32 569 %tmp7 = insertelement <16 x i8> %tmp6, i8 %A, i32 670 %tmp8 = insertelement <16 x i8> %tmp7, i8 %A, i32 771 %tmp9 = insertelement <16 x i8> %tmp8, i8 %A, i32 872 %tmp10 = insertelement <16 x i8> %tmp9, i8 %A, i32 973 %tmp11 = insertelement <16 x i8> %tmp10, i8 %A, i32 1074 %tmp12 = insertelement <16 x i8> %tmp11, i8 %A, i32 1175 %tmp13 = insertelement <16 x i8> %tmp12, i8 %A, i32 1276 %tmp14 = insertelement <16 x i8> %tmp13, i8 %A, i32 1377 %tmp15 = insertelement <16 x i8> %tmp14, i8 %A, i32 1478 %tmp16 = insertelement <16 x i8> %tmp15, i8 %A, i32 1579 ret <16 x i8> %tmp1680}81 82define <8 x i16> @v_dupQ16(i16 %A) nounwind {83; CHECK-LABEL: v_dupQ16:84; CHECK: @ %bb.0:85; CHECK-NEXT: vdup.16 q8, r086; CHECK-NEXT: vmov r0, r1, d1687; CHECK-NEXT: vmov r2, r3, d1788; CHECK-NEXT: mov pc, lr89 %tmp1 = insertelement <8 x i16> zeroinitializer, i16 %A, i32 090 %tmp2 = insertelement <8 x i16> %tmp1, i16 %A, i32 191 %tmp3 = insertelement <8 x i16> %tmp2, i16 %A, i32 292 %tmp4 = insertelement <8 x i16> %tmp3, i16 %A, i32 393 %tmp5 = insertelement <8 x i16> %tmp4, i16 %A, i32 494 %tmp6 = insertelement <8 x i16> %tmp5, i16 %A, i32 595 %tmp7 = insertelement <8 x i16> %tmp6, i16 %A, i32 696 %tmp8 = insertelement <8 x i16> %tmp7, i16 %A, i32 797 ret <8 x i16> %tmp898}99 100define <4 x i32> @v_dupQ32(i32 %A) nounwind {101; CHECK-LABEL: v_dupQ32:102; CHECK: @ %bb.0:103; CHECK-NEXT: mov r1, r0104; CHECK-NEXT: mov r2, r0105; CHECK-NEXT: mov r3, r0106; CHECK-NEXT: mov pc, lr107 %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %A, i32 0108 %tmp2 = insertelement <4 x i32> %tmp1, i32 %A, i32 1109 %tmp3 = insertelement <4 x i32> %tmp2, i32 %A, i32 2110 %tmp4 = insertelement <4 x i32> %tmp3, i32 %A, i32 3111 ret <4 x i32> %tmp4112}113 114define <4 x float> @v_dupQfloat(float %A) nounwind {115; CHECK-LABEL: v_dupQfloat:116; CHECK: @ %bb.0:117; CHECK-NEXT: vdup.32 q8, r0118; CHECK-NEXT: vmov r0, r1, d16119; CHECK-NEXT: vmov r2, r3, d17120; CHECK-NEXT: mov pc, lr121 %tmp1 = insertelement <4 x float> zeroinitializer, float %A, i32 0122 %tmp2 = insertelement <4 x float> %tmp1, float %A, i32 1123 %tmp3 = insertelement <4 x float> %tmp2, float %A, i32 2124 %tmp4 = insertelement <4 x float> %tmp3, float %A, i32 3125 ret <4 x float> %tmp4126}127 128; Check to make sure it works with shuffles, too.129 130define <8 x i8> @v_shuffledup8(i8 %A) nounwind {131; CHECK-LABEL: v_shuffledup8:132; CHECK: @ %bb.0:133; CHECK-NEXT: vdup.8 d16, r0134; CHECK-NEXT: vmov r0, r1, d16135; CHECK-NEXT: mov pc, lr136 %tmp1 = insertelement <8 x i8> undef, i8 %A, i32 0137 %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> zeroinitializer138 ret <8 x i8> %tmp2139}140 141define <4 x i16> @v_shuffledup16(i16 %A) nounwind {142; CHECK-LABEL: v_shuffledup16:143; CHECK: @ %bb.0:144; CHECK-NEXT: vdup.16 d16, r0145; CHECK-NEXT: vmov r0, r1, d16146; CHECK-NEXT: mov pc, lr147 %tmp1 = insertelement <4 x i16> undef, i16 %A, i32 0148 %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> zeroinitializer149 ret <4 x i16> %tmp2150}151 152define <2 x i32> @v_shuffledup32(i32 %A) nounwind {153; CHECK-LABEL: v_shuffledup32:154; CHECK: @ %bb.0:155; CHECK-NEXT: vdup.32 d16, r0156; CHECK-NEXT: vmov r0, r1, d16157; CHECK-NEXT: mov pc, lr158 %tmp1 = insertelement <2 x i32> undef, i32 %A, i32 0159 %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> zeroinitializer160 ret <2 x i32> %tmp2161}162 163define <2 x float> @v_shuffledupfloat(float %A) nounwind {164; CHECK-LABEL: v_shuffledupfloat:165; CHECK: @ %bb.0:166; CHECK-NEXT: vdup.32 d16, r0167; CHECK-NEXT: vmov r0, r1, d16168; CHECK-NEXT: mov pc, lr169 %tmp1 = insertelement <2 x float> undef, float %A, i32 0170 %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <2 x i32> zeroinitializer171 ret <2 x float> %tmp2172}173 174define <16 x i8> @v_shuffledupQ8(i8 %A) nounwind {175; CHECK-LABEL: v_shuffledupQ8:176; CHECK: @ %bb.0:177; CHECK-NEXT: vdup.8 q8, r0178; CHECK-NEXT: vmov r0, r1, d16179; CHECK-NEXT: vmov r2, r3, d17180; CHECK-NEXT: mov pc, lr181 %tmp1 = insertelement <16 x i8> undef, i8 %A, i32 0182 %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> zeroinitializer183 ret <16 x i8> %tmp2184}185 186define <8 x i16> @v_shuffledupQ16(i16 %A) nounwind {187; CHECK-LABEL: v_shuffledupQ16:188; CHECK: @ %bb.0:189; CHECK-NEXT: vdup.16 q8, r0190; CHECK-NEXT: vmov r0, r1, d16191; CHECK-NEXT: vmov r2, r3, d17192; CHECK-NEXT: mov pc, lr193 %tmp1 = insertelement <8 x i16> undef, i16 %A, i32 0194 %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> zeroinitializer195 ret <8 x i16> %tmp2196}197 198define <4 x i32> @v_shuffledupQ32(i32 %A) nounwind {199; CHECK-LABEL: v_shuffledupQ32:200; CHECK: @ %bb.0:201; CHECK-NEXT: vdup.32 q8, r0202; CHECK-NEXT: vmov r0, r1, d16203; CHECK-NEXT: vmov r2, r3, d17204; CHECK-NEXT: mov pc, lr205 %tmp1 = insertelement <4 x i32> undef, i32 %A, i32 0206 %tmp2 = shufflevector <4 x i32> %tmp1, <4 x i32> undef, <4 x i32> zeroinitializer207 ret <4 x i32> %tmp2208}209 210define <4 x float> @v_shuffledupQfloat(float %A) nounwind {211; CHECK-LABEL: v_shuffledupQfloat:212; CHECK: @ %bb.0:213; CHECK-NEXT: vdup.32 q8, r0214; CHECK-NEXT: vmov r0, r1, d16215; CHECK-NEXT: vmov r2, r3, d17216; CHECK-NEXT: mov pc, lr217 %tmp1 = insertelement <4 x float> undef, float %A, i32 0218 %tmp2 = shufflevector <4 x float> %tmp1, <4 x float> undef, <4 x i32> zeroinitializer219 ret <4 x float> %tmp2220}221 222define arm_aapcs_vfpcc <8 x i8> @vduplane8(<8 x i8> %A) nounwind {223; CHECK-LABEL: vduplane8:224; CHECK: @ %bb.0:225; CHECK-NEXT: vdup.8 d0, d0[1]226; CHECK-NEXT: mov pc, lr227 %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 >228 ret <8 x i8> %tmp2229}230 231define arm_aapcs_vfpcc <4 x i16> @vduplane16(<4 x i16> %A) nounwind {232; CHECK-LABEL: vduplane16:233; CHECK: @ %bb.0:234; CHECK-NEXT: vdup.16 d0, d0[1]235; CHECK-NEXT: mov pc, lr236 %tmp2 = shufflevector <4 x i16> %A, <4 x i16> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >237 ret <4 x i16> %tmp2238}239 240define arm_aapcs_vfpcc <2 x i32> @vduplane32(<2 x i32> %A) nounwind {241; CHECK-LABEL: vduplane32:242; CHECK: @ %bb.0:243; CHECK-NEXT: vdup.32 d0, d0[1]244; CHECK-NEXT: mov pc, lr245 %tmp2 = shufflevector <2 x i32> %A, <2 x i32> undef, <2 x i32> < i32 1, i32 1 >246 ret <2 x i32> %tmp2247}248 249define arm_aapcs_vfpcc <2 x float> @vduplanefloat(<2 x float> %A) nounwind {250; CHECK-LABEL: vduplanefloat:251; CHECK: @ %bb.0:252; CHECK-NEXT: vdup.32 d0, d0[1]253; CHECK-NEXT: mov pc, lr254 %tmp2 = shufflevector <2 x float> %A, <2 x float> undef, <2 x i32> < i32 1, i32 1 >255 ret <2 x float> %tmp2256}257 258define arm_aapcs_vfpcc <16 x i8> @vduplaneQ8(<8 x i8> %A) nounwind {259; CHECK-LABEL: vduplaneQ8:260; CHECK: @ %bb.0:261; CHECK-NEXT: vdup.8 q0, d0[1]262; CHECK-NEXT: mov pc, lr263 %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 >264 ret <16 x i8> %tmp2265}266 267define arm_aapcs_vfpcc <8 x i16> @vduplaneQ16(<4 x i16> %A) nounwind {268; CHECK-LABEL: vduplaneQ16:269; CHECK: @ %bb.0:270; CHECK-NEXT: vdup.16 q0, d0[1]271; CHECK-NEXT: mov pc, lr272 %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 arm_aapcs_vfpcc <4 x i32> @vduplaneQ32(<2 x i32> %A) nounwind {277; CHECK-LABEL: vduplaneQ32:278; CHECK: @ %bb.0:279; CHECK-NEXT: vdup.32 q0, d0[1]280; CHECK-NEXT: mov pc, lr281 %tmp2 = shufflevector <2 x i32> %A, <2 x i32> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >282 ret <4 x i32> %tmp2283}284 285define arm_aapcs_vfpcc <4 x float> @vduplaneQfloat(<2 x float> %A) nounwind {286; CHECK-LABEL: vduplaneQfloat:287; CHECK: @ %bb.0:288; CHECK-NEXT: vdup.32 q0, d0[1]289; CHECK-NEXT: mov pc, lr290 %tmp2 = shufflevector <2 x float> %A, <2 x float> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >291 ret <4 x float> %tmp2292}293 294define <2 x i64> @foo(<2 x i64> %arg0_int64x1_t) nounwind readnone {295; CHECK-LABEL: foo:296; CHECK: @ %bb.0: @ %entry297; CHECK-NEXT: mov r0, r2298; CHECK-NEXT: mov r1, r3299; CHECK-NEXT: mov pc, lr300entry:301 %0 = shufflevector <2 x i64> %arg0_int64x1_t, <2 x i64> undef, <2 x i32> <i32 1, i32 1>302 ret <2 x i64> %0303}304 305define <2 x i64> @bar(<2 x i64> %arg0_int64x1_t) nounwind readnone {306; CHECK-LABEL: bar:307; CHECK: @ %bb.0: @ %entry308; CHECK-NEXT: mov r2, r0309; CHECK-NEXT: mov r3, r1310; CHECK-NEXT: mov pc, lr311entry: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: mov r0, r2320; CHECK-NEXT: mov r1, r3321; CHECK-NEXT: mov pc, lr322entry:323 %0 = shufflevector <2 x double> %arg0_int64x1_t, <2 x double> undef, <2 x i32> <i32 1, i32 1>324 ret <2 x double> %0325}326 327define <2 x double> @qux(<2 x double> %arg0_int64x1_t) nounwind readnone {328; CHECK-LABEL: qux:329; CHECK: @ %bb.0: @ %entry330; CHECK-NEXT: mov r2, r0331; CHECK-NEXT: mov r3, r1332; CHECK-NEXT: mov pc, lr333entry:334 %0 = shufflevector <2 x double> %arg0_int64x1_t, <2 x double> undef, <2 x i32> <i32 0, i32 0>335 ret <2 x double> %0336}337 338; Radar 7373643339define void @redundantVdup(ptr %ptr) nounwind {340; CHECK-LABEL: redundantVdup:341; CHECK: @ %bb.0:342; CHECK-NEXT: vmov.i8 d16, #0x80343; CHECK-NEXT: vstr d16, [r0]344; CHECK-NEXT: mov pc, lr345 %1 = insertelement <8 x i8> undef, i8 -128, i32 0346 %2 = shufflevector <8 x i8> %1, <8 x i8> undef, <8 x i32> zeroinitializer347 store <8 x i8> %2, ptr %ptr, align 8348 ret void349}350 351define <4 x i32> @tdupi(i32 %x, i32 %y) {352; CHECK-LABEL: tdupi:353; CHECK: @ %bb.0:354; CHECK-NEXT: mov r3, r1355; CHECK-NEXT: mov r1, r0356; CHECK-NEXT: mov r2, r0357; CHECK-NEXT: mov pc, lr358 %1 = insertelement <4 x i32> undef, i32 %x, i32 0359 %2 = insertelement <4 x i32> %1, i32 %x, i32 1360 %3 = insertelement <4 x i32> %2, i32 %x, i32 2361 %4 = insertelement <4 x i32> %3, i32 %y, i32 3362 ret <4 x i32> %4363}364 365define <4 x float> @tdupf(float %x, float %y) {366; CHECK-LABEL: tdupf:367; CHECK: @ %bb.0:368; CHECK-NEXT: vdup.32 q0, r0369; CHECK-NEXT: vmov s3, r1370; CHECK-NEXT: vmov r0, r1, d0371; CHECK-NEXT: vmov r2, r3, d1372; CHECK-NEXT: mov pc, lr373 %1 = insertelement <4 x float> undef, float %x, i32 0374 %2 = insertelement <4 x float> %1, float %x, i32 1375 %3 = insertelement <4 x float> %2, float %x, i32 2376 %4 = insertelement <4 x float> %3, float %y, i32 3377 ret <4 x float> %4378}379 380; This test checks that when splatting an element from a vector into another,381; the value isn't moved out to GPRs first.382define <4 x i32> @tduplane(<4 x i32> %invec) {383; CHECK-LABEL: tduplane:384; CHECK: @ %bb.0:385; CHECK-NEXT: vmov d16, r0, r1386; CHECK-NEXT: mov r3, #255387; CHECK-NEXT: vmov.32 r0, d16[1]388; CHECK-NEXT: mov r1, r0389; CHECK-NEXT: mov r2, r0390; CHECK-NEXT: mov pc, lr391 %in = extractelement <4 x i32> %invec, i32 1392 %1 = insertelement <4 x i32> undef, i32 %in, i32 0393 %2 = insertelement <4 x i32> %1, i32 %in, i32 1394 %3 = insertelement <4 x i32> %2, i32 %in, i32 2395 %4 = insertelement <4 x i32> %3, i32 255, i32 3396 ret <4 x i32> %4397}398 399define <2 x float> @check_f32(<4 x float> %v) nounwind {400; CHECK-LABEL: check_f32:401; CHECK: @ %bb.0:402; CHECK-NEXT: vmov d16, r2, r3403; CHECK-NEXT: vdup.32 d16, d16[1]404; CHECK-NEXT: vmov r0, r1, d16405; CHECK-NEXT: mov pc, lr406 %x = extractelement <4 x float> %v, i32 3407 %1 = insertelement <2 x float> undef, float %x, i32 0408 %2 = insertelement <2 x float> %1, float %x, i32 1409 ret <2 x float> %2410}411 412define <2 x i32> @check_i32(<4 x i32> %v) nounwind {413; CHECK-LABEL: check_i32:414; CHECK: @ %bb.0:415; CHECK-NEXT: vmov d16, r2, r3416; CHECK-NEXT: vdup.32 d16, d16[1]417; CHECK-NEXT: vmov r0, r1, d16418; CHECK-NEXT: mov pc, lr419 %x = extractelement <4 x i32> %v, i32 3420 %1 = insertelement <2 x i32> undef, i32 %x, i32 0421 %2 = insertelement <2 x i32> %1, i32 %x, i32 1422 ret <2 x i32> %2423}424 425define <4 x i16> @check_i16(<8 x i16> %v) nounwind {426; CHECK-LABEL: check_i16:427; CHECK: @ %bb.0:428; CHECK-NEXT: vmov d16, r0, r1429; CHECK-NEXT: vdup.16 d16, d16[3]430; CHECK-NEXT: vmov r0, r1, d16431; CHECK-NEXT: mov pc, lr432 %x = extractelement <8 x i16> %v, i32 3433 %1 = insertelement <4 x i16> undef, i16 %x, i32 0434 %2 = insertelement <4 x i16> %1, i16 %x, i32 1435 ret <4 x i16> %2436}437 438define <8 x i8> @check_i8(<16 x i8> %v) nounwind {439; CHECK-LABEL: check_i8:440; CHECK: @ %bb.0:441; CHECK-NEXT: vmov d16, r0, r1442; CHECK-NEXT: vdup.8 d16, d16[3]443; CHECK-NEXT: vmov r0, r1, d16444; CHECK-NEXT: mov pc, lr445 %x = extractelement <16 x i8> %v, i32 3446 %1 = insertelement <8 x i8> undef, i8 %x, i32 0447 %2 = insertelement <8 x i8> %1, i8 %x, i32 1448 ret <8 x i8> %2449}450 451; Check that an SPR splat produces a vdup.452 453define <2 x float> @check_spr_splat2(<2 x float> %p, i16 %q) {454; CHECK-LABEL: check_spr_splat2:455; CHECK: @ %bb.0:456; CHECK-NEXT: lsl r2, r2, #16457; CHECK-NEXT: vmov d16, r0, r1458; CHECK-NEXT: asr r2, r2, #16459; CHECK-NEXT: vmov s0, r2460; CHECK-NEXT: vcvt.f32.s32 s0, s0461; CHECK-NEXT: vdup.32 d17, d0[0]462; CHECK-NEXT: vsub.f32 d16, d17, d16463; CHECK-NEXT: vmov r0, r1, d16464; CHECK-NEXT: mov pc, lr465 %conv = sitofp i16 %q to float466 %splat.splatinsert = insertelement <2 x float> undef, float %conv, i32 0467 %splat.splat = shufflevector <2 x float> %splat.splatinsert, <2 x float> undef, <2 x i32> zeroinitializer468 %sub = fsub <2 x float> %splat.splat, %p469 ret <2 x float> %sub470}471 472define <4 x float> @check_spr_splat4(<4 x float> %p, i16 %q) {473; CHECK-LABEL: check_spr_splat4:474; CHECK: @ %bb.0:475; CHECK-NEXT: ldrsh r12, [sp]476; CHECK-NEXT: vmov d17, r2, r3477; CHECK-NEXT: vmov d16, r0, r1478; CHECK-NEXT: vmov s0, r12479; CHECK-NEXT: vcvt.f32.s32 s0, s0480; CHECK-NEXT: vdup.32 q9, d0[0]481; CHECK-NEXT: vsub.f32 q8, q9, q8482; CHECK-NEXT: vmov r0, r1, d16483; CHECK-NEXT: vmov r2, r3, d17484; CHECK-NEXT: mov pc, lr485 %conv = sitofp i16 %q to float486 %splat.splatinsert = insertelement <4 x float> undef, float %conv, i32 0487 %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> zeroinitializer488 %sub = fsub <4 x float> %splat.splat, %p489 ret <4 x float> %sub490}491; Same codegen as above test; scalar is splatted using vld1, so shuffle index is irrelevant.492define <4 x float> @check_spr_splat4_lane1(<4 x float> %p, i16 %q) {493; CHECK-LABEL: check_spr_splat4_lane1:494; CHECK: @ %bb.0:495; CHECK-NEXT: ldrsh r12, [sp]496; CHECK-NEXT: vmov d17, r2, r3497; CHECK-NEXT: vmov d16, r0, r1498; CHECK-NEXT: vmov s0, r12499; CHECK-NEXT: vcvt.f32.s32 s0, s0500; CHECK-NEXT: vdup.32 q9, d0[0]501; CHECK-NEXT: vsub.f32 q8, q9, q8502; CHECK-NEXT: vmov r0, r1, d16503; CHECK-NEXT: vmov r2, r3, d17504; CHECK-NEXT: mov pc, lr505 %conv = sitofp i16 %q to float506 %splat.splatinsert = insertelement <4 x float> undef, float %conv, i32 1507 %splat.splat = shufflevector <4 x float> %splat.splatinsert, <4 x float> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>508 %sub = fsub <4 x float> %splat.splat, %p509 ret <4 x float> %sub510}511 512; Also make sure we don't barf on variable-index extractelts, where we almost513; could have generated a vdup.514 515define <8 x i8> @check_i8_varidx(<16 x i8> %v, i32 %idx) {516; CHECK-LABEL: check_i8_varidx:517; CHECK: @ %bb.0:518; CHECK-NEXT: .save {r11}519; CHECK-NEXT: push {r11}520; CHECK-NEXT: .setfp r11, sp521; CHECK-NEXT: mov r11, sp522; CHECK-NEXT: .pad #28523; CHECK-NEXT: sub sp, sp, #28524; CHECK-NEXT: bic sp, sp, #15525; CHECK-NEXT: ldr r12, [r11, #4]526; CHECK-NEXT: vmov d17, r2, r3527; CHECK-NEXT: vmov d16, r0, r1528; CHECK-NEXT: mov r1, sp529; CHECK-NEXT: and r0, r12, #15530; CHECK-NEXT: vst1.64 {d16, d17}, [r1:128], r0531; CHECK-NEXT: vld1.8 {d16[]}, [r1]532; CHECK-NEXT: vmov r0, r1, d16533; CHECK-NEXT: mov sp, r11534; CHECK-NEXT: pop {r11}535; CHECK-NEXT: mov pc, lr536 %x = extractelement <16 x i8> %v, i32 %idx537 %1 = insertelement <8 x i8> undef, i8 %x, i32 0538 %2 = insertelement <8 x i8> %1, i8 %x, i32 1539 ret <8 x i8> %2540}541