1354 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 42; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc < %s -mtriple=arm64-eabi -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5define <8 x i8> @addhn8b(ptr %A, ptr %B) nounwind {6; CHECK-LABEL: addhn8b:7; CHECK: // %bb.0:8; CHECK-NEXT: ldr q0, [x0]9; CHECK-NEXT: ldr q1, [x1]10; CHECK-NEXT: addhn v0.8b, v0.8h, v1.8h11; CHECK-NEXT: ret12 %tmp1 = load <8 x i16>, ptr %A13 %tmp2 = load <8 x i16>, ptr %B14 %tmp3 = call <8 x i8> @llvm.aarch64.neon.addhn.v8i8(<8 x i16> %tmp1, <8 x i16> %tmp2)15 ret <8 x i8> %tmp316}17 18define <4 x i16> @addhn4h(ptr %A, ptr %B) nounwind {19; CHECK-LABEL: addhn4h:20; CHECK: // %bb.0:21; CHECK-NEXT: ldr q0, [x0]22; CHECK-NEXT: ldr q1, [x1]23; CHECK-NEXT: addhn v0.4h, v0.4s, v1.4s24; CHECK-NEXT: ret25 %tmp1 = load <4 x i32>, ptr %A26 %tmp2 = load <4 x i32>, ptr %B27 %tmp3 = call <4 x i16> @llvm.aarch64.neon.addhn.v4i16(<4 x i32> %tmp1, <4 x i32> %tmp2)28 ret <4 x i16> %tmp329}30 31define <2 x i32> @addhn2s(ptr %A, ptr %B) nounwind {32; CHECK-LABEL: addhn2s:33; CHECK: // %bb.0:34; CHECK-NEXT: ldr q0, [x0]35; CHECK-NEXT: ldr q1, [x1]36; CHECK-NEXT: addhn v0.2s, v0.2d, v1.2d37; CHECK-NEXT: ret38 %tmp1 = load <2 x i64>, ptr %A39 %tmp2 = load <2 x i64>, ptr %B40 %tmp3 = call <2 x i32> @llvm.aarch64.neon.addhn.v2i32(<2 x i64> %tmp1, <2 x i64> %tmp2)41 ret <2 x i32> %tmp342}43 44define <16 x i8> @addhn2_16b(<8 x i16> %a, <8 x i16> %b) nounwind {45; CHECK-LABEL: addhn2_16b:46; CHECK: // %bb.0:47; CHECK-NEXT: addhn v2.8b, v0.8h, v1.8h48; CHECK-NEXT: addhn2 v2.16b, v0.8h, v1.8h49; CHECK-NEXT: mov v0.16b, v2.16b50; CHECK-NEXT: ret51 %vaddhn2.i = tail call <8 x i8> @llvm.aarch64.neon.addhn.v8i8(<8 x i16> %a, <8 x i16> %b) nounwind52 %vaddhn_high2.i = tail call <8 x i8> @llvm.aarch64.neon.addhn.v8i8(<8 x i16> %a, <8 x i16> %b) nounwind53 %res = shufflevector <8 x i8> %vaddhn2.i, <8 x i8> %vaddhn_high2.i, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>54 ret <16 x i8> %res55}56 57define <8 x i16> @addhn2_8h(<4 x i32> %a, <4 x i32> %b) nounwind {58; CHECK-LABEL: addhn2_8h:59; CHECK: // %bb.0:60; CHECK-NEXT: addhn v2.4h, v0.4s, v1.4s61; CHECK-NEXT: addhn2 v2.8h, v0.4s, v1.4s62; CHECK-NEXT: mov v0.16b, v2.16b63; CHECK-NEXT: ret64 %vaddhn2.i = tail call <4 x i16> @llvm.aarch64.neon.addhn.v4i16(<4 x i32> %a, <4 x i32> %b) nounwind65 %vaddhn_high3.i = tail call <4 x i16> @llvm.aarch64.neon.addhn.v4i16(<4 x i32> %a, <4 x i32> %b) nounwind66 %res = shufflevector <4 x i16> %vaddhn2.i, <4 x i16> %vaddhn_high3.i, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>67 ret <8 x i16> %res68}69 70define <4 x i32> @addhn2_4s(<2 x i64> %a, <2 x i64> %b) nounwind {71; CHECK-LABEL: addhn2_4s:72; CHECK: // %bb.0:73; CHECK-NEXT: addhn v2.2s, v0.2d, v1.2d74; CHECK-NEXT: addhn2 v2.4s, v0.2d, v1.2d75; CHECK-NEXT: mov v0.16b, v2.16b76; CHECK-NEXT: ret77 %vaddhn2.i = tail call <2 x i32> @llvm.aarch64.neon.addhn.v2i32(<2 x i64> %a, <2 x i64> %b) nounwind78 %vaddhn_high3.i = tail call <2 x i32> @llvm.aarch64.neon.addhn.v2i32(<2 x i64> %a, <2 x i64> %b) nounwind79 %res = shufflevector <2 x i32> %vaddhn2.i, <2 x i32> %vaddhn_high3.i, <4 x i32> <i32 0, i32 1, i32 2, i32 3>80 ret <4 x i32> %res81}82 83declare <2 x i32> @llvm.aarch64.neon.addhn.v2i32(<2 x i64>, <2 x i64>) nounwind readnone84declare <4 x i16> @llvm.aarch64.neon.addhn.v4i16(<4 x i32>, <4 x i32>) nounwind readnone85declare <8 x i8> @llvm.aarch64.neon.addhn.v8i8(<8 x i16>, <8 x i16>) nounwind readnone86 87 88define <8 x i8> @raddhn8b(ptr %A, ptr %B) nounwind {89; CHECK-LABEL: raddhn8b:90; CHECK: // %bb.0:91; CHECK-NEXT: ldr q0, [x0]92; CHECK-NEXT: ldr q1, [x1]93; CHECK-NEXT: raddhn v0.8b, v0.8h, v1.8h94; CHECK-NEXT: ret95 %tmp1 = load <8 x i16>, ptr %A96 %tmp2 = load <8 x i16>, ptr %B97 %tmp3 = call <8 x i8> @llvm.aarch64.neon.raddhn.v8i8(<8 x i16> %tmp1, <8 x i16> %tmp2)98 ret <8 x i8> %tmp399}100 101define <4 x i16> @raddhn4h(ptr %A, ptr %B) nounwind {102; CHECK-LABEL: raddhn4h:103; CHECK: // %bb.0:104; CHECK-NEXT: ldr q0, [x0]105; CHECK-NEXT: ldr q1, [x1]106; CHECK-NEXT: raddhn v0.4h, v0.4s, v1.4s107; CHECK-NEXT: ret108 %tmp1 = load <4 x i32>, ptr %A109 %tmp2 = load <4 x i32>, ptr %B110 %tmp3 = call <4 x i16> @llvm.aarch64.neon.raddhn.v4i16(<4 x i32> %tmp1, <4 x i32> %tmp2)111 ret <4 x i16> %tmp3112}113 114define <2 x i32> @raddhn2s(ptr %A, ptr %B) nounwind {115; CHECK-LABEL: raddhn2s:116; CHECK: // %bb.0:117; CHECK-NEXT: ldr q0, [x0]118; CHECK-NEXT: ldr q1, [x1]119; CHECK-NEXT: raddhn v0.2s, v0.2d, v1.2d120; CHECK-NEXT: ret121 %tmp1 = load <2 x i64>, ptr %A122 %tmp2 = load <2 x i64>, ptr %B123 %tmp3 = call <2 x i32> @llvm.aarch64.neon.raddhn.v2i32(<2 x i64> %tmp1, <2 x i64> %tmp2)124 ret <2 x i32> %tmp3125}126 127define <16 x i8> @raddhn2_16b(<8 x i16> %a, <8 x i16> %b) nounwind {128; CHECK-LABEL: raddhn2_16b:129; CHECK: // %bb.0:130; CHECK-NEXT: raddhn v2.8b, v0.8h, v1.8h131; CHECK-NEXT: raddhn2 v2.16b, v0.8h, v1.8h132; CHECK-NEXT: mov v0.16b, v2.16b133; CHECK-NEXT: ret134 %vraddhn2.i = tail call <8 x i8> @llvm.aarch64.neon.raddhn.v8i8(<8 x i16> %a, <8 x i16> %b) nounwind135 %vraddhn_high2.i = tail call <8 x i8> @llvm.aarch64.neon.raddhn.v8i8(<8 x i16> %a, <8 x i16> %b) nounwind136 %res = shufflevector <8 x i8> %vraddhn2.i, <8 x i8> %vraddhn_high2.i, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>137 ret <16 x i8> %res138}139 140define <8 x i16> @raddhn2_8h(<4 x i32> %a, <4 x i32> %b) nounwind {141; CHECK-LABEL: raddhn2_8h:142; CHECK: // %bb.0:143; CHECK-NEXT: raddhn v2.4h, v0.4s, v1.4s144; CHECK-NEXT: raddhn2 v2.8h, v0.4s, v1.4s145; CHECK-NEXT: mov v0.16b, v2.16b146; CHECK-NEXT: ret147 %vraddhn2.i = tail call <4 x i16> @llvm.aarch64.neon.raddhn.v4i16(<4 x i32> %a, <4 x i32> %b) nounwind148 %vraddhn_high3.i = tail call <4 x i16> @llvm.aarch64.neon.raddhn.v4i16(<4 x i32> %a, <4 x i32> %b) nounwind149 %res = shufflevector <4 x i16> %vraddhn2.i, <4 x i16> %vraddhn_high3.i, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>150 ret <8 x i16> %res151}152 153define <4 x i32> @raddhn2_4s(<2 x i64> %a, <2 x i64> %b) nounwind {154; CHECK-LABEL: raddhn2_4s:155; CHECK: // %bb.0:156; CHECK-NEXT: raddhn v2.2s, v0.2d, v1.2d157; CHECK-NEXT: raddhn2 v2.4s, v0.2d, v1.2d158; CHECK-NEXT: mov v0.16b, v2.16b159; CHECK-NEXT: ret160 %vraddhn2.i = tail call <2 x i32> @llvm.aarch64.neon.raddhn.v2i32(<2 x i64> %a, <2 x i64> %b) nounwind161 %vraddhn_high3.i = tail call <2 x i32> @llvm.aarch64.neon.raddhn.v2i32(<2 x i64> %a, <2 x i64> %b) nounwind162 %res = shufflevector <2 x i32> %vraddhn2.i, <2 x i32> %vraddhn_high3.i, <4 x i32> <i32 0, i32 1, i32 2, i32 3>163 ret <4 x i32> %res164}165 166declare <2 x i32> @llvm.aarch64.neon.raddhn.v2i32(<2 x i64>, <2 x i64>) nounwind readnone167declare <4 x i16> @llvm.aarch64.neon.raddhn.v4i16(<4 x i32>, <4 x i32>) nounwind readnone168declare <8 x i8> @llvm.aarch64.neon.raddhn.v8i8(<8 x i16>, <8 x i16>) nounwind readnone169 170define <8 x i16> @saddl2_8h(<16 x i8> %a, <16 x i8> %b) nounwind {171; CHECK-LABEL: saddl2_8h:172; CHECK: // %bb.0:173; CHECK-NEXT: saddl2 v0.8h, v0.16b, v1.16b174; CHECK-NEXT: ret175 %tmp = bitcast <16 x i8> %a to <2 x i64>176 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>177 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <8 x i8>178 %vmovl.i.i.i = sext <8 x i8> %tmp1 to <8 x i16>179 %tmp2 = bitcast <16 x i8> %b to <2 x i64>180 %shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>181 %tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <8 x i8>182 %vmovl.i.i5.i = sext <8 x i8> %tmp3 to <8 x i16>183 %add.i = add <8 x i16> %vmovl.i.i.i, %vmovl.i.i5.i184 ret <8 x i16> %add.i185}186 187define <4 x i32> @saddl2_4s(<8 x i16> %a, <8 x i16> %b) nounwind {188; CHECK-LABEL: saddl2_4s:189; CHECK: // %bb.0:190; CHECK-NEXT: saddl2 v0.4s, v0.8h, v1.8h191; CHECK-NEXT: ret192 %tmp = bitcast <8 x i16> %a to <2 x i64>193 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>194 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <4 x i16>195 %vmovl.i.i.i = sext <4 x i16> %tmp1 to <4 x i32>196 %tmp2 = bitcast <8 x i16> %b to <2 x i64>197 %shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>198 %tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <4 x i16>199 %vmovl.i.i5.i = sext <4 x i16> %tmp3 to <4 x i32>200 %add.i = add <4 x i32> %vmovl.i.i.i, %vmovl.i.i5.i201 ret <4 x i32> %add.i202}203 204define <2 x i64> @saddl2_2d(<4 x i32> %a, <4 x i32> %b) nounwind {205; CHECK-LABEL: saddl2_2d:206; CHECK: // %bb.0:207; CHECK-NEXT: saddl2 v0.2d, v0.4s, v1.4s208; CHECK-NEXT: ret209 %tmp = bitcast <4 x i32> %a to <2 x i64>210 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>211 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <2 x i32>212 %vmovl.i.i.i = sext <2 x i32> %tmp1 to <2 x i64>213 %tmp2 = bitcast <4 x i32> %b to <2 x i64>214 %shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>215 %tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <2 x i32>216 %vmovl.i.i5.i = sext <2 x i32> %tmp3 to <2 x i64>217 %add.i = add <2 x i64> %vmovl.i.i.i, %vmovl.i.i5.i218 ret <2 x i64> %add.i219}220 221define <8 x i16> @uaddl2_8h(<16 x i8> %a, <16 x i8> %b) nounwind {222; CHECK-LABEL: uaddl2_8h:223; CHECK: // %bb.0:224; CHECK-NEXT: uaddl2 v0.8h, v0.16b, v1.16b225; CHECK-NEXT: ret226 %tmp = bitcast <16 x i8> %a to <2 x i64>227 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>228 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <8 x i8>229 %vmovl.i.i.i = zext <8 x i8> %tmp1 to <8 x i16>230 %tmp2 = bitcast <16 x i8> %b to <2 x i64>231 %shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>232 %tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <8 x i8>233 %vmovl.i.i5.i = zext <8 x i8> %tmp3 to <8 x i16>234 %add.i = add <8 x i16> %vmovl.i.i.i, %vmovl.i.i5.i235 ret <8 x i16> %add.i236}237 238define <4 x i32> @uaddl2_4s(<8 x i16> %a, <8 x i16> %b) nounwind {239; CHECK-LABEL: uaddl2_4s:240; CHECK: // %bb.0:241; CHECK-NEXT: uaddl2 v0.4s, v0.8h, v1.8h242; CHECK-NEXT: ret243 %tmp = bitcast <8 x i16> %a to <2 x i64>244 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>245 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <4 x i16>246 %vmovl.i.i.i = zext <4 x i16> %tmp1 to <4 x i32>247 %tmp2 = bitcast <8 x i16> %b to <2 x i64>248 %shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>249 %tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <4 x i16>250 %vmovl.i.i5.i = zext <4 x i16> %tmp3 to <4 x i32>251 %add.i = add <4 x i32> %vmovl.i.i.i, %vmovl.i.i5.i252 ret <4 x i32> %add.i253}254 255define <2 x i64> @uaddl2_2d(<4 x i32> %a, <4 x i32> %b) nounwind {256; CHECK-LABEL: uaddl2_2d:257; CHECK: // %bb.0:258; CHECK-NEXT: uaddl2 v0.2d, v0.4s, v1.4s259; CHECK-NEXT: ret260 %tmp = bitcast <4 x i32> %a to <2 x i64>261 %shuffle.i.i.i = shufflevector <2 x i64> %tmp, <2 x i64> undef, <1 x i32> <i32 1>262 %tmp1 = bitcast <1 x i64> %shuffle.i.i.i to <2 x i32>263 %vmovl.i.i.i = zext <2 x i32> %tmp1 to <2 x i64>264 %tmp2 = bitcast <4 x i32> %b to <2 x i64>265 %shuffle.i.i4.i = shufflevector <2 x i64> %tmp2, <2 x i64> undef, <1 x i32> <i32 1>266 %tmp3 = bitcast <1 x i64> %shuffle.i.i4.i to <2 x i32>267 %vmovl.i.i5.i = zext <2 x i32> %tmp3 to <2 x i64>268 %add.i = add <2 x i64> %vmovl.i.i.i, %vmovl.i.i5.i269 ret <2 x i64> %add.i270}271 272define <8 x i16> @uaddw8h(ptr %A, ptr %B) nounwind {273; CHECK-LABEL: uaddw8h:274; CHECK: // %bb.0:275; CHECK-NEXT: ldr q0, [x0]276; CHECK-NEXT: ldr d1, [x1]277; CHECK-NEXT: uaddw v0.8h, v0.8h, v1.8b278; CHECK-NEXT: ret279 %tmp1 = load <8 x i16>, ptr %A280 %tmp2 = load <8 x i8>, ptr %B281 %tmp3 = zext <8 x i8> %tmp2 to <8 x i16>282 %tmp4 = add <8 x i16> %tmp1, %tmp3283 ret <8 x i16> %tmp4284}285 286define <4 x i32> @uaddw4s(ptr %A, ptr %B) nounwind {287; CHECK-LABEL: uaddw4s:288; CHECK: // %bb.0:289; CHECK-NEXT: ldr q0, [x0]290; CHECK-NEXT: ldr d1, [x1]291; CHECK-NEXT: uaddw v0.4s, v0.4s, v1.4h292; CHECK-NEXT: ret293 %tmp1 = load <4 x i32>, ptr %A294 %tmp2 = load <4 x i16>, ptr %B295 %tmp3 = zext <4 x i16> %tmp2 to <4 x i32>296 %tmp4 = add <4 x i32> %tmp1, %tmp3297 ret <4 x i32> %tmp4298}299 300define <2 x i64> @uaddw2d(ptr %A, ptr %B) nounwind {301; CHECK-LABEL: uaddw2d:302; CHECK: // %bb.0:303; CHECK-NEXT: ldr q0, [x0]304; CHECK-NEXT: ldr d1, [x1]305; CHECK-NEXT: uaddw v0.2d, v0.2d, v1.2s306; CHECK-NEXT: ret307 %tmp1 = load <2 x i64>, ptr %A308 %tmp2 = load <2 x i32>, ptr %B309 %tmp3 = zext <2 x i32> %tmp2 to <2 x i64>310 %tmp4 = add <2 x i64> %tmp1, %tmp3311 ret <2 x i64> %tmp4312}313 314define <8 x i16> @uaddw2_8h(ptr %A, ptr %B) nounwind {315; CHECK-SD-LABEL: uaddw2_8h:316; CHECK-SD: // %bb.0:317; CHECK-SD-NEXT: ldr q0, [x0]318; CHECK-SD-NEXT: ldr d1, [x1, #8]319; CHECK-SD-NEXT: uaddw v0.8h, v0.8h, v1.8b320; CHECK-SD-NEXT: ret321;322; CHECK-GI-LABEL: uaddw2_8h:323; CHECK-GI: // %bb.0:324; CHECK-GI-NEXT: ldr q0, [x0]325; CHECK-GI-NEXT: ldr q1, [x1]326; CHECK-GI-NEXT: uaddw2 v0.8h, v0.8h, v1.16b327; CHECK-GI-NEXT: ret328 %tmp1 = load <8 x i16>, ptr %A329 330 %tmp2 = load <16 x i8>, ptr %B331 %high2 = shufflevector <16 x i8> %tmp2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>332 %ext2 = zext <8 x i8> %high2 to <8 x i16>333 334 %res = add <8 x i16> %tmp1, %ext2335 ret <8 x i16> %res336}337 338define <4 x i32> @uaddw2_4s(ptr %A, ptr %B) nounwind {339; CHECK-SD-LABEL: uaddw2_4s:340; CHECK-SD: // %bb.0:341; CHECK-SD-NEXT: ldr q0, [x0]342; CHECK-SD-NEXT: ldr d1, [x1, #8]343; CHECK-SD-NEXT: uaddw v0.4s, v0.4s, v1.4h344; CHECK-SD-NEXT: ret345;346; CHECK-GI-LABEL: uaddw2_4s:347; CHECK-GI: // %bb.0:348; CHECK-GI-NEXT: ldr q0, [x0]349; CHECK-GI-NEXT: ldr q1, [x1]350; CHECK-GI-NEXT: uaddw2 v0.4s, v0.4s, v1.8h351; CHECK-GI-NEXT: ret352 %tmp1 = load <4 x i32>, ptr %A353 354 %tmp2 = load <8 x i16>, ptr %B355 %high2 = shufflevector <8 x i16> %tmp2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>356 %ext2 = zext <4 x i16> %high2 to <4 x i32>357 358 %res = add <4 x i32> %tmp1, %ext2359 ret <4 x i32> %res360}361 362define <2 x i64> @uaddw2_2d(ptr %A, ptr %B) nounwind {363; CHECK-SD-LABEL: uaddw2_2d:364; CHECK-SD: // %bb.0:365; CHECK-SD-NEXT: ldr q0, [x0]366; CHECK-SD-NEXT: ldr d1, [x1, #8]367; CHECK-SD-NEXT: uaddw v0.2d, v0.2d, v1.2s368; CHECK-SD-NEXT: ret369;370; CHECK-GI-LABEL: uaddw2_2d:371; CHECK-GI: // %bb.0:372; CHECK-GI-NEXT: ldr q0, [x0]373; CHECK-GI-NEXT: ldr q1, [x1]374; CHECK-GI-NEXT: uaddw2 v0.2d, v0.2d, v1.4s375; CHECK-GI-NEXT: ret376 %tmp1 = load <2 x i64>, ptr %A377 378 %tmp2 = load <4 x i32>, ptr %B379 %high2 = shufflevector <4 x i32> %tmp2, <4 x i32> undef, <2 x i32> <i32 2, i32 3>380 %ext2 = zext <2 x i32> %high2 to <2 x i64>381 382 %res = add <2 x i64> %tmp1, %ext2383 ret <2 x i64> %res384}385 386define <8 x i16> @saddw8h(ptr %A, ptr %B) nounwind {387; CHECK-LABEL: saddw8h:388; CHECK: // %bb.0:389; CHECK-NEXT: ldr q0, [x0]390; CHECK-NEXT: ldr d1, [x1]391; CHECK-NEXT: saddw v0.8h, v0.8h, v1.8b392; CHECK-NEXT: ret393 %tmp1 = load <8 x i16>, ptr %A394 %tmp2 = load <8 x i8>, ptr %B395 %tmp3 = sext <8 x i8> %tmp2 to <8 x i16>396 %tmp4 = add <8 x i16> %tmp1, %tmp3397 ret <8 x i16> %tmp4398}399 400define <4 x i32> @saddw4s(ptr %A, ptr %B) nounwind {401; CHECK-LABEL: saddw4s:402; CHECK: // %bb.0:403; CHECK-NEXT: ldr q0, [x0]404; CHECK-NEXT: ldr d1, [x1]405; CHECK-NEXT: saddw v0.4s, v0.4s, v1.4h406; CHECK-NEXT: ret407 %tmp1 = load <4 x i32>, ptr %A408 %tmp2 = load <4 x i16>, ptr %B409 %tmp3 = sext <4 x i16> %tmp2 to <4 x i32>410 %tmp4 = add <4 x i32> %tmp1, %tmp3411 ret <4 x i32> %tmp4412}413 414define <2 x i64> @saddw2d(ptr %A, ptr %B) nounwind {415; CHECK-LABEL: saddw2d:416; CHECK: // %bb.0:417; CHECK-NEXT: ldr q0, [x0]418; CHECK-NEXT: ldr d1, [x1]419; CHECK-NEXT: saddw v0.2d, v0.2d, v1.2s420; CHECK-NEXT: ret421 %tmp1 = load <2 x i64>, ptr %A422 %tmp2 = load <2 x i32>, ptr %B423 %tmp3 = sext <2 x i32> %tmp2 to <2 x i64>424 %tmp4 = add <2 x i64> %tmp1, %tmp3425 ret <2 x i64> %tmp4426}427 428define <8 x i16> @saddw2_8h(ptr %A, ptr %B) nounwind {429; CHECK-SD-LABEL: saddw2_8h:430; CHECK-SD: // %bb.0:431; CHECK-SD-NEXT: ldr q0, [x0]432; CHECK-SD-NEXT: ldr d1, [x1, #8]433; CHECK-SD-NEXT: saddw v0.8h, v0.8h, v1.8b434; CHECK-SD-NEXT: ret435;436; CHECK-GI-LABEL: saddw2_8h:437; CHECK-GI: // %bb.0:438; CHECK-GI-NEXT: ldr q0, [x0]439; CHECK-GI-NEXT: ldr q1, [x1]440; CHECK-GI-NEXT: saddw2 v0.8h, v0.8h, v1.16b441; CHECK-GI-NEXT: ret442 %tmp1 = load <8 x i16>, ptr %A443 444 %tmp2 = load <16 x i8>, ptr %B445 %high2 = shufflevector <16 x i8> %tmp2, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>446 %ext2 = sext <8 x i8> %high2 to <8 x i16>447 448 %res = add <8 x i16> %tmp1, %ext2449 ret <8 x i16> %res450}451 452define <4 x i32> @saddw2_4s(ptr %A, ptr %B) nounwind {453; CHECK-SD-LABEL: saddw2_4s:454; CHECK-SD: // %bb.0:455; CHECK-SD-NEXT: ldr q0, [x0]456; CHECK-SD-NEXT: ldr d1, [x1, #8]457; CHECK-SD-NEXT: saddw v0.4s, v0.4s, v1.4h458; CHECK-SD-NEXT: ret459;460; CHECK-GI-LABEL: saddw2_4s:461; CHECK-GI: // %bb.0:462; CHECK-GI-NEXT: ldr q0, [x0]463; CHECK-GI-NEXT: ldr q1, [x1]464; CHECK-GI-NEXT: saddw2 v0.4s, v0.4s, v1.8h465; CHECK-GI-NEXT: ret466 %tmp1 = load <4 x i32>, ptr %A467 468 %tmp2 = load <8 x i16>, ptr %B469 %high2 = shufflevector <8 x i16> %tmp2, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>470 %ext2 = sext <4 x i16> %high2 to <4 x i32>471 472 %res = add <4 x i32> %tmp1, %ext2473 ret <4 x i32> %res474}475 476define <2 x i64> @saddw2_2d(ptr %A, ptr %B) nounwind {477; CHECK-SD-LABEL: saddw2_2d:478; CHECK-SD: // %bb.0:479; CHECK-SD-NEXT: ldr q0, [x0]480; CHECK-SD-NEXT: ldr d1, [x1, #8]481; CHECK-SD-NEXT: saddw v0.2d, v0.2d, v1.2s482; CHECK-SD-NEXT: ret483;484; CHECK-GI-LABEL: saddw2_2d:485; CHECK-GI: // %bb.0:486; CHECK-GI-NEXT: ldr q0, [x0]487; CHECK-GI-NEXT: ldr q1, [x1]488; CHECK-GI-NEXT: saddw2 v0.2d, v0.2d, v1.4s489; CHECK-GI-NEXT: ret490 %tmp1 = load <2 x i64>, ptr %A491 492 %tmp2 = load <4 x i32>, ptr %B493 %high2 = shufflevector <4 x i32> %tmp2, <4 x i32> undef, <2 x i32> <i32 2, i32 3>494 %ext2 = sext <2 x i32> %high2 to <2 x i64>495 496 %res = add <2 x i64> %tmp1, %ext2497 ret <2 x i64> %res498}499 500define <4 x i16> @saddlp4h(ptr %A) nounwind {501; CHECK-LABEL: saddlp4h:502; CHECK: // %bb.0:503; CHECK-NEXT: ldr d0, [x0]504; CHECK-NEXT: saddlp v0.4h, v0.8b505; CHECK-NEXT: ret506 %tmp1 = load <8 x i8>, ptr %A507 %tmp3 = call <4 x i16> @llvm.aarch64.neon.saddlp.v4i16.v8i8(<8 x i8> %tmp1)508 ret <4 x i16> %tmp3509}510 511define <2 x i32> @saddlp2s(ptr %A) nounwind {512; CHECK-LABEL: saddlp2s:513; CHECK: // %bb.0:514; CHECK-NEXT: ldr d0, [x0]515; CHECK-NEXT: saddlp v0.2s, v0.4h516; CHECK-NEXT: ret517 %tmp1 = load <4 x i16>, ptr %A518 %tmp3 = call <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16> %tmp1)519 ret <2 x i32> %tmp3520}521 522define <1 x i64> @saddlp1d(ptr %A) nounwind {523; CHECK-LABEL: saddlp1d:524; CHECK: // %bb.0:525; CHECK-NEXT: ldr d0, [x0]526; CHECK-NEXT: saddlp v0.1d, v0.2s527; CHECK-NEXT: ret528 %tmp1 = load <2 x i32>, ptr %A529 %tmp3 = call <1 x i64> @llvm.aarch64.neon.saddlp.v1i64.v2i32(<2 x i32> %tmp1)530 ret <1 x i64> %tmp3531}532 533define <8 x i16> @saddlp8h(ptr %A) nounwind {534; CHECK-LABEL: saddlp8h:535; CHECK: // %bb.0:536; CHECK-NEXT: ldr q0, [x0]537; CHECK-NEXT: saddlp v0.8h, v0.16b538; CHECK-NEXT: ret539 %tmp1 = load <16 x i8>, ptr %A540 %tmp3 = call <8 x i16> @llvm.aarch64.neon.saddlp.v8i16.v16i8(<16 x i8> %tmp1)541 ret <8 x i16> %tmp3542}543 544define <4 x i32> @saddlp4s(ptr %A) nounwind {545; CHECK-LABEL: saddlp4s:546; CHECK: // %bb.0:547; CHECK-NEXT: ldr q0, [x0]548; CHECK-NEXT: saddlp v0.4s, v0.8h549; CHECK-NEXT: ret550 %tmp1 = load <8 x i16>, ptr %A551 %tmp3 = call <4 x i32> @llvm.aarch64.neon.saddlp.v4i32.v8i16(<8 x i16> %tmp1)552 ret <4 x i32> %tmp3553}554 555define <2 x i64> @saddlp2d(ptr %A) nounwind {556; CHECK-LABEL: saddlp2d:557; CHECK: // %bb.0:558; CHECK-NEXT: ldr q0, [x0]559; CHECK-NEXT: saddlp v0.2d, v0.4s560; CHECK-NEXT: ret561 %tmp1 = load <4 x i32>, ptr %A562 %tmp3 = call <2 x i64> @llvm.aarch64.neon.saddlp.v2i64.v4i32(<4 x i32> %tmp1)563 ret <2 x i64> %tmp3564}565 566declare <4 x i16> @llvm.aarch64.neon.saddlp.v4i16.v8i8(<8 x i8>) nounwind readnone567declare <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16>) nounwind readnone568declare <1 x i64> @llvm.aarch64.neon.saddlp.v1i64.v2i32(<2 x i32>) nounwind readnone569 570declare <8 x i16> @llvm.aarch64.neon.saddlp.v8i16.v16i8(<16 x i8>) nounwind readnone571declare <4 x i32> @llvm.aarch64.neon.saddlp.v4i32.v8i16(<8 x i16>) nounwind readnone572declare <2 x i64> @llvm.aarch64.neon.saddlp.v2i64.v4i32(<4 x i32>) nounwind readnone573 574define <4 x i16> @uaddlp4h(ptr %A) nounwind {575; CHECK-LABEL: uaddlp4h:576; CHECK: // %bb.0:577; CHECK-NEXT: ldr d0, [x0]578; CHECK-NEXT: uaddlp v0.4h, v0.8b579; CHECK-NEXT: ret580 %tmp1 = load <8 x i8>, ptr %A581 %tmp3 = call <4 x i16> @llvm.aarch64.neon.uaddlp.v4i16.v8i8(<8 x i8> %tmp1)582 ret <4 x i16> %tmp3583}584 585define <2 x i32> @uaddlp2s(ptr %A) nounwind {586; CHECK-LABEL: uaddlp2s:587; CHECK: // %bb.0:588; CHECK-NEXT: ldr d0, [x0]589; CHECK-NEXT: uaddlp v0.2s, v0.4h590; CHECK-NEXT: ret591 %tmp1 = load <4 x i16>, ptr %A592 %tmp3 = call <2 x i32> @llvm.aarch64.neon.uaddlp.v2i32.v4i16(<4 x i16> %tmp1)593 ret <2 x i32> %tmp3594}595 596define <1 x i64> @uaddlp1d(ptr %A) nounwind {597; CHECK-LABEL: uaddlp1d:598; CHECK: // %bb.0:599; CHECK-NEXT: ldr d0, [x0]600; CHECK-NEXT: uaddlp v0.1d, v0.2s601; CHECK-NEXT: ret602 %tmp1 = load <2 x i32>, ptr %A603 %tmp3 = call <1 x i64> @llvm.aarch64.neon.uaddlp.v1i64.v2i32(<2 x i32> %tmp1)604 ret <1 x i64> %tmp3605}606 607define <8 x i16> @uaddlp8h(ptr %A) nounwind {608; CHECK-LABEL: uaddlp8h:609; CHECK: // %bb.0:610; CHECK-NEXT: ldr q0, [x0]611; CHECK-NEXT: uaddlp v0.8h, v0.16b612; CHECK-NEXT: ret613 %tmp1 = load <16 x i8>, ptr %A614 %tmp3 = call <8 x i16> @llvm.aarch64.neon.uaddlp.v8i16.v16i8(<16 x i8> %tmp1)615 ret <8 x i16> %tmp3616}617 618define <4 x i32> @uaddlp4s(ptr %A) nounwind {619; CHECK-LABEL: uaddlp4s:620; CHECK: // %bb.0:621; CHECK-NEXT: ldr q0, [x0]622; CHECK-NEXT: uaddlp v0.4s, v0.8h623; CHECK-NEXT: ret624 %tmp1 = load <8 x i16>, ptr %A625 %tmp3 = call <4 x i32> @llvm.aarch64.neon.uaddlp.v4i32.v8i16(<8 x i16> %tmp1)626 ret <4 x i32> %tmp3627}628 629define <2 x i64> @uaddlp2d(ptr %A) nounwind {630; CHECK-LABEL: uaddlp2d:631; CHECK: // %bb.0:632; CHECK-NEXT: ldr q0, [x0]633; CHECK-NEXT: uaddlp v0.2d, v0.4s634; CHECK-NEXT: ret635 %tmp1 = load <4 x i32>, ptr %A636 %tmp3 = call <2 x i64> @llvm.aarch64.neon.uaddlp.v2i64.v4i32(<4 x i32> %tmp1)637 ret <2 x i64> %tmp3638}639 640declare <4 x i16> @llvm.aarch64.neon.uaddlp.v4i16.v8i8(<8 x i8>) nounwind readnone641declare <2 x i32> @llvm.aarch64.neon.uaddlp.v2i32.v4i16(<4 x i16>) nounwind readnone642declare <1 x i64> @llvm.aarch64.neon.uaddlp.v1i64.v2i32(<2 x i32>) nounwind readnone643 644declare <8 x i16> @llvm.aarch64.neon.uaddlp.v8i16.v16i8(<16 x i8>) nounwind readnone645declare <4 x i32> @llvm.aarch64.neon.uaddlp.v4i32.v8i16(<8 x i16>) nounwind readnone646declare <2 x i64> @llvm.aarch64.neon.uaddlp.v2i64.v4i32(<4 x i32>) nounwind readnone647 648define <4 x i16> @sadalp4h(ptr %A, ptr %B) nounwind {649; CHECK-LABEL: sadalp4h:650; CHECK: // %bb.0:651; CHECK-NEXT: ldr d1, [x0]652; CHECK-NEXT: ldr d0, [x1]653; CHECK-NEXT: sadalp v0.4h, v1.8b654; CHECK-NEXT: ret655 %tmp1 = load <8 x i8>, ptr %A656 %tmp3 = call <4 x i16> @llvm.aarch64.neon.saddlp.v4i16.v8i8(<8 x i8> %tmp1)657 %tmp4 = load <4 x i16>, ptr %B658 %tmp5 = add <4 x i16> %tmp3, %tmp4659 ret <4 x i16> %tmp5660}661 662define <2 x i32> @sadalp2s(ptr %A, ptr %B) nounwind {663; CHECK-LABEL: sadalp2s:664; CHECK: // %bb.0:665; CHECK-NEXT: ldr d1, [x0]666; CHECK-NEXT: ldr d0, [x1]667; CHECK-NEXT: sadalp v0.2s, v1.4h668; CHECK-NEXT: ret669 %tmp1 = load <4 x i16>, ptr %A670 %tmp3 = call <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16> %tmp1)671 %tmp4 = load <2 x i32>, ptr %B672 %tmp5 = add <2 x i32> %tmp3, %tmp4673 ret <2 x i32> %tmp5674}675 676define <8 x i16> @sadalp8h(ptr %A, ptr %B) nounwind {677; CHECK-LABEL: sadalp8h:678; CHECK: // %bb.0:679; CHECK-NEXT: ldr q1, [x0]680; CHECK-NEXT: ldr q0, [x1]681; CHECK-NEXT: sadalp v0.8h, v1.16b682; CHECK-NEXT: ret683 %tmp1 = load <16 x i8>, ptr %A684 %tmp3 = call <8 x i16> @llvm.aarch64.neon.saddlp.v8i16.v16i8(<16 x i8> %tmp1)685 %tmp4 = load <8 x i16>, ptr %B686 %tmp5 = add <8 x i16> %tmp3, %tmp4687 ret <8 x i16> %tmp5688}689 690define <4 x i32> @sadalp4s(ptr %A, ptr %B) nounwind {691; CHECK-LABEL: sadalp4s:692; CHECK: // %bb.0:693; CHECK-NEXT: ldr q1, [x0]694; CHECK-NEXT: ldr q0, [x1]695; CHECK-NEXT: sadalp v0.4s, v1.8h696; CHECK-NEXT: ret697 %tmp1 = load <8 x i16>, ptr %A698 %tmp3 = call <4 x i32> @llvm.aarch64.neon.saddlp.v4i32.v8i16(<8 x i16> %tmp1)699 %tmp4 = load <4 x i32>, ptr %B700 %tmp5 = add <4 x i32> %tmp3, %tmp4701 ret <4 x i32> %tmp5702}703 704define <2 x i64> @sadalp2d(ptr %A, ptr %B) nounwind {705; CHECK-LABEL: sadalp2d:706; CHECK: // %bb.0:707; CHECK-NEXT: ldr q1, [x0]708; CHECK-NEXT: ldr q0, [x1]709; CHECK-NEXT: sadalp v0.2d, v1.4s710; CHECK-NEXT: ret711 %tmp1 = load <4 x i32>, ptr %A712 %tmp3 = call <2 x i64> @llvm.aarch64.neon.saddlp.v2i64.v4i32(<4 x i32> %tmp1)713 %tmp4 = load <2 x i64>, ptr %B714 %tmp5 = add <2 x i64> %tmp3, %tmp4715 ret <2 x i64> %tmp5716}717 718define <4 x i16> @uadalp4h(ptr %A, ptr %B) nounwind {719; CHECK-LABEL: uadalp4h:720; CHECK: // %bb.0:721; CHECK-NEXT: ldr d1, [x0]722; CHECK-NEXT: ldr d0, [x1]723; CHECK-NEXT: uadalp v0.4h, v1.8b724; CHECK-NEXT: ret725 %tmp1 = load <8 x i8>, ptr %A726 %tmp3 = call <4 x i16> @llvm.aarch64.neon.uaddlp.v4i16.v8i8(<8 x i8> %tmp1)727 %tmp4 = load <4 x i16>, ptr %B728 %tmp5 = add <4 x i16> %tmp3, %tmp4729 ret <4 x i16> %tmp5730}731 732define <2 x i32> @uadalp2s(ptr %A, ptr %B) nounwind {733; CHECK-LABEL: uadalp2s:734; CHECK: // %bb.0:735; CHECK-NEXT: ldr d1, [x0]736; CHECK-NEXT: ldr d0, [x1]737; CHECK-NEXT: uadalp v0.2s, v1.4h738; CHECK-NEXT: ret739 %tmp1 = load <4 x i16>, ptr %A740 %tmp3 = call <2 x i32> @llvm.aarch64.neon.uaddlp.v2i32.v4i16(<4 x i16> %tmp1)741 %tmp4 = load <2 x i32>, ptr %B742 %tmp5 = add <2 x i32> %tmp3, %tmp4743 ret <2 x i32> %tmp5744}745 746define <8 x i16> @uadalp8h(ptr %A, ptr %B) nounwind {747; CHECK-LABEL: uadalp8h:748; CHECK: // %bb.0:749; CHECK-NEXT: ldr q1, [x0]750; CHECK-NEXT: ldr q0, [x1]751; CHECK-NEXT: uadalp v0.8h, v1.16b752; CHECK-NEXT: ret753 %tmp1 = load <16 x i8>, ptr %A754 %tmp3 = call <8 x i16> @llvm.aarch64.neon.uaddlp.v8i16.v16i8(<16 x i8> %tmp1)755 %tmp4 = load <8 x i16>, ptr %B756 %tmp5 = add <8 x i16> %tmp3, %tmp4757 ret <8 x i16> %tmp5758}759 760define <4 x i32> @uadalp4s(ptr %A, ptr %B) nounwind {761; CHECK-LABEL: uadalp4s:762; CHECK: // %bb.0:763; CHECK-NEXT: ldr q1, [x0]764; CHECK-NEXT: ldr q0, [x1]765; CHECK-NEXT: uadalp v0.4s, v1.8h766; CHECK-NEXT: ret767 %tmp1 = load <8 x i16>, ptr %A768 %tmp3 = call <4 x i32> @llvm.aarch64.neon.uaddlp.v4i32.v8i16(<8 x i16> %tmp1)769 %tmp4 = load <4 x i32>, ptr %B770 %tmp5 = add <4 x i32> %tmp3, %tmp4771 ret <4 x i32> %tmp5772}773 774define <2 x i64> @uadalp2d(ptr %A, ptr %B) nounwind {775; CHECK-LABEL: uadalp2d:776; CHECK: // %bb.0:777; CHECK-NEXT: ldr q1, [x0]778; CHECK-NEXT: ldr q0, [x1]779; CHECK-NEXT: uadalp v0.2d, v1.4s780; CHECK-NEXT: ret781 %tmp1 = load <4 x i32>, ptr %A782 %tmp3 = call <2 x i64> @llvm.aarch64.neon.uaddlp.v2i64.v4i32(<4 x i32> %tmp1)783 %tmp4 = load <2 x i64>, ptr %B784 %tmp5 = add <2 x i64> %tmp3, %tmp4785 ret <2 x i64> %tmp5786}787 788define <8 x i8> @addp_8b(ptr %A, ptr %B) nounwind {789; CHECK-LABEL: addp_8b:790; CHECK: // %bb.0:791; CHECK-NEXT: ldr d0, [x0]792; CHECK-NEXT: ldr d1, [x1]793; CHECK-NEXT: addp v0.8b, v0.8b, v1.8b794; CHECK-NEXT: ret795 %tmp1 = load <8 x i8>, ptr %A796 %tmp2 = load <8 x i8>, ptr %B797 %tmp3 = call <8 x i8> @llvm.aarch64.neon.addp.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)798 ret <8 x i8> %tmp3799}800 801define <16 x i8> @addp_16b(ptr %A, ptr %B) nounwind {802; CHECK-LABEL: addp_16b:803; CHECK: // %bb.0:804; CHECK-NEXT: ldr q0, [x0]805; CHECK-NEXT: ldr q1, [x1]806; CHECK-NEXT: addp v0.16b, v0.16b, v1.16b807; CHECK-NEXT: ret808 %tmp1 = load <16 x i8>, ptr %A809 %tmp2 = load <16 x i8>, ptr %B810 %tmp3 = call <16 x i8> @llvm.aarch64.neon.addp.v16i8(<16 x i8> %tmp1, <16 x i8> %tmp2)811 ret <16 x i8> %tmp3812}813 814define <4 x i16> @addp_4h(ptr %A, ptr %B) nounwind {815; CHECK-LABEL: addp_4h:816; CHECK: // %bb.0:817; CHECK-NEXT: ldr d0, [x0]818; CHECK-NEXT: ldr d1, [x1]819; CHECK-NEXT: addp v0.4h, v0.4h, v1.4h820; CHECK-NEXT: ret821 %tmp1 = load <4 x i16>, ptr %A822 %tmp2 = load <4 x i16>, ptr %B823 %tmp3 = call <4 x i16> @llvm.aarch64.neon.addp.v4i16(<4 x i16> %tmp1, <4 x i16> %tmp2)824 ret <4 x i16> %tmp3825}826 827define <8 x i16> @addp_8h(ptr %A, ptr %B) nounwind {828; CHECK-LABEL: addp_8h:829; CHECK: // %bb.0:830; CHECK-NEXT: ldr q0, [x0]831; CHECK-NEXT: ldr q1, [x1]832; CHECK-NEXT: addp v0.8h, v0.8h, v1.8h833; CHECK-NEXT: ret834 %tmp1 = load <8 x i16>, ptr %A835 %tmp2 = load <8 x i16>, ptr %B836 %tmp3 = call <8 x i16> @llvm.aarch64.neon.addp.v8i16(<8 x i16> %tmp1, <8 x i16> %tmp2)837 ret <8 x i16> %tmp3838}839 840define <2 x i32> @addp_2s(ptr %A, ptr %B) nounwind {841; CHECK-LABEL: addp_2s:842; CHECK: // %bb.0:843; CHECK-NEXT: ldr d0, [x0]844; CHECK-NEXT: ldr d1, [x1]845; CHECK-NEXT: addp v0.2s, v0.2s, v1.2s846; CHECK-NEXT: ret847 %tmp1 = load <2 x i32>, ptr %A848 %tmp2 = load <2 x i32>, ptr %B849 %tmp3 = call <2 x i32> @llvm.aarch64.neon.addp.v2i32(<2 x i32> %tmp1, <2 x i32> %tmp2)850 ret <2 x i32> %tmp3851}852 853define <4 x i32> @addp_4s(ptr %A, ptr %B) nounwind {854; CHECK-LABEL: addp_4s:855; CHECK: // %bb.0:856; CHECK-NEXT: ldr q0, [x0]857; CHECK-NEXT: ldr q1, [x1]858; CHECK-NEXT: addp v0.4s, v0.4s, v1.4s859; CHECK-NEXT: ret860 %tmp1 = load <4 x i32>, ptr %A861 %tmp2 = load <4 x i32>, ptr %B862 %tmp3 = call <4 x i32> @llvm.aarch64.neon.addp.v4i32(<4 x i32> %tmp1, <4 x i32> %tmp2)863 ret <4 x i32> %tmp3864}865 866define <2 x i64> @addp_2d(ptr %A, ptr %B) nounwind {867; CHECK-LABEL: addp_2d:868; CHECK: // %bb.0:869; CHECK-NEXT: ldr q0, [x0]870; CHECK-NEXT: ldr q1, [x1]871; CHECK-NEXT: addp v0.2d, v0.2d, v1.2d872; CHECK-NEXT: ret873 %tmp1 = load <2 x i64>, ptr %A874 %tmp2 = load <2 x i64>, ptr %B875 %tmp3 = call <2 x i64> @llvm.aarch64.neon.addp.v2i64(<2 x i64> %tmp1, <2 x i64> %tmp2)876 ret <2 x i64> %tmp3877}878 879declare <8 x i8> @llvm.aarch64.neon.addp.v8i8(<8 x i8>, <8 x i8>) nounwind readnone880declare <16 x i8> @llvm.aarch64.neon.addp.v16i8(<16 x i8>, <16 x i8>) nounwind readnone881declare <4 x i16> @llvm.aarch64.neon.addp.v4i16(<4 x i16>, <4 x i16>) nounwind readnone882declare <8 x i16> @llvm.aarch64.neon.addp.v8i16(<8 x i16>, <8 x i16>) nounwind readnone883declare <2 x i32> @llvm.aarch64.neon.addp.v2i32(<2 x i32>, <2 x i32>) nounwind readnone884declare <4 x i32> @llvm.aarch64.neon.addp.v4i32(<4 x i32>, <4 x i32>) nounwind readnone885declare <2 x i64> @llvm.aarch64.neon.addp.v2i64(<2 x i64>, <2 x i64>) nounwind readnone886 887define <2 x float> @faddp_2s(ptr %A, ptr %B) nounwind {888; CHECK-LABEL: faddp_2s:889; CHECK: // %bb.0:890; CHECK-NEXT: ldr d0, [x0]891; CHECK-NEXT: ldr d1, [x1]892; CHECK-NEXT: faddp v0.2s, v0.2s, v1.2s893; CHECK-NEXT: ret894 %tmp1 = load <2 x float>, ptr %A895 %tmp2 = load <2 x float>, ptr %B896 %tmp3 = call <2 x float> @llvm.aarch64.neon.faddp.v2f32(<2 x float> %tmp1, <2 x float> %tmp2)897 ret <2 x float> %tmp3898}899 900define <4 x float> @faddp_4s(ptr %A, ptr %B) nounwind {901; CHECK-LABEL: faddp_4s:902; CHECK: // %bb.0:903; CHECK-NEXT: ldr q0, [x0]904; CHECK-NEXT: ldr q1, [x1]905; CHECK-NEXT: faddp v0.4s, v0.4s, v1.4s906; CHECK-NEXT: ret907 %tmp1 = load <4 x float>, ptr %A908 %tmp2 = load <4 x float>, ptr %B909 %tmp3 = call <4 x float> @llvm.aarch64.neon.faddp.v4f32(<4 x float> %tmp1, <4 x float> %tmp2)910 ret <4 x float> %tmp3911}912 913define <2 x double> @faddp_2d(ptr %A, ptr %B) nounwind {914; CHECK-LABEL: faddp_2d:915; CHECK: // %bb.0:916; CHECK-NEXT: ldr q0, [x0]917; CHECK-NEXT: ldr q1, [x1]918; CHECK-NEXT: faddp v0.2d, v0.2d, v1.2d919; CHECK-NEXT: ret920 %tmp1 = load <2 x double>, ptr %A921 %tmp2 = load <2 x double>, ptr %B922 %tmp3 = call <2 x double> @llvm.aarch64.neon.faddp.v2f64(<2 x double> %tmp1, <2 x double> %tmp2)923 ret <2 x double> %tmp3924}925 926declare <2 x float> @llvm.aarch64.neon.faddp.v2f32(<2 x float>, <2 x float>) nounwind readnone927declare <4 x float> @llvm.aarch64.neon.faddp.v4f32(<4 x float>, <4 x float>) nounwind readnone928declare <2 x double> @llvm.aarch64.neon.faddp.v2f64(<2 x double>, <2 x double>) nounwind readnone929 930define <2 x i64> @uaddl_duprhs(<4 x i32> %lhs, i32 %rhs) {931; CHECK-LABEL: uaddl_duprhs:932; CHECK: // %bb.0:933; CHECK-NEXT: dup v1.2s, w0934; CHECK-NEXT: uaddl v0.2d, v0.2s, v1.2s935; CHECK-NEXT: ret936 %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0937 %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1938 939 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>940 941 %lhs.ext = zext <2 x i32> %lhs.high to <2 x i64>942 %rhs.ext = zext <2 x i32> %rhsvec to <2 x i64>943 944 %res = add <2 x i64> %lhs.ext, %rhs.ext945 ret <2 x i64> %res946}947 948define <2 x i64> @uaddl2_duprhs(<4 x i32> %lhs, i32 %rhs) {949; CHECK-SD-LABEL: uaddl2_duprhs:950; CHECK-SD: // %bb.0:951; CHECK-SD-NEXT: dup v1.4s, w0952; CHECK-SD-NEXT: uaddl2 v0.2d, v0.4s, v1.4s953; CHECK-SD-NEXT: ret954;955; CHECK-GI-LABEL: uaddl2_duprhs:956; CHECK-GI: // %bb.0:957; CHECK-GI-NEXT: dup v1.2s, w0958; CHECK-GI-NEXT: ushll v1.2d, v1.2s, #0959; CHECK-GI-NEXT: uaddw2 v0.2d, v1.2d, v0.4s960; CHECK-GI-NEXT: ret961 %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 0962 %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 1963 964 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>965 966 %lhs.ext = zext <2 x i32> %lhs.high to <2 x i64>967 %rhs.ext = zext <2 x i32> %rhsvec to <2 x i64>968 969 %res = add <2 x i64> %lhs.ext, %rhs.ext970 ret <2 x i64> %res971}972 973define <2 x i64> @saddl_duplhs(i32 %lhs, <4 x i32> %rhs) {974; CHECK-LABEL: saddl_duplhs:975; CHECK: // %bb.0:976; CHECK-NEXT: dup v1.2s, w0977; CHECK-NEXT: saddl v0.2d, v1.2s, v0.2s978; CHECK-NEXT: ret979 %lhsvec.tmp = insertelement <2 x i32> undef, i32 %lhs, i32 0980 %lhsvec = insertelement <2 x i32> %lhsvec.tmp, i32 %lhs, i32 1981 982 %rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>983 984 %lhs.ext = sext <2 x i32> %lhsvec to <2 x i64>985 %rhs.ext = sext <2 x i32> %rhs.high to <2 x i64>986 987 %res = add <2 x i64> %lhs.ext, %rhs.ext988 ret <2 x i64> %res989}990 991define <2 x i64> @saddl2_duplhs(i32 %lhs, <4 x i32> %rhs) {992; CHECK-SD-LABEL: saddl2_duplhs:993; CHECK-SD: // %bb.0:994; CHECK-SD-NEXT: dup v1.4s, w0995; CHECK-SD-NEXT: saddl2 v0.2d, v1.4s, v0.4s996; CHECK-SD-NEXT: ret997;998; CHECK-GI-LABEL: saddl2_duplhs:999; CHECK-GI: // %bb.0:1000; CHECK-GI-NEXT: dup v1.2s, w01001; CHECK-GI-NEXT: sshll v1.2d, v1.2s, #01002; CHECK-GI-NEXT: saddw2 v0.2d, v1.2d, v0.4s1003; CHECK-GI-NEXT: ret1004 %lhsvec.tmp = insertelement <2 x i32> undef, i32 %lhs, i32 01005 %lhsvec = insertelement <2 x i32> %lhsvec.tmp, i32 %lhs, i32 11006 1007 %rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>1008 1009 %lhs.ext = sext <2 x i32> %lhsvec to <2 x i64>1010 %rhs.ext = sext <2 x i32> %rhs.high to <2 x i64>1011 1012 %res = add <2 x i64> %lhs.ext, %rhs.ext1013 ret <2 x i64> %res1014}1015 1016define <2 x i64> @usubl_duprhs(<4 x i32> %lhs, i32 %rhs) {1017; CHECK-LABEL: usubl_duprhs:1018; CHECK: // %bb.0:1019; CHECK-NEXT: dup v1.2s, w01020; CHECK-NEXT: usubl v0.2d, v0.2s, v1.2s1021; CHECK-NEXT: ret1022 %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 01023 %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 11024 1025 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>1026 1027 %lhs.ext = zext <2 x i32> %lhs.high to <2 x i64>1028 %rhs.ext = zext <2 x i32> %rhsvec to <2 x i64>1029 1030 %res = sub <2 x i64> %lhs.ext, %rhs.ext1031 ret <2 x i64> %res1032}1033 1034define <2 x i64> @usubl2_duprhs(<4 x i32> %lhs, i32 %rhs) {1035; CHECK-SD-LABEL: usubl2_duprhs:1036; CHECK-SD: // %bb.0:1037; CHECK-SD-NEXT: dup v1.4s, w01038; CHECK-SD-NEXT: usubl2 v0.2d, v0.4s, v1.4s1039; CHECK-SD-NEXT: ret1040;1041; CHECK-GI-LABEL: usubl2_duprhs:1042; CHECK-GI: // %bb.0:1043; CHECK-GI-NEXT: dup v1.2s, w01044; CHECK-GI-NEXT: mov d0, v0.d[1]1045; CHECK-GI-NEXT: usubl v0.2d, v0.2s, v1.2s1046; CHECK-GI-NEXT: ret1047 %rhsvec.tmp = insertelement <2 x i32> undef, i32 %rhs, i32 01048 %rhsvec = insertelement <2 x i32> %rhsvec.tmp, i32 %rhs, i32 11049 1050 %lhs.high = shufflevector <4 x i32> %lhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>1051 1052 %lhs.ext = zext <2 x i32> %lhs.high to <2 x i64>1053 %rhs.ext = zext <2 x i32> %rhsvec to <2 x i64>1054 1055 %res = sub <2 x i64> %lhs.ext, %rhs.ext1056 ret <2 x i64> %res1057}1058 1059define <2 x i64> @ssubl_duplhs(i32 %lhs, <4 x i32> %rhs) {1060; CHECK-LABEL: ssubl_duplhs:1061; CHECK: // %bb.0:1062; CHECK-NEXT: dup v1.2s, w01063; CHECK-NEXT: ssubl v0.2d, v1.2s, v0.2s1064; CHECK-NEXT: ret1065 %lhsvec.tmp = insertelement <2 x i32> undef, i32 %lhs, i32 01066 %lhsvec = insertelement <2 x i32> %lhsvec.tmp, i32 %lhs, i32 11067 1068 %rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 0, i32 1>1069 1070 %lhs.ext = sext <2 x i32> %lhsvec to <2 x i64>1071 %rhs.ext = sext <2 x i32> %rhs.high to <2 x i64>1072 1073 %res = sub <2 x i64> %lhs.ext, %rhs.ext1074 ret <2 x i64> %res1075}1076 1077define <2 x i64> @ssubl2_duplhs(i32 %lhs, <4 x i32> %rhs) {1078; CHECK-SD-LABEL: ssubl2_duplhs:1079; CHECK-SD: // %bb.0:1080; CHECK-SD-NEXT: dup v1.4s, w01081; CHECK-SD-NEXT: ssubl2 v0.2d, v1.4s, v0.4s1082; CHECK-SD-NEXT: ret1083;1084; CHECK-GI-LABEL: ssubl2_duplhs:1085; CHECK-GI: // %bb.0:1086; CHECK-GI-NEXT: dup v1.2s, w01087; CHECK-GI-NEXT: sshll v1.2d, v1.2s, #01088; CHECK-GI-NEXT: ssubw2 v0.2d, v1.2d, v0.4s1089; CHECK-GI-NEXT: ret1090 %lhsvec.tmp = insertelement <2 x i32> undef, i32 %lhs, i32 01091 %lhsvec = insertelement <2 x i32> %lhsvec.tmp, i32 %lhs, i32 11092 1093 %rhs.high = shufflevector <4 x i32> %rhs, <4 x i32> undef, <2 x i32> <i32 2, i32 3>1094 1095 %lhs.ext = sext <2 x i32> %lhsvec to <2 x i64>1096 %rhs.ext = sext <2 x i32> %rhs.high to <2 x i64>1097 1098 %res = sub <2 x i64> %lhs.ext, %rhs.ext1099 ret <2 x i64> %res1100}1101 1102define <8 x i8> @addhn8b_natural(ptr %A, ptr %B) nounwind {1103; CHECK-LABEL: addhn8b_natural:1104; CHECK: // %bb.0:1105; CHECK-NEXT: ldr q0, [x0]1106; CHECK-NEXT: ldr q1, [x1]1107; CHECK-NEXT: addhn v0.8b, v0.8h, v1.8h1108; CHECK-NEXT: ret1109 %tmp1 = load <8 x i16>, ptr %A1110 %tmp2 = load <8 x i16>, ptr %B1111 %sum = add <8 x i16> %tmp1, %tmp21112 %high_bits = lshr <8 x i16> %sum, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>1113 %narrowed = trunc <8 x i16> %high_bits to <8 x i8>1114 ret <8 x i8> %narrowed1115}1116 1117define <4 x i16> @addhn4h_natural(ptr %A, ptr %B) nounwind {1118; CHECK-LABEL: addhn4h_natural:1119; CHECK: // %bb.0:1120; CHECK-NEXT: ldr q0, [x0]1121; CHECK-NEXT: ldr q1, [x1]1122; CHECK-NEXT: addhn v0.4h, v0.4s, v1.4s1123; CHECK-NEXT: ret1124 %tmp1 = load <4 x i32>, ptr %A1125 %tmp2 = load <4 x i32>, ptr %B1126 %sum = add <4 x i32> %tmp1, %tmp21127 %high_bits = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>1128 %narrowed = trunc <4 x i32> %high_bits to <4 x i16>1129 ret <4 x i16> %narrowed1130}1131 1132define <2 x i32> @addhn2s_natural(ptr %A, ptr %B) nounwind {1133; CHECK-LABEL: addhn2s_natural:1134; CHECK: // %bb.0:1135; CHECK-NEXT: ldr q0, [x0]1136; CHECK-NEXT: ldr q1, [x1]1137; CHECK-NEXT: addhn v0.2s, v0.2d, v1.2d1138; CHECK-NEXT: ret1139 %tmp1 = load <2 x i64>, ptr %A1140 %tmp2 = load <2 x i64>, ptr %B1141 %sum = add <2 x i64> %tmp1, %tmp21142 %high_bits = lshr <2 x i64> %sum, <i64 32, i64 32>1143 %narrowed = trunc <2 x i64> %high_bits to <2 x i32>1144 ret <2 x i32> %narrowed1145}1146 1147define <16 x i8> @addhn2_16b_natural(<8 x i8> %low, ptr %A, ptr %B) nounwind {1148; CHECK-LABEL: addhn2_16b_natural:1149; CHECK: // %bb.0:1150; CHECK-NEXT: ldr q1, [x0]1151; CHECK-NEXT: ldr q2, [x1]1152; CHECK-NEXT: // kill: def $d0 killed $d0 def $q01153; CHECK-NEXT: addhn2 v0.16b, v1.8h, v2.8h1154; CHECK-NEXT: ret1155 %tmp1 = load <8 x i16>, ptr %A1156 %tmp2 = load <8 x i16>, ptr %B1157 %sum = add <8 x i16> %tmp1, %tmp21158 %high_bits = lshr <8 x i16> %sum, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>1159 %narrowed = trunc <8 x i16> %high_bits to <8 x i8>1160 %res = shufflevector <8 x i8> %low, <8 x i8> %narrowed, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>1161 ret <16 x i8> %res1162}1163 1164define <8 x i16> @addhn2_8h_natural(<4 x i16> %low, ptr %A, ptr %B) nounwind {1165; CHECK-LABEL: addhn2_8h_natural:1166; CHECK: // %bb.0:1167; CHECK-NEXT: ldr q1, [x0]1168; CHECK-NEXT: ldr q2, [x1]1169; CHECK-NEXT: // kill: def $d0 killed $d0 def $q01170; CHECK-NEXT: addhn2 v0.8h, v1.4s, v2.4s1171; CHECK-NEXT: ret1172 %tmp1 = load <4 x i32>, ptr %A1173 %tmp2 = load <4 x i32>, ptr %B1174 %sum = add <4 x i32> %tmp1, %tmp21175 %high_bits = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>1176 %narrowed = trunc <4 x i32> %high_bits to <4 x i16>1177 %res = shufflevector <4 x i16> %low, <4 x i16> %narrowed, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>1178 ret <8 x i16> %res1179}1180 1181define <4 x i32> @addhn2_4s_natural(<2 x i32> %low, ptr %A, ptr %B) nounwind {1182; CHECK-LABEL: addhn2_4s_natural:1183; CHECK: // %bb.0:1184; CHECK-NEXT: ldr q1, [x0]1185; CHECK-NEXT: ldr q2, [x1]1186; CHECK-NEXT: // kill: def $d0 killed $d0 def $q01187; CHECK-NEXT: addhn2 v0.4s, v1.2d, v2.2d1188; CHECK-NEXT: ret1189 %tmp1 = load <2 x i64>, ptr %A1190 %tmp2 = load <2 x i64>, ptr %B1191 %sum = add <2 x i64> %tmp1, %tmp21192 %high_bits = lshr <2 x i64> %sum, <i64 32, i64 32>1193 %narrowed = trunc <2 x i64> %high_bits to <2 x i32>1194 %res = shufflevector <2 x i32> %low, <2 x i32> %narrowed, <4 x i32> <i32 0, i32 1, i32 2, i32 3>1195 ret <4 x i32> %res1196}1197 1198define <4 x i32> @addhn_addhn2_4s(ptr %A, ptr %B, ptr %C, ptr %D) nounwind {1199; CHECK-LABEL: addhn_addhn2_4s:1200; CHECK: // %bb.0:1201; CHECK-NEXT: ldr q1, [x0]1202; CHECK-NEXT: ldr q2, [x1]1203; CHECK-NEXT: addhn v0.2s, v1.2d, v2.2d1204; CHECK-NEXT: addhn2 v0.4s, v1.2d, v2.2d1205; CHECK-NEXT: ret1206 %tmp1 = load <2 x i64>, ptr %A1207 %tmp2 = load <2 x i64>, ptr %B1208 %sum1 = add <2 x i64> %tmp1, %tmp21209 %low_bits = lshr <2 x i64> %sum1, <i64 32, i64 32>1210 %narrowed1 = trunc <2 x i64> %low_bits to <2 x i32>1211 %tmp3 = load <2 x i64>, ptr %C1212 %tmp4 = load <2 x i64>, ptr %D1213 %sum2 = add <2 x i64> %tmp3, %tmp41214 %high_bits = lshr <2 x i64> %sum1, <i64 32, i64 32>1215 %narrowed2 = trunc <2 x i64> %high_bits to <2 x i32>1216 %res = shufflevector <2 x i32> %narrowed1, <2 x i32> %narrowed2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>1217 ret <4 x i32> %res1218}1219 1220define <8 x i8> @subhn8b_natural(ptr %A, ptr %B) nounwind {1221; CHECK-LABEL: subhn8b_natural:1222; CHECK: // %bb.0:1223; CHECK-NEXT: ldr q0, [x0]1224; CHECK-NEXT: ldr q1, [x1]1225; CHECK-NEXT: subhn v0.8b, v0.8h, v1.8h1226; CHECK-NEXT: ret1227 %tmp1 = load <8 x i16>, ptr %A1228 %tmp2 = load <8 x i16>, ptr %B1229 %diff = sub <8 x i16> %tmp1, %tmp21230 %high_bits = lshr <8 x i16> %diff, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>1231 %narrowed = trunc <8 x i16> %high_bits to <8 x i8>1232 ret <8 x i8> %narrowed1233}1234 1235define <4 x i16> @subhn4h_natural(ptr %A, ptr %B) nounwind {1236; CHECK-LABEL: subhn4h_natural:1237; CHECK: // %bb.0:1238; CHECK-NEXT: ldr q0, [x0]1239; CHECK-NEXT: ldr q1, [x1]1240; CHECK-NEXT: subhn v0.4h, v0.4s, v1.4s1241; CHECK-NEXT: ret1242 %tmp1 = load <4 x i32>, ptr %A1243 %tmp2 = load <4 x i32>, ptr %B1244 %diff = sub <4 x i32> %tmp1, %tmp21245 %high_bits = lshr <4 x i32> %diff, <i32 16, i32 16, i32 16, i32 16>1246 %narrowed = trunc <4 x i32> %high_bits to <4 x i16>1247 ret <4 x i16> %narrowed1248}1249 1250define <2 x i32> @subhn2s_natural(ptr %A, ptr %B) nounwind {1251; CHECK-LABEL: subhn2s_natural:1252; CHECK: // %bb.0:1253; CHECK-NEXT: ldr q0, [x0]1254; CHECK-NEXT: ldr q1, [x1]1255; CHECK-NEXT: subhn v0.2s, v0.2d, v1.2d1256; CHECK-NEXT: ret1257 %tmp1 = load <2 x i64>, ptr %A1258 %tmp2 = load <2 x i64>, ptr %B1259 %diff = sub <2 x i64> %tmp1, %tmp21260 %high_bits = lshr <2 x i64> %diff, <i64 32, i64 32>1261 %narrowed = trunc <2 x i64> %high_bits to <2 x i32>1262 ret <2 x i32> %narrowed1263}1264 1265define <16 x i8> @subhn2_16b_natural(<8 x i8> %low, ptr %A, ptr %B) nounwind {1266; CHECK-LABEL: subhn2_16b_natural:1267; CHECK: // %bb.0:1268; CHECK-NEXT: ldr q1, [x0]1269; CHECK-NEXT: ldr q2, [x1]1270; CHECK-NEXT: // kill: def $d0 killed $d0 def $q01271; CHECK-NEXT: subhn2 v0.16b, v1.8h, v2.8h1272; CHECK-NEXT: ret1273 %tmp1 = load <8 x i16>, ptr %A1274 %tmp2 = load <8 x i16>, ptr %B1275 %diff = sub <8 x i16> %tmp1, %tmp21276 %high_bits = lshr <8 x i16> %diff, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>1277 %narrowed = trunc <8 x i16> %high_bits to <8 x i8>1278 %res = shufflevector <8 x i8> %low, <8 x i8> %narrowed, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>1279 ret <16 x i8> %res1280}1281 1282define <8 x i16> @subhn2_8h_natural(<4 x i16> %low, ptr %A, ptr %B) nounwind {1283; CHECK-LABEL: subhn2_8h_natural:1284; CHECK: // %bb.0:1285; CHECK-NEXT: ldr q1, [x0]1286; CHECK-NEXT: ldr q2, [x1]1287; CHECK-NEXT: // kill: def $d0 killed $d0 def $q01288; CHECK-NEXT: subhn2 v0.8h, v1.4s, v2.4s1289; CHECK-NEXT: ret1290 %tmp1 = load <4 x i32>, ptr %A1291 %tmp2 = load <4 x i32>, ptr %B1292 %diff = sub <4 x i32> %tmp1, %tmp21293 %high_bits = lshr <4 x i32> %diff, <i32 16, i32 16, i32 16, i32 16>1294 %narrowed = trunc <4 x i32> %high_bits to <4 x i16>1295 %res = shufflevector <4 x i16> %low, <4 x i16> %narrowed, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>1296 ret <8 x i16> %res1297}1298 1299define <4 x i32> @subhn2_4s_natural(<2 x i32> %low, ptr %A, ptr %B) nounwind {1300; CHECK-LABEL: subhn2_4s_natural:1301; CHECK: // %bb.0:1302; CHECK-NEXT: ldr q1, [x0]1303; CHECK-NEXT: ldr q2, [x1]1304; CHECK-NEXT: // kill: def $d0 killed $d0 def $q01305; CHECK-NEXT: subhn2 v0.4s, v1.2d, v2.2d1306; CHECK-NEXT: ret1307 %tmp1 = load <2 x i64>, ptr %A1308 %tmp2 = load <2 x i64>, ptr %B1309 %diff = sub <2 x i64> %tmp1, %tmp21310 %high_bits = lshr <2 x i64> %diff, <i64 32, i64 32>1311 %narrowed = trunc <2 x i64> %high_bits to <2 x i32>1312 %res = shufflevector <2 x i32> %low, <2 x i32> %narrowed, <4 x i32> <i32 0, i32 1, i32 2, i32 3>1313 ret <4 x i32> %res1314}1315 1316define <16 x i8> @neg_narrow_i8(<16 x i16> %a) {1317; CHECK-LABEL: neg_narrow_i8:1318; CHECK: // %bb.0:1319; CHECK-NEXT: movi v2.2d, #0xffffffffffffffff1320; CHECK-NEXT: subhn v0.8b, v2.8h, v0.8h1321; CHECK-NEXT: subhn2 v0.16b, v2.8h, v1.8h1322; CHECK-NEXT: ret1323 %not.i = xor <16 x i16> %a, splat (i16 -1)1324 %s = lshr <16 x i16> %not.i, splat (i16 8)1325 %vshrn_n = trunc nuw <16 x i16> %s to <16 x i8>1326 ret <16 x i8> %vshrn_n1327}1328 1329define <8 x i16> @neg_narrow_i16(<8 x i32> %a) {1330; CHECK-LABEL: neg_narrow_i16:1331; CHECK: // %bb.0:1332; CHECK-NEXT: movi v2.2d, #0xffffffffffffffff1333; CHECK-NEXT: subhn v0.4h, v2.4s, v0.4s1334; CHECK-NEXT: subhn2 v0.8h, v2.4s, v1.4s1335; CHECK-NEXT: ret1336 %not.i = xor <8 x i32> %a, splat (i32 -1)1337 %s = lshr <8 x i32> %not.i, splat (i32 16)1338 %vshrn_n = trunc nuw <8 x i32> %s to <8 x i16>1339 ret <8 x i16> %vshrn_n1340}1341 1342define <4 x i32> @neg_narrow_i32(<4 x i64> %a) {1343; CHECK-LABEL: neg_narrow_i32:1344; CHECK: // %bb.0:1345; CHECK-NEXT: movi v2.2d, #0xffffffffffffffff1346; CHECK-NEXT: subhn v0.2s, v2.2d, v0.2d1347; CHECK-NEXT: subhn2 v0.4s, v2.2d, v1.2d1348; CHECK-NEXT: ret1349 %not.i = xor <4 x i64> %a, splat (i64 -1)1350 %s = lshr <4 x i64> %not.i, splat (i64 32)1351 %vshrn_n = trunc nuw <4 x i64> %s to <4 x i32>1352 ret <4 x i32> %vshrn_n1353}1354