870 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -verify-machineinstrs -mtriple=arm64-eabi -mattr=+rdm | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc < %s -verify-machineinstrs -mtriple=arm64-eabi -mattr=+v8.1a | FileCheck %s --check-prefixes=CHECK,CHECK-SD4; RUN: llc < %s -verify-machineinstrs -mtriple=arm64-eabi -mattr=+rdm -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI5 6declare <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16>, <4 x i16>)7declare <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16>, <8 x i16>)8declare <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32>, <2 x i32>)9declare <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32>, <4 x i32>)10declare i32 @llvm.aarch64.neon.sqrdmulh.i32(i32, i32)11 12declare <4 x i16> @llvm.aarch64.neon.sqadd.v4i16(<4 x i16>, <4 x i16>)13declare <8 x i16> @llvm.aarch64.neon.sqadd.v8i16(<8 x i16>, <8 x i16>)14declare <2 x i32> @llvm.aarch64.neon.sqadd.v2i32(<2 x i32>, <2 x i32>)15declare <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32>, <4 x i32>)16declare i32 @llvm.aarch64.neon.sqadd.i32(i32, i32)17 18declare <4 x i16> @llvm.aarch64.neon.sqsub.v4i16(<4 x i16>, <4 x i16>)19declare <8 x i16> @llvm.aarch64.neon.sqsub.v8i16(<8 x i16>, <8 x i16>)20declare <2 x i32> @llvm.aarch64.neon.sqsub.v2i32(<2 x i32>, <2 x i32>)21declare <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32>, <4 x i32>)22declare i32 @llvm.aarch64.neon.sqsub.i32(i32, i32)23 24declare <4 x i16> @llvm.aarch64.neon.sqrdmlah.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)25declare <2 x i32> @llvm.aarch64.neon.sqrdmlah.v2i32(<2 x i32>, <2 x i32>, <2 x i32>)26declare <8 x i16> @llvm.aarch64.neon.sqrdmlah.v8i16(<8 x i16>, <8 x i16>, <8 x i16>)27declare <4 x i32> @llvm.aarch64.neon.sqrdmlah.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)28declare i32 @llvm.aarch64.neon.sqrdmlah.i32(i32, i32, i32)29 30declare <4 x i16> @llvm.aarch64.neon.sqrdmlsh.v4i16(<4 x i16>, <4 x i16>, <4 x i16>)31declare <2 x i32> @llvm.aarch64.neon.sqrdmlsh.v2i32(<2 x i32>, <2 x i32>, <2 x i32>)32declare <8 x i16> @llvm.aarch64.neon.sqrdmlsh.v8i16(<8 x i16>, <8 x i16>, <8 x i16>)33declare <4 x i32> @llvm.aarch64.neon.sqrdmlsh.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)34declare i32 @llvm.aarch64.neon.sqrdmlsh.i32(i32, i32, i32)35 36; The sadd intrinsics in this file previously transformed into sqrdmlah where they37; shouldn't. They should produce sqrdmulh and sqadd.38 39;-----------------------------------------------------------------------------40; RDMA Vector41; test for SIMDThreeSameVectorSQRDMLxHTiedHS42 43define <4 x i16> @test_sqrdmlah_v4i16(<4 x i16> %acc, <4 x i16> %mhs, <4 x i16> %rhs) {44; CHECK-LABEL: test_sqrdmlah_v4i16:45; CHECK: // %bb.0:46; CHECK-NEXT: sqrdmulh v1.4h, v1.4h, v2.4h47; CHECK-NEXT: sqadd v0.4h, v0.4h, v1.4h48; CHECK-NEXT: ret49 %prod = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %mhs, <4 x i16> %rhs)50 %retval = call <4 x i16> @llvm.aarch64.neon.sqadd.v4i16(<4 x i16> %acc, <4 x i16> %prod)51 ret <4 x i16> %retval52}53 54define <8 x i16> @test_sqrdmlah_v8i16(<8 x i16> %acc, <8 x i16> %mhs, <8 x i16> %rhs) {55; CHECK-LABEL: test_sqrdmlah_v8i16:56; CHECK: // %bb.0:57; CHECK-NEXT: sqrdmulh v1.8h, v1.8h, v2.8h58; CHECK-NEXT: sqadd v0.8h, v0.8h, v1.8h59; CHECK-NEXT: ret60 %prod = call <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16> %mhs, <8 x i16> %rhs)61 %retval = call <8 x i16> @llvm.aarch64.neon.sqadd.v8i16(<8 x i16> %acc, <8 x i16> %prod)62 ret <8 x i16> %retval63}64 65define <2 x i32> @test_sqrdmlah_v2i32(<2 x i32> %acc, <2 x i32> %mhs, <2 x i32> %rhs) {66; CHECK-LABEL: test_sqrdmlah_v2i32:67; CHECK: // %bb.0:68; CHECK-NEXT: sqrdmulh v1.2s, v1.2s, v2.2s69; CHECK-NEXT: sqadd v0.2s, v0.2s, v1.2s70; CHECK-NEXT: ret71 %prod = call <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32> %mhs, <2 x i32> %rhs)72 %retval = call <2 x i32> @llvm.aarch64.neon.sqadd.v2i32(<2 x i32> %acc, <2 x i32> %prod)73 ret <2 x i32> %retval74}75 76define <4 x i32> @test_sqrdmlah_v4i32(<4 x i32> %acc, <4 x i32> %mhs, <4 x i32> %rhs) {77; CHECK-LABEL: test_sqrdmlah_v4i32:78; CHECK: // %bb.0:79; CHECK-NEXT: sqrdmulh v1.4s, v1.4s, v2.4s80; CHECK-NEXT: sqadd v0.4s, v0.4s, v1.4s81; CHECK-NEXT: ret82 %prod = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %mhs, <4 x i32> %rhs)83 %retval = call <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> %acc, <4 x i32> %prod)84 ret <4 x i32> %retval85}86 87define <4 x i16> @test_sqrdmlsh_v4i16(<4 x i16> %acc, <4 x i16> %mhs, <4 x i16> %rhs) {88; CHECK-LABEL: test_sqrdmlsh_v4i16:89; CHECK: // %bb.0:90; CHECK-NEXT: sqrdmulh v1.4h, v1.4h, v2.4h91; CHECK-NEXT: sqsub v0.4h, v0.4h, v1.4h92; CHECK-NEXT: ret93 %prod = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %mhs, <4 x i16> %rhs)94 %retval = call <4 x i16> @llvm.aarch64.neon.sqsub.v4i16(<4 x i16> %acc, <4 x i16> %prod)95 ret <4 x i16> %retval96}97 98define <8 x i16> @test_sqrdmlsh_v8i16(<8 x i16> %acc, <8 x i16> %mhs, <8 x i16> %rhs) {99; CHECK-LABEL: test_sqrdmlsh_v8i16:100; CHECK: // %bb.0:101; CHECK-NEXT: sqrdmulh v1.8h, v1.8h, v2.8h102; CHECK-NEXT: sqsub v0.8h, v0.8h, v1.8h103; CHECK-NEXT: ret104 %prod = call <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16> %mhs, <8 x i16> %rhs)105 %retval = call <8 x i16> @llvm.aarch64.neon.sqsub.v8i16(<8 x i16> %acc, <8 x i16> %prod)106 ret <8 x i16> %retval107}108 109define <2 x i32> @test_sqrdmlsh_v2i32(<2 x i32> %acc, <2 x i32> %mhs, <2 x i32> %rhs) {110; CHECK-LABEL: test_sqrdmlsh_v2i32:111; CHECK: // %bb.0:112; CHECK-NEXT: sqrdmulh v1.2s, v1.2s, v2.2s113; CHECK-NEXT: sqsub v0.2s, v0.2s, v1.2s114; CHECK-NEXT: ret115 %prod = call <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32> %mhs, <2 x i32> %rhs)116 %retval = call <2 x i32> @llvm.aarch64.neon.sqsub.v2i32(<2 x i32> %acc, <2 x i32> %prod)117 ret <2 x i32> %retval118}119 120define <4 x i32> @test_sqrdmlsh_v4i32(<4 x i32> %acc, <4 x i32> %mhs, <4 x i32> %rhs) {121; CHECK-LABEL: test_sqrdmlsh_v4i32:122; CHECK: // %bb.0:123; CHECK-NEXT: sqrdmulh v1.4s, v1.4s, v2.4s124; CHECK-NEXT: sqsub v0.4s, v0.4s, v1.4s125; CHECK-NEXT: ret126 %prod = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %mhs, <4 x i32> %rhs)127 %retval = call <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32> %acc, <4 x i32> %prod)128 ret <4 x i32> %retval129}130 131;-----------------------------------------------------------------------------132; RDMA Vector, by element133; tests for vXiYY_indexed in SIMDIndexedSQRDMLxHSDTied134 135define <4 x i16> @test_sqrdmlah_lane_s16(<4 x i16> %acc, <4 x i16> %x, <4 x i16> %v) {136; CHECK-LABEL: test_sqrdmlah_lane_s16:137; CHECK: // %bb.0: // %entry138; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2139; CHECK-NEXT: sqrdmulh v1.4h, v1.4h, v2.h[3]140; CHECK-NEXT: sqadd v0.4h, v0.4h, v1.4h141; CHECK-NEXT: ret142entry:143 %shuffle = shufflevector <4 x i16> %v, <4 x i16> undef, <4 x i32> <i32 3, i32 3, i32 3, i32 3>144 %prod = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %x, <4 x i16> %shuffle)145 %retval = call <4 x i16> @llvm.aarch64.neon.sqadd.v4i16(<4 x i16> %acc, <4 x i16> %prod)146 ret <4 x i16> %retval147}148 149define <8 x i16> @test_sqrdmlahq_lane_s16(<8 x i16> %acc, <8 x i16> %x, <8 x i16> %v) {150; CHECK-LABEL: test_sqrdmlahq_lane_s16:151; CHECK: // %bb.0: // %entry152; CHECK-NEXT: sqrdmulh v1.8h, v1.8h, v2.h[2]153; CHECK-NEXT: sqadd v0.8h, v0.8h, v1.8h154; CHECK-NEXT: ret155entry:156 %shuffle = shufflevector <8 x i16> %v, <8 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>157 %prod = call <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16> %x, <8 x i16> %shuffle)158 %retval = call <8 x i16> @llvm.aarch64.neon.sqadd.v8i16(<8 x i16> %acc, <8 x i16> %prod)159 ret <8 x i16> %retval160}161 162define <2 x i32> @test_sqrdmlah_lane_s32(<2 x i32> %acc, <2 x i32> %x, <2 x i32> %v) {163; CHECK-LABEL: test_sqrdmlah_lane_s32:164; CHECK: // %bb.0: // %entry165; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2166; CHECK-NEXT: sqrdmulh v1.2s, v1.2s, v2.s[1]167; CHECK-NEXT: sqadd v0.2s, v0.2s, v1.2s168; CHECK-NEXT: ret169entry:170 %shuffle = shufflevector <2 x i32> %v, <2 x i32> undef, <2 x i32> <i32 1, i32 1>171 %prod = call <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32> %x, <2 x i32> %shuffle)172 %retval = call <2 x i32> @llvm.aarch64.neon.sqadd.v2i32(<2 x i32> %acc, <2 x i32> %prod)173 ret <2 x i32> %retval174}175 176define <4 x i32> @test_sqrdmlahq_lane_s32(<4 x i32> %acc,<4 x i32> %x, <4 x i32> %v) {177; CHECK-LABEL: test_sqrdmlahq_lane_s32:178; CHECK: // %bb.0: // %entry179; CHECK-NEXT: sqrdmulh v1.4s, v1.4s, v2.s[0]180; CHECK-NEXT: sqadd v0.4s, v0.4s, v1.4s181; CHECK-NEXT: ret182entry:183 %shuffle = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> zeroinitializer184 %prod = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %x, <4 x i32> %shuffle)185 %retval = call <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> %acc, <4 x i32> %prod)186 ret <4 x i32> %retval187}188 189define <4 x i16> @test_sqrdmlsh_lane_s16(<4 x i16> %acc, <4 x i16> %x, <4 x i16> %v) {190; CHECK-LABEL: test_sqrdmlsh_lane_s16:191; CHECK: // %bb.0: // %entry192; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2193; CHECK-NEXT: sqrdmulh v1.4h, v1.4h, v2.h[3]194; CHECK-NEXT: sqsub v0.4h, v0.4h, v1.4h195; CHECK-NEXT: ret196entry:197 %shuffle = shufflevector <4 x i16> %v, <4 x i16> undef, <4 x i32> <i32 3, i32 3, i32 3, i32 3>198 %prod = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %x, <4 x i16> %shuffle)199 %retval = call <4 x i16> @llvm.aarch64.neon.sqsub.v4i16(<4 x i16> %acc, <4 x i16> %prod)200 ret <4 x i16> %retval201}202 203define <8 x i16> @test_sqrdmlshq_lane_s16(<8 x i16> %acc, <8 x i16> %x, <8 x i16> %v) {204; CHECK-LABEL: test_sqrdmlshq_lane_s16:205; CHECK: // %bb.0: // %entry206; CHECK-NEXT: sqrdmulh v1.8h, v1.8h, v2.h[2]207; CHECK-NEXT: sqsub v0.8h, v0.8h, v1.8h208; CHECK-NEXT: ret209entry:210 %shuffle = shufflevector <8 x i16> %v, <8 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>211 %prod = call <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16> %x, <8 x i16> %shuffle)212 %retval = call <8 x i16> @llvm.aarch64.neon.sqsub.v8i16(<8 x i16> %acc, <8 x i16> %prod)213 ret <8 x i16> %retval214}215 216define <2 x i32> @test_sqrdmlsh_lane_s32(<2 x i32> %acc, <2 x i32> %x, <2 x i32> %v) {217; CHECK-LABEL: test_sqrdmlsh_lane_s32:218; CHECK: // %bb.0: // %entry219; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2220; CHECK-NEXT: sqrdmulh v1.2s, v1.2s, v2.s[1]221; CHECK-NEXT: sqsub v0.2s, v0.2s, v1.2s222; CHECK-NEXT: ret223entry:224 %shuffle = shufflevector <2 x i32> %v, <2 x i32> undef, <2 x i32> <i32 1, i32 1>225 %prod = call <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32> %x, <2 x i32> %shuffle)226 %retval = call <2 x i32> @llvm.aarch64.neon.sqsub.v2i32(<2 x i32> %acc, <2 x i32> %prod)227 ret <2 x i32> %retval228}229 230define <4 x i32> @test_sqrdmlshq_lane_s32(<4 x i32> %acc,<4 x i32> %x, <4 x i32> %v) {231; CHECK-LABEL: test_sqrdmlshq_lane_s32:232; CHECK: // %bb.0: // %entry233; CHECK-NEXT: sqrdmulh v1.4s, v1.4s, v2.s[0]234; CHECK-NEXT: sqsub v0.4s, v0.4s, v1.4s235; CHECK-NEXT: ret236entry:237 %shuffle = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> zeroinitializer238 %prod = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %x, <4 x i32> %shuffle)239 %retval = call <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32> %acc, <4 x i32> %prod)240 ret <4 x i32> %retval241}242 243;-----------------------------------------------------------------------------244; RDMA Vector, by element, extracted245; i16 tests are for vXi16_indexed in SIMDIndexedSQRDMLxHSDTied, with IR in ACLE style246; i32 tests are for "def : Pat" in SIMDIndexedSQRDMLxHSDTied247 248define i16 @test_sqrdmlah_extracted_lane_s16(i16 %acc,<4 x i16> %x, <4 x i16> %v) {249; CHECK-LABEL: test_sqrdmlah_extracted_lane_s16:250; CHECK: // %bb.0: // %entry251; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1252; CHECK-NEXT: sqrdmulh v0.4h, v0.4h, v1.h[1]253; CHECK-NEXT: fmov s1, w0254; CHECK-NEXT: sqadd v0.4h, v1.4h, v0.4h255; CHECK-NEXT: umov w0, v0.h[0]256; CHECK-NEXT: ret257entry:258 %shuffle = shufflevector <4 x i16> %v, <4 x i16> undef, <4 x i32> <i32 1,i32 1,i32 1,i32 1>259 %prod = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %x, <4 x i16> %shuffle)260 %acc_vec = insertelement <4 x i16> undef, i16 %acc, i64 0261 %retval_vec = call <4 x i16> @llvm.aarch64.neon.sqadd.v4i16(<4 x i16> %acc_vec, <4 x i16> %prod)262 %retval = extractelement <4 x i16> %retval_vec, i64 0263 ret i16 %retval264}265 266define i16 @test_sqrdmlahq_extracted_lane_s16(i16 %acc,<8 x i16> %x, <8 x i16> %v) {267; CHECK-LABEL: test_sqrdmlahq_extracted_lane_s16:268; CHECK: // %bb.0: // %entry269; CHECK-NEXT: sqrdmulh v0.8h, v0.8h, v1.h[1]270; CHECK-NEXT: fmov s1, w0271; CHECK-NEXT: sqadd v0.8h, v1.8h, v0.8h272; CHECK-NEXT: umov w0, v0.h[0]273; CHECK-NEXT: ret274entry:275 %shuffle = shufflevector <8 x i16> %v, <8 x i16> undef, <8 x i32> <i32 1,i32 1,i32 1,i32 1, i32 1,i32 1,i32 1,i32 1>276 %prod = call <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16> %x, <8 x i16> %shuffle)277 %acc_vec = insertelement <8 x i16> undef, i16 %acc, i64 0278 %retval_vec = call <8 x i16> @llvm.aarch64.neon.sqadd.v8i16(<8 x i16> %acc_vec, <8 x i16> %prod)279 %retval = extractelement <8 x i16> %retval_vec, i64 0280 ret i16 %retval281}282 283define i32 @test_sqrdmlah_extracted_lane_s32(i32 %acc,<2 x i32> %x, <2 x i32> %v) {284; CHECK-LABEL: test_sqrdmlah_extracted_lane_s32:285; CHECK: // %bb.0: // %entry286; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1287; CHECK-NEXT: sqrdmulh v0.2s, v0.2s, v1.s[0]288; CHECK-NEXT: fmov s1, w0289; CHECK-NEXT: sqadd s0, s1, s0290; CHECK-NEXT: fmov w0, s0291; CHECK-NEXT: ret292entry:293 %shuffle = shufflevector <2 x i32> %v, <2 x i32> undef, <2 x i32> zeroinitializer294 %prod = call <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32> %x, <2 x i32> %shuffle)295 %extract = extractelement <2 x i32> %prod, i64 0296 %retval = call i32 @llvm.aarch64.neon.sqadd.i32(i32 %acc, i32 %extract)297 ret i32 %retval298}299 300define i32 @test_sqrdmlahq_extracted_lane_s32(i32 %acc,<4 x i32> %x, <4 x i32> %v) {301; CHECK-LABEL: test_sqrdmlahq_extracted_lane_s32:302; CHECK: // %bb.0: // %entry303; CHECK-NEXT: sqrdmulh v0.4s, v0.4s, v1.s[0]304; CHECK-NEXT: fmov s1, w0305; CHECK-NEXT: sqadd s0, s1, s0306; CHECK-NEXT: fmov w0, s0307; CHECK-NEXT: ret308entry:309 %shuffle = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> zeroinitializer310 %prod = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %x, <4 x i32> %shuffle)311 %extract = extractelement <4 x i32> %prod, i64 0312 %retval = call i32 @llvm.aarch64.neon.sqadd.i32(i32 %acc, i32 %extract)313 ret i32 %retval314}315 316define i16 @test_sqrdmlsh_extracted_lane_s16(i16 %acc,<4 x i16> %x, <4 x i16> %v) {317; CHECK-LABEL: test_sqrdmlsh_extracted_lane_s16:318; CHECK: // %bb.0: // %entry319; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1320; CHECK-NEXT: sqrdmulh v0.4h, v0.4h, v1.h[1]321; CHECK-NEXT: fmov s1, w0322; CHECK-NEXT: sqsub v0.4h, v1.4h, v0.4h323; CHECK-NEXT: umov w0, v0.h[0]324; CHECK-NEXT: ret325entry:326 %shuffle = shufflevector <4 x i16> %v, <4 x i16> undef, <4 x i32> <i32 1,i32 1,i32 1,i32 1>327 %prod = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %x, <4 x i16> %shuffle)328 %acc_vec = insertelement <4 x i16> undef, i16 %acc, i64 0329 %retval_vec = call <4 x i16> @llvm.aarch64.neon.sqsub.v4i16(<4 x i16> %acc_vec, <4 x i16> %prod)330 %retval = extractelement <4 x i16> %retval_vec, i64 0331 ret i16 %retval332}333 334define i16 @test_sqrdmlshq_extracted_lane_s16(i16 %acc,<8 x i16> %x, <8 x i16> %v) {335; CHECK-LABEL: test_sqrdmlshq_extracted_lane_s16:336; CHECK: // %bb.0: // %entry337; CHECK-NEXT: sqrdmulh v0.8h, v0.8h, v1.h[1]338; CHECK-NEXT: fmov s1, w0339; CHECK-NEXT: sqsub v0.8h, v1.8h, v0.8h340; CHECK-NEXT: umov w0, v0.h[0]341; CHECK-NEXT: ret342entry:343 %shuffle = shufflevector <8 x i16> %v, <8 x i16> undef, <8 x i32> <i32 1,i32 1,i32 1,i32 1, i32 1,i32 1,i32 1,i32 1>344 %prod = call <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16> %x, <8 x i16> %shuffle)345 %acc_vec = insertelement <8 x i16> undef, i16 %acc, i64 0346 %retval_vec = call <8 x i16> @llvm.aarch64.neon.sqsub.v8i16(<8 x i16> %acc_vec, <8 x i16> %prod)347 %retval = extractelement <8 x i16> %retval_vec, i64 0348 ret i16 %retval349}350 351define i32 @test_sqrdmlsh_extracted_lane_s32(i32 %acc,<2 x i32> %x, <2 x i32> %v) {352; CHECK-LABEL: test_sqrdmlsh_extracted_lane_s32:353; CHECK: // %bb.0: // %entry354; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1355; CHECK-NEXT: sqrdmulh v0.2s, v0.2s, v1.s[0]356; CHECK-NEXT: fmov s1, w0357; CHECK-NEXT: sqsub s0, s1, s0358; CHECK-NEXT: fmov w0, s0359; CHECK-NEXT: ret360entry:361 %shuffle = shufflevector <2 x i32> %v, <2 x i32> undef, <2 x i32> zeroinitializer362 %prod = call <2 x i32> @llvm.aarch64.neon.sqrdmulh.v2i32(<2 x i32> %x, <2 x i32> %shuffle)363 %extract = extractelement <2 x i32> %prod, i64 0364 %retval = call i32 @llvm.aarch64.neon.sqsub.i32(i32 %acc, i32 %extract)365 ret i32 %retval366}367 368define i32 @test_sqrdmlshq_extracted_lane_s32(i32 %acc,<4 x i32> %x, <4 x i32> %v) {369; CHECK-LABEL: test_sqrdmlshq_extracted_lane_s32:370; CHECK: // %bb.0: // %entry371; CHECK-NEXT: sqrdmulh v0.4s, v0.4s, v1.s[0]372; CHECK-NEXT: fmov s1, w0373; CHECK-NEXT: sqsub s0, s1, s0374; CHECK-NEXT: fmov w0, s0375; CHECK-NEXT: ret376entry:377 %shuffle = shufflevector <4 x i32> %v, <4 x i32> undef, <4 x i32> zeroinitializer378 %prod = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %x, <4 x i32> %shuffle)379 %extract = extractelement <4 x i32> %prod, i64 0380 %retval = call i32 @llvm.aarch64.neon.sqsub.i32(i32 %acc, i32 %extract)381 ret i32 %retval382}383 384;-----------------------------------------------------------------------------385; RDMA Scalar386; test for "def : Pat" near SIMDThreeScalarHSTied in AArch64InstInfo.td387 388define i16 @test_sqrdmlah_v1i16(i16 %acc, i16 %x, i16 %y) {389; CHECK-LABEL: test_sqrdmlah_v1i16:390; CHECK: // %bb.0:391; CHECK-NEXT: fmov s0, w1392; CHECK-NEXT: fmov s1, w2393; CHECK-NEXT: sqrdmulh v0.4h, v0.4h, v1.4h394; CHECK-NEXT: fmov s1, w0395; CHECK-NEXT: sqadd v0.4h, v1.4h, v0.4h396; CHECK-NEXT: umov w0, v0.h[0]397; CHECK-NEXT: ret398 %x_vec = insertelement <4 x i16> undef, i16 %x, i64 0399 %y_vec = insertelement <4 x i16> undef, i16 %y, i64 0400 %prod_vec = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %x_vec, <4 x i16> %y_vec)401 %acc_vec = insertelement <4 x i16> undef, i16 %acc, i64 0402 %retval_vec = call <4 x i16> @llvm.aarch64.neon.sqadd.v4i16(<4 x i16> %acc_vec, <4 x i16> %prod_vec)403 %retval = extractelement <4 x i16> %retval_vec, i64 0404 ret i16 %retval405}406 407define i32 @test_sqrdmlah_v1i32(i32 %acc, i32 %x, i32 %y) {408; CHECK-LABEL: test_sqrdmlah_v1i32:409; CHECK: // %bb.0:410; CHECK-NEXT: fmov s0, w1411; CHECK-NEXT: fmov s1, w2412; CHECK-NEXT: sqrdmulh v0.4s, v0.4s, v1.4s413; CHECK-NEXT: fmov s1, w0414; CHECK-NEXT: sqadd v0.4s, v1.4s, v0.4s415; CHECK-NEXT: fmov w0, s0416; CHECK-NEXT: ret417 %x_vec = insertelement <4 x i32> undef, i32 %x, i64 0418 %y_vec = insertelement <4 x i32> undef, i32 %y, i64 0419 %prod_vec = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %x_vec, <4 x i32> %y_vec)420 %acc_vec = insertelement <4 x i32> undef, i32 %acc, i64 0421 %retval_vec = call <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> %acc_vec, <4 x i32> %prod_vec)422 %retval = extractelement <4 x i32> %retval_vec, i64 0423 ret i32 %retval424}425 426 427define i16 @test_sqrdmlsh_v1i16(i16 %acc, i16 %x, i16 %y) {428; CHECK-LABEL: test_sqrdmlsh_v1i16:429; CHECK: // %bb.0:430; CHECK-NEXT: fmov s0, w1431; CHECK-NEXT: fmov s1, w2432; CHECK-NEXT: sqrdmulh v0.4h, v0.4h, v1.4h433; CHECK-NEXT: fmov s1, w0434; CHECK-NEXT: sqsub v0.4h, v1.4h, v0.4h435; CHECK-NEXT: umov w0, v0.h[0]436; CHECK-NEXT: ret437 %x_vec = insertelement <4 x i16> undef, i16 %x, i64 0438 %y_vec = insertelement <4 x i16> undef, i16 %y, i64 0439 %prod_vec = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %x_vec, <4 x i16> %y_vec)440 %acc_vec = insertelement <4 x i16> undef, i16 %acc, i64 0441 %retval_vec = call <4 x i16> @llvm.aarch64.neon.sqsub.v4i16(<4 x i16> %acc_vec, <4 x i16> %prod_vec)442 %retval = extractelement <4 x i16> %retval_vec, i64 0443 ret i16 %retval444}445 446define i32 @test_sqrdmlsh_v1i32(i32 %acc, i32 %x, i32 %y) {447; CHECK-LABEL: test_sqrdmlsh_v1i32:448; CHECK: // %bb.0:449; CHECK-NEXT: fmov s0, w1450; CHECK-NEXT: fmov s1, w2451; CHECK-NEXT: sqrdmulh v0.4s, v0.4s, v1.4s452; CHECK-NEXT: fmov s1, w0453; CHECK-NEXT: sqsub v0.4s, v1.4s, v0.4s454; CHECK-NEXT: fmov w0, s0455; CHECK-NEXT: ret456 %x_vec = insertelement <4 x i32> undef, i32 %x, i64 0457 %y_vec = insertelement <4 x i32> undef, i32 %y, i64 0458 %prod_vec = call <4 x i32> @llvm.aarch64.neon.sqrdmulh.v4i32(<4 x i32> %x_vec, <4 x i32> %y_vec)459 %acc_vec = insertelement <4 x i32> undef, i32 %acc, i64 0460 %retval_vec = call <4 x i32> @llvm.aarch64.neon.sqsub.v4i32(<4 x i32> %acc_vec, <4 x i32> %prod_vec)461 %retval = extractelement <4 x i32> %retval_vec, i64 0462 ret i32 %retval463}464 465define i32 @test_sqrdmlah_i32(i32 %acc, i32 %mhs, i32 %rhs) {466; CHECK-LABEL: test_sqrdmlah_i32:467; CHECK: // %bb.0:468; CHECK-NEXT: fmov s0, w1469; CHECK-NEXT: fmov s1, w2470; CHECK-NEXT: sqrdmulh s0, s0, s1471; CHECK-NEXT: fmov s1, w0472; CHECK-NEXT: sqadd s0, s1, s0473; CHECK-NEXT: fmov w0, s0474; CHECK-NEXT: ret475 %prod = call i32 @llvm.aarch64.neon.sqrdmulh.i32(i32 %mhs, i32 %rhs)476 %retval = call i32 @llvm.aarch64.neon.sqadd.i32(i32 %acc, i32 %prod)477 ret i32 %retval478}479 480define i32 @test_sqrdmlsh_i32(i32 %acc, i32 %mhs, i32 %rhs) {481; CHECK-LABEL: test_sqrdmlsh_i32:482; CHECK: // %bb.0:483; CHECK-NEXT: fmov s0, w1484; CHECK-NEXT: fmov s1, w2485; CHECK-NEXT: sqrdmulh s0, s0, s1486; CHECK-NEXT: fmov s1, w0487; CHECK-NEXT: sqsub s0, s1, s0488; CHECK-NEXT: fmov w0, s0489; CHECK-NEXT: ret490 %prod = call i32 @llvm.aarch64.neon.sqrdmulh.i32(i32 %mhs, i32 %rhs)491 %retval = call i32 @llvm.aarch64.neon.sqsub.i32(i32 %acc, i32 %prod)492 ret i32 %retval493}494 495;-----------------------------------------------------------------------------496; RDMA Scalar, by element497; i16 tests are performed via tests in above chapter, with IR in ACLE style498; i32 tests are for v1i32_indexed in SIMDIndexedSQRDMLxHSDTied499 500define i16 @test_sqrdmlah_extract_i16(i16 %acc, i16 %x, <4 x i16> %y_vec) {501; CHECK-LABEL: test_sqrdmlah_extract_i16:502; CHECK: // %bb.0:503; CHECK-NEXT: fmov s1, w1504; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0505; CHECK-NEXT: sqrdmulh v0.4h, v1.4h, v0.h[1]506; CHECK-NEXT: fmov s1, w0507; CHECK-NEXT: sqadd v0.4h, v1.4h, v0.4h508; CHECK-NEXT: umov w0, v0.h[0]509; CHECK-NEXT: ret510 %shuffle = shufflevector <4 x i16> %y_vec, <4 x i16> undef, <4 x i32> <i32 1,i32 1,i32 1,i32 1>511 %x_vec = insertelement <4 x i16> undef, i16 %x, i64 0512 %prod = call <4 x i16> @llvm.aarch64.neon.sqrdmulh.v4i16(<4 x i16> %x_vec, <4 x i16> %shuffle)513 %acc_vec = insertelement <4 x i16> undef, i16 %acc, i64 0514 %retval_vec = call <4 x i16> @llvm.aarch64.neon.sqadd.v4i16(<4 x i16> %acc_vec, <4 x i16> %prod)515 %retval = extractelement <4 x i16> %retval_vec, i32 0516 ret i16 %retval517}518 519define i32 @test_sqrdmlah_extract_i32(i32 %acc, i32 %mhs, <4 x i32> %rhs) {520; CHECK-LABEL: test_sqrdmlah_extract_i32:521; CHECK: // %bb.0:522; CHECK-NEXT: fmov s1, w1523; CHECK-NEXT: sqrdmulh s0, s1, v0.s[3]524; CHECK-NEXT: fmov s1, w0525; CHECK-NEXT: sqadd s0, s1, s0526; CHECK-NEXT: fmov w0, s0527; CHECK-NEXT: ret528 %extract = extractelement <4 x i32> %rhs, i32 3529 %prod = call i32 @llvm.aarch64.neon.sqrdmulh.i32(i32 %mhs, i32 %extract)530 %retval = call i32 @llvm.aarch64.neon.sqadd.i32(i32 %acc, i32 %prod)531 ret i32 %retval532}533 534define i16 @test_sqrdmlshq_extract_i16(i16 %acc, i16 %x, <8 x i16> %y_vec) {535; CHECK-LABEL: test_sqrdmlshq_extract_i16:536; CHECK: // %bb.0:537; CHECK-NEXT: fmov s1, w1538; CHECK-NEXT: sqrdmulh v0.8h, v1.8h, v0.h[1]539; CHECK-NEXT: fmov s1, w0540; CHECK-NEXT: sqsub v0.8h, v1.8h, v0.8h541; CHECK-NEXT: umov w0, v0.h[0]542; CHECK-NEXT: ret543 %shuffle = shufflevector <8 x i16> %y_vec, <8 x i16> undef, <8 x i32> <i32 1,i32 1,i32 1,i32 1,i32 1,i32 1,i32 1,i32 1>544 %x_vec = insertelement <8 x i16> undef, i16 %x, i64 0545 %prod = call <8 x i16> @llvm.aarch64.neon.sqrdmulh.v8i16(<8 x i16> %x_vec, <8 x i16> %shuffle)546 %acc_vec = insertelement <8 x i16> undef, i16 %acc, i64 0547 %retval_vec = call <8 x i16> @llvm.aarch64.neon.sqsub.v8i16(<8 x i16> %acc_vec, <8 x i16> %prod)548 %retval = extractelement <8 x i16> %retval_vec, i32 0549 ret i16 %retval550}551 552define i32 @test_sqrdmlsh_extract_i32(i32 %acc, i32 %mhs, <4 x i32> %rhs) {553; CHECK-LABEL: test_sqrdmlsh_extract_i32:554; CHECK: // %bb.0:555; CHECK-NEXT: fmov s1, w1556; CHECK-NEXT: sqrdmulh s0, s1, v0.s[3]557; CHECK-NEXT: fmov s1, w0558; CHECK-NEXT: sqsub s0, s1, s0559; CHECK-NEXT: fmov w0, s0560; CHECK-NEXT: ret561 %extract = extractelement <4 x i32> %rhs, i32 3562 %prod = call i32 @llvm.aarch64.neon.sqrdmulh.i32(i32 %mhs, i32 %extract)563 %retval = call i32 @llvm.aarch64.neon.sqsub.i32(i32 %acc, i32 %prod)564 ret i32 %retval565}566 567 568;-----------------------------------------------------------------------------569; Using sqrdmlah intrinsics570 571define <4 x i16> @test_vqrdmlah_laneq_s16(<4 x i16> %a, <4 x i16> %b, <8 x i16> %v) {572; CHECK-LABEL: test_vqrdmlah_laneq_s16:573; CHECK: // %bb.0: // %entry574; CHECK-NEXT: sqrdmlah v0.4h, v1.4h, v2.h[7]575; CHECK-NEXT: ret576entry:577 %lane = shufflevector <8 x i16> %v, <8 x i16> poison, <4 x i32> <i32 7, i32 7, i32 7, i32 7>578 %vqrdmlah_v3.i = tail call <4 x i16> @llvm.aarch64.neon.sqrdmlah.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %lane) #4579 ret <4 x i16> %vqrdmlah_v3.i580}581 582define <2 x i32> @test_vqrdmlah_laneq_s32(<2 x i32> %a, <2 x i32> %b, <4 x i32> %v) {583; CHECK-LABEL: test_vqrdmlah_laneq_s32:584; CHECK: // %bb.0: // %entry585; CHECK-NEXT: sqrdmlah v0.2s, v1.2s, v2.s[3]586; CHECK-NEXT: ret587entry:588 %lane = shufflevector <4 x i32> %v, <4 x i32> poison, <2 x i32> <i32 3, i32 3>589 %vqrdmlah_v3.i = tail call <2 x i32> @llvm.aarch64.neon.sqrdmlah.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %lane) #4590 ret <2 x i32> %vqrdmlah_v3.i591}592 593define <8 x i16> @test_vqrdmlahq_laneq_s16(<8 x i16> %a, <8 x i16> %b, <8 x i16> %v) {594; CHECK-LABEL: test_vqrdmlahq_laneq_s16:595; CHECK: // %bb.0: // %entry596; CHECK-NEXT: sqrdmlah v0.8h, v1.8h, v2.h[7]597; CHECK-NEXT: ret598entry:599 %lane = shufflevector <8 x i16> %v, <8 x i16> poison, <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7>600 %vqrdmlahq_v3.i = tail call <8 x i16> @llvm.aarch64.neon.sqrdmlah.v8i16(<8 x i16> %a, <8 x i16> %b, <8 x i16> %lane) #4601 ret <8 x i16> %vqrdmlahq_v3.i602}603 604define <4 x i32> @test_vqrdmlahq_laneq_s32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %v) {605; CHECK-LABEL: test_vqrdmlahq_laneq_s32:606; CHECK: // %bb.0: // %entry607; CHECK-NEXT: sqrdmlah v0.4s, v1.4s, v2.s[3]608; CHECK-NEXT: ret609entry:610 %lane = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3>611 %vqrdmlahq_v3.i = tail call <4 x i32> @llvm.aarch64.neon.sqrdmlah.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %lane) #4612 ret <4 x i32> %vqrdmlahq_v3.i613}614 615define i16 @test_vqrdmlahh_s16(i16 %a, i16 %b, i16 %c) {616; CHECK-LABEL: test_vqrdmlahh_s16:617; CHECK: // %bb.0: // %entry618; CHECK-NEXT: fmov s0, w0619; CHECK-NEXT: fmov s1, w1620; CHECK-NEXT: fmov s2, w2621; CHECK-NEXT: sqrdmlah v0.4h, v1.4h, v2.4h622; CHECK-NEXT: umov w0, v0.h[0]623; CHECK-NEXT: ret624entry:625 %0 = insertelement <4 x i16> undef, i16 %a, i64 0626 %1 = insertelement <4 x i16> undef, i16 %b, i64 0627 %2 = insertelement <4 x i16> undef, i16 %c, i64 0628 %vqrdmlahh_s16.i = tail call <4 x i16> @llvm.aarch64.neon.sqrdmlah.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) #4629 %3 = extractelement <4 x i16> %vqrdmlahh_s16.i, i64 0630 ret i16 %3631}632 633define i32 @test_vqrdmlahs_s32(i32 %a, i32 %b, i32 %c) {634; CHECK-LABEL: test_vqrdmlahs_s32:635; CHECK: // %bb.0: // %entry636; CHECK-NEXT: fmov s0, w0637; CHECK-NEXT: fmov s1, w1638; CHECK-NEXT: fmov s2, w2639; CHECK-NEXT: sqrdmlah s0, s1, s2640; CHECK-NEXT: fmov w0, s0641; CHECK-NEXT: ret642entry:643 %vqrdmlahs_s32.i = tail call i32 @llvm.aarch64.neon.sqrdmlah.i32(i32 %a, i32 %b, i32 %c) #4644 ret i32 %vqrdmlahs_s32.i645}646 647define i16 @test_vqrdmlahh_lane_s16(i16 %a, i16 %b, <4 x i16> %c) {648; CHECK-LABEL: test_vqrdmlahh_lane_s16:649; CHECK: // %bb.0: // %entry650; CHECK-NEXT: fmov s1, w0651; CHECK-NEXT: fmov s2, w1652; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0653; CHECK-NEXT: sqrdmlah v1.4h, v2.4h, v0.h[3]654; CHECK-NEXT: umov w0, v1.h[0]655; CHECK-NEXT: ret656entry:657 %0 = insertelement <4 x i16> undef, i16 %a, i64 0658 %1 = insertelement <4 x i16> undef, i16 %b, i64 0659 %2 = shufflevector <4 x i16> %c, <4 x i16> undef, <4 x i32> <i32 3, i32 undef, i32 undef, i32 undef>660 %vqrdmlahh_s16.i = tail call <4 x i16> @llvm.aarch64.neon.sqrdmlah.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) #4661 %3 = extractelement <4 x i16> %vqrdmlahh_s16.i, i64 0662 ret i16 %3663}664 665define i32 @test_vqrdmlahs_lane_s32(i32 %a, i32 %b, <2 x i32> %c) {666; CHECK-SD-LABEL: test_vqrdmlahs_lane_s32:667; CHECK-SD: // %bb.0: // %entry668; CHECK-SD-NEXT: fmov s1, w0669; CHECK-SD-NEXT: fmov s2, w1670; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0671; CHECK-SD-NEXT: sqrdmlah s1, s2, v0.s[1]672; CHECK-SD-NEXT: fmov w0, s1673; CHECK-SD-NEXT: ret674;675; CHECK-GI-LABEL: test_vqrdmlahs_lane_s32:676; CHECK-GI: // %bb.0: // %entry677; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0678; CHECK-GI-NEXT: fmov s1, w0679; CHECK-GI-NEXT: fmov s2, w1680; CHECK-GI-NEXT: mov s0, v0.s[1]681; CHECK-GI-NEXT: sqrdmlah s1, s2, s0682; CHECK-GI-NEXT: fmov w0, s1683; CHECK-GI-NEXT: ret684entry:685 %vget_lane = extractelement <2 x i32> %c, i64 1686 %vqrdmlahs_s32.i = tail call i32 @llvm.aarch64.neon.sqrdmlah.i32(i32 %a, i32 %b, i32 %vget_lane) #4687 ret i32 %vqrdmlahs_s32.i688}689 690define i16 @test_vqrdmlahh_laneq_s16(i16 %a, i16 %b, <8 x i16> %c) {691; CHECK-LABEL: test_vqrdmlahh_laneq_s16:692; CHECK: // %bb.0: // %entry693; CHECK-NEXT: fmov s1, w0694; CHECK-NEXT: fmov s2, w1695; CHECK-NEXT: sqrdmlah v1.4h, v2.4h, v0.h[7]696; CHECK-NEXT: umov w0, v1.h[0]697; CHECK-NEXT: ret698entry:699 %0 = insertelement <4 x i16> undef, i16 %a, i64 0700 %1 = insertelement <4 x i16> undef, i16 %b, i64 0701 %2 = shufflevector <8 x i16> %c, <8 x i16> undef, <4 x i32> <i32 7, i32 undef, i32 undef, i32 undef>702 %vqrdmlahh_s16.i = tail call <4 x i16> @llvm.aarch64.neon.sqrdmlah.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) #4703 %3 = extractelement <4 x i16> %vqrdmlahh_s16.i, i64 0704 ret i16 %3705}706 707define i32 @test_vqrdmlahs_laneq_s32(i32 %a, i32 %b, <4 x i32> %c) {708; CHECK-LABEL: test_vqrdmlahs_laneq_s32:709; CHECK: // %bb.0: // %entry710; CHECK-NEXT: fmov s1, w0711; CHECK-NEXT: fmov s2, w1712; CHECK-NEXT: sqrdmlah s1, s2, v0.s[3]713; CHECK-NEXT: fmov w0, s1714; CHECK-NEXT: ret715entry:716 %vgetq_lane = extractelement <4 x i32> %c, i64 3717 %vqrdmlahs_s32.i = tail call i32 @llvm.aarch64.neon.sqrdmlah.i32(i32 %a, i32 %b, i32 %vgetq_lane) #4718 ret i32 %vqrdmlahs_s32.i719}720 721define <4 x i16> @test_vqrdmlsh_laneq_s16(<4 x i16> %a, <4 x i16> %b, <8 x i16> %v) {722; CHECK-LABEL: test_vqrdmlsh_laneq_s16:723; CHECK: // %bb.0: // %entry724; CHECK-NEXT: sqrdmlsh v0.4h, v1.4h, v2.h[7]725; CHECK-NEXT: ret726entry:727 %lane = shufflevector <8 x i16> %v, <8 x i16> poison, <4 x i32> <i32 7, i32 7, i32 7, i32 7>728 %vqrdmlsh_v3.i = tail call <4 x i16> @llvm.aarch64.neon.sqrdmlsh.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %lane) #4729 ret <4 x i16> %vqrdmlsh_v3.i730}731 732define <2 x i32> @test_vqrdmlsh_laneq_s32(<2 x i32> %a, <2 x i32> %b, <4 x i32> %v) {733; CHECK-LABEL: test_vqrdmlsh_laneq_s32:734; CHECK: // %bb.0: // %entry735; CHECK-NEXT: sqrdmlsh v0.2s, v1.2s, v2.s[3]736; CHECK-NEXT: ret737entry:738 %lane = shufflevector <4 x i32> %v, <4 x i32> poison, <2 x i32> <i32 3, i32 3>739 %vqrdmlsh_v3.i = tail call <2 x i32> @llvm.aarch64.neon.sqrdmlsh.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %lane) #4740 ret <2 x i32> %vqrdmlsh_v3.i741}742 743define <8 x i16> @test_vqrdmlshq_laneq_s16(<8 x i16> %a, <8 x i16> %b, <8 x i16> %v) {744; CHECK-LABEL: test_vqrdmlshq_laneq_s16:745; CHECK: // %bb.0: // %entry746; CHECK-NEXT: sqrdmlsh v0.8h, v1.8h, v2.h[7]747; CHECK-NEXT: ret748entry:749 %lane = shufflevector <8 x i16> %v, <8 x i16> poison, <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7>750 %vqrdmlshq_v3.i = tail call <8 x i16> @llvm.aarch64.neon.sqrdmlsh.v8i16(<8 x i16> %a, <8 x i16> %b, <8 x i16> %lane) #4751 ret <8 x i16> %vqrdmlshq_v3.i752}753 754define <4 x i32> @test_vqrdmlshq_laneq_s32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %v) {755; CHECK-LABEL: test_vqrdmlshq_laneq_s32:756; CHECK: // %bb.0: // %entry757; CHECK-NEXT: sqrdmlsh v0.4s, v1.4s, v2.s[3]758; CHECK-NEXT: ret759entry:760 %lane = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3>761 %vqrdmlshq_v3.i = tail call <4 x i32> @llvm.aarch64.neon.sqrdmlsh.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %lane) #4762 ret <4 x i32> %vqrdmlshq_v3.i763}764 765define i16 @test_vqrdmlshh_s16(i16 %a, i16 %b, i16 %c) {766; CHECK-LABEL: test_vqrdmlshh_s16:767; CHECK: // %bb.0: // %entry768; CHECK-NEXT: fmov s0, w0769; CHECK-NEXT: fmov s1, w1770; CHECK-NEXT: fmov s2, w2771; CHECK-NEXT: sqrdmlsh v0.4h, v1.4h, v2.4h772; CHECK-NEXT: umov w0, v0.h[0]773; CHECK-NEXT: ret774entry:775 %0 = insertelement <4 x i16> undef, i16 %a, i64 0776 %1 = insertelement <4 x i16> undef, i16 %b, i64 0777 %2 = insertelement <4 x i16> undef, i16 %c, i64 0778 %vqrdmlshh_s16.i = tail call <4 x i16> @llvm.aarch64.neon.sqrdmlsh.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) #4779 %3 = extractelement <4 x i16> %vqrdmlshh_s16.i, i64 0780 ret i16 %3781}782 783define i32 @test_vqrdmlshs_s32(i32 %a, i32 %b, i32 %c) {784; CHECK-LABEL: test_vqrdmlshs_s32:785; CHECK: // %bb.0: // %entry786; CHECK-NEXT: fmov s0, w0787; CHECK-NEXT: fmov s1, w1788; CHECK-NEXT: fmov s2, w2789; CHECK-NEXT: sqrdmlsh s0, s1, s2790; CHECK-NEXT: fmov w0, s0791; CHECK-NEXT: ret792entry:793 %vqrdmlshs_s32.i = tail call i32 @llvm.aarch64.neon.sqrdmlsh.i32(i32 %a, i32 %b, i32 %c) #4794 ret i32 %vqrdmlshs_s32.i795}796 797define i16 @test_vqrdmlshh_lane_s16(i16 %a, i16 %b, <4 x i16> %c) {798; CHECK-LABEL: test_vqrdmlshh_lane_s16:799; CHECK: // %bb.0: // %entry800; CHECK-NEXT: fmov s1, w0801; CHECK-NEXT: fmov s2, w1802; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0803; CHECK-NEXT: sqrdmlsh v1.4h, v2.4h, v0.h[3]804; CHECK-NEXT: umov w0, v1.h[0]805; CHECK-NEXT: ret806entry:807 %0 = insertelement <4 x i16> undef, i16 %a, i64 0808 %1 = insertelement <4 x i16> undef, i16 %b, i64 0809 %2 = shufflevector <4 x i16> %c, <4 x i16> undef, <4 x i32> <i32 3, i32 undef, i32 undef, i32 undef>810 %vqrdmlshh_s16.i = tail call <4 x i16> @llvm.aarch64.neon.sqrdmlsh.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) #4811 %3 = extractelement <4 x i16> %vqrdmlshh_s16.i, i64 0812 ret i16 %3813}814 815define i32 @test_vqrdmlshs_lane_s32(i32 %a, i32 %b, <2 x i32> %c) {816; CHECK-SD-LABEL: test_vqrdmlshs_lane_s32:817; CHECK-SD: // %bb.0: // %entry818; CHECK-SD-NEXT: fmov s1, w0819; CHECK-SD-NEXT: fmov s2, w1820; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0821; CHECK-SD-NEXT: sqrdmlsh s1, s2, v0.s[1]822; CHECK-SD-NEXT: fmov w0, s1823; CHECK-SD-NEXT: ret824;825; CHECK-GI-LABEL: test_vqrdmlshs_lane_s32:826; CHECK-GI: // %bb.0: // %entry827; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0828; CHECK-GI-NEXT: fmov s1, w0829; CHECK-GI-NEXT: fmov s2, w1830; CHECK-GI-NEXT: mov s0, v0.s[1]831; CHECK-GI-NEXT: sqrdmlsh s1, s2, s0832; CHECK-GI-NEXT: fmov w0, s1833; CHECK-GI-NEXT: ret834entry:835 %vget_lane = extractelement <2 x i32> %c, i64 1836 %vqrdmlshs_s32.i = tail call i32 @llvm.aarch64.neon.sqrdmlsh.i32(i32 %a, i32 %b, i32 %vget_lane) #4837 ret i32 %vqrdmlshs_s32.i838}839 840define i16 @test_vqrdmlshh_laneq_s16(i16 %a, i16 %b, <8 x i16> %c) {841; CHECK-LABEL: test_vqrdmlshh_laneq_s16:842; CHECK: // %bb.0: // %entry843; CHECK-NEXT: fmov s1, w0844; CHECK-NEXT: fmov s2, w1845; CHECK-NEXT: sqrdmlsh v1.4h, v2.4h, v0.h[7]846; CHECK-NEXT: umov w0, v1.h[0]847; CHECK-NEXT: ret848entry:849 %0 = insertelement <4 x i16> undef, i16 %a, i64 0850 %1 = insertelement <4 x i16> undef, i16 %b, i64 0851 %2 = shufflevector <8 x i16> %c, <8 x i16> undef, <4 x i32> <i32 7, i32 undef, i32 undef, i32 undef>852 %vqrdmlshh_s16.i = tail call <4 x i16> @llvm.aarch64.neon.sqrdmlsh.v4i16(<4 x i16> %0, <4 x i16> %1, <4 x i16> %2) #4853 %3 = extractelement <4 x i16> %vqrdmlshh_s16.i, i64 0854 ret i16 %3855}856 857define i32 @test_vqrdmlshs_laneq_s32(i32 %a, i32 %b, <4 x i32> %c) {858; CHECK-LABEL: test_vqrdmlshs_laneq_s32:859; CHECK: // %bb.0: // %entry860; CHECK-NEXT: fmov s1, w0861; CHECK-NEXT: fmov s2, w1862; CHECK-NEXT: sqrdmlsh s1, s2, v0.s[3]863; CHECK-NEXT: fmov w0, s1864; CHECK-NEXT: ret865entry:866 %vgetq_lane = extractelement <4 x i32> %c, i64 3867 %vqrdmlshs_s32.i = tail call i32 @llvm.aarch64.neon.sqrdmlsh.i32(i32 %a, i32 %b, i32 %vgetq_lane) #4868 ret i32 %vqrdmlshs_s32.i869}870