454 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 %s3; RUN: llc < %s -mtriple=arm64-eabi -global-isel | FileCheck %s4 5define signext i8 @test_vaddv_s8(<8 x i8> %a1) {6; CHECK-LABEL: test_vaddv_s8:7; CHECK: // %bb.0: // %entry8; CHECK-NEXT: addv b0, v0.8b9; CHECK-NEXT: smov w0, v0.b[0]10; CHECK-NEXT: ret11entry:12 %vaddv.i = tail call i32 @llvm.aarch64.neon.saddv.i32.v8i8(<8 x i8> %a1)13 %0 = trunc i32 %vaddv.i to i814 ret i8 %015}16 17define <8 x i8> @test_vaddv_s8_used_by_laneop(<8 x i8> %a1, <8 x i8> %a2) {18; CHECK-LABEL: test_vaddv_s8_used_by_laneop:19; CHECK: // %bb.0: // %entry20; CHECK-NEXT: addv b1, v1.8b21; CHECK-NEXT: // kill: def $d0 killed $d0 def $q022; CHECK-NEXT: mov v0.b[3], v1.b[0]23; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q024; CHECK-NEXT: ret25entry:26 %0 = tail call i32 @llvm.aarch64.neon.saddv.i32.v8i8(<8 x i8> %a2)27 %1 = trunc i32 %0 to i828 %2 = insertelement <8 x i8> %a1, i8 %1, i32 329 ret <8 x i8> %230}31 32define signext i16 @test_vaddv_s16(<4 x i16> %a1) {33; CHECK-LABEL: test_vaddv_s16:34; CHECK: // %bb.0: // %entry35; CHECK-NEXT: addv h0, v0.4h36; CHECK-NEXT: smov w0, v0.h[0]37; CHECK-NEXT: ret38entry:39 %vaddv.i = tail call i32 @llvm.aarch64.neon.saddv.i32.v4i16(<4 x i16> %a1)40 %0 = trunc i32 %vaddv.i to i1641 ret i16 %042}43 44define <4 x i16> @test_vaddv_s16_used_by_laneop(<4 x i16> %a1, <4 x i16> %a2) {45; CHECK-LABEL: test_vaddv_s16_used_by_laneop:46; CHECK: // %bb.0: // %entry47; CHECK-NEXT: addv h1, v1.4h48; CHECK-NEXT: // kill: def $d0 killed $d0 def $q049; CHECK-NEXT: mov v0.h[3], v1.h[0]50; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q051; CHECK-NEXT: ret52entry:53 %0 = tail call i32 @llvm.aarch64.neon.saddv.i32.v4i16(<4 x i16> %a2)54 %1 = trunc i32 %0 to i1655 %2 = insertelement <4 x i16> %a1, i16 %1, i32 356 ret <4 x i16> %257}58 59define i32 @test_vaddv_s32(<2 x i32> %a1) {60; CHECK-LABEL: test_vaddv_s32:61; CHECK: // %bb.0: // %entry62; CHECK-NEXT: addp v0.2s, v0.2s, v0.2s63; CHECK-NEXT: fmov w0, s064; CHECK-NEXT: ret65; 2 x i32 is not supported by the ISA, thus, this is a special case66entry:67 %vaddv.i = tail call i32 @llvm.aarch64.neon.saddv.i32.v2i32(<2 x i32> %a1)68 ret i32 %vaddv.i69}70 71define <2 x i32> @test_vaddv_s32_used_by_laneop(<2 x i32> %a1, <2 x i32> %a2) {72; CHECK-LABEL: test_vaddv_s32_used_by_laneop:73; CHECK: // %bb.0: // %entry74; CHECK-NEXT: addp v1.2s, v1.2s, v1.2s75; CHECK-NEXT: // kill: def $d0 killed $d0 def $q076; CHECK-NEXT: mov v0.s[1], v1.s[0]77; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q078; CHECK-NEXT: ret79entry:80 %0 = tail call i32 @llvm.aarch64.neon.saddv.i32.v2i32(<2 x i32> %a2)81 %1 = insertelement <2 x i32> %a1, i32 %0, i32 182 ret <2 x i32> %183}84 85define i64 @test_vaddv_s64(<2 x i64> %a1) {86; CHECK-LABEL: test_vaddv_s64:87; CHECK: // %bb.0: // %entry88; CHECK-NEXT: addp d0, v0.2d89; CHECK-NEXT: fmov x0, d090; CHECK-NEXT: ret91entry:92 %vaddv.i = tail call i64 @llvm.aarch64.neon.saddv.i64.v2i64(<2 x i64> %a1)93 ret i64 %vaddv.i94}95 96define <2 x i64> @test_vaddv_s64_used_by_laneop(<2 x i64> %a1, <2 x i64> %a2) {97; CHECK-LABEL: test_vaddv_s64_used_by_laneop:98; CHECK: // %bb.0: // %entry99; CHECK-NEXT: addp d1, v1.2d100; CHECK-NEXT: mov v0.d[1], v1.d[0]101; CHECK-NEXT: ret102entry:103 %0 = tail call i64 @llvm.aarch64.neon.saddv.i64.v2i64(<2 x i64> %a2)104 %1 = insertelement <2 x i64> %a1, i64 %0, i64 1105 ret <2 x i64> %1106}107 108define zeroext i8 @test_vaddv_u8(<8 x i8> %a1) {109; CHECK-LABEL: test_vaddv_u8:110; CHECK: // %bb.0: // %entry111; CHECK-NEXT: addv b0, v0.8b112; CHECK-NEXT: fmov w0, s0113; CHECK-NEXT: ret114entry:115 %vaddv.i = tail call i32 @llvm.aarch64.neon.uaddv.i32.v8i8(<8 x i8> %a1)116 %0 = trunc i32 %vaddv.i to i8117 ret i8 %0118}119 120define <8 x i8> @test_vaddv_u8_used_by_laneop(<8 x i8> %a1, <8 x i8> %a2) {121; CHECK-LABEL: test_vaddv_u8_used_by_laneop:122; CHECK: // %bb.0: // %entry123; CHECK-NEXT: addv b1, v1.8b124; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0125; CHECK-NEXT: mov v0.b[3], v1.b[0]126; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0127; CHECK-NEXT: ret128entry:129 %0 = tail call i32 @llvm.aarch64.neon.uaddv.i32.v8i8(<8 x i8> %a2)130 %1 = trunc i32 %0 to i8131 %2 = insertelement <8 x i8> %a1, i8 %1, i32 3132 ret <8 x i8> %2133}134 135define i32 @test_vaddv_u8_masked(<8 x i8> %a1) {136; CHECK-LABEL: test_vaddv_u8_masked:137; CHECK: // %bb.0: // %entry138; CHECK-NEXT: addv b0, v0.8b139; CHECK-NEXT: fmov w0, s0140; CHECK-NEXT: ret141entry:142 %vaddv.i = tail call i32 @llvm.aarch64.neon.uaddv.i32.v8i8(<8 x i8> %a1)143 %0 = and i32 %vaddv.i, 511 ; 0x1ff144 ret i32 %0145}146 147define zeroext i16 @test_vaddv_u16(<4 x i16> %a1) {148; CHECK-LABEL: test_vaddv_u16:149; CHECK: // %bb.0: // %entry150; CHECK-NEXT: addv h0, v0.4h151; CHECK-NEXT: fmov w0, s0152; CHECK-NEXT: ret153entry:154 %vaddv.i = tail call i32 @llvm.aarch64.neon.uaddv.i32.v4i16(<4 x i16> %a1)155 %0 = trunc i32 %vaddv.i to i16156 ret i16 %0157}158 159define <4 x i16> @test_vaddv_u16_used_by_laneop(<4 x i16> %a1, <4 x i16> %a2) {160; CHECK-LABEL: test_vaddv_u16_used_by_laneop:161; CHECK: // %bb.0: // %entry162; CHECK-NEXT: addv h1, v1.4h163; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0164; CHECK-NEXT: mov v0.h[3], v1.h[0]165; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0166; CHECK-NEXT: ret167entry:168 %0 = tail call i32 @llvm.aarch64.neon.uaddv.i32.v4i16(<4 x i16> %a2)169 %1 = trunc i32 %0 to i16170 %2 = insertelement <4 x i16> %a1, i16 %1, i32 3171 ret <4 x i16> %2172}173 174define i32 @test_vaddv_u16_masked(<4 x i16> %a1) {175; CHECK-LABEL: test_vaddv_u16_masked:176; CHECK: // %bb.0: // %entry177; CHECK-NEXT: addv h0, v0.4h178; CHECK-NEXT: fmov w0, s0179; CHECK-NEXT: ret180entry:181 %vaddv.i = tail call i32 @llvm.aarch64.neon.uaddv.i32.v4i16(<4 x i16> %a1)182 %0 = and i32 %vaddv.i, 3276799 ; 0x31ffff183 ret i32 %0184}185 186define i32 @test_vaddv_u32(<2 x i32> %a1) {187; CHECK-LABEL: test_vaddv_u32:188; CHECK: // %bb.0: // %entry189; CHECK-NEXT: addp v0.2s, v0.2s, v0.2s190; CHECK-NEXT: fmov w0, s0191; CHECK-NEXT: ret192; 2 x i32 is not supported by the ISA, thus, this is a special case193entry:194 %vaddv.i = tail call i32 @llvm.aarch64.neon.uaddv.i32.v2i32(<2 x i32> %a1)195 ret i32 %vaddv.i196}197 198define <2 x i32> @test_vaddv_u32_used_by_laneop(<2 x i32> %a1, <2 x i32> %a2) {199; CHECK-LABEL: test_vaddv_u32_used_by_laneop:200; CHECK: // %bb.0: // %entry201; CHECK-NEXT: addp v1.2s, v1.2s, v1.2s202; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0203; CHECK-NEXT: mov v0.s[1], v1.s[0]204; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0205; CHECK-NEXT: ret206entry:207 %0 = tail call i32 @llvm.aarch64.neon.uaddv.i32.v2i32(<2 x i32> %a2)208 %1 = insertelement <2 x i32> %a1, i32 %0, i32 1209 ret <2 x i32> %1210}211 212define float @test_vaddv_f32(<2 x float> %a1) {213; CHECK-LABEL: test_vaddv_f32:214; CHECK: // %bb.0: // %entry215; CHECK-NEXT: faddp s0, v0.2s216; CHECK-NEXT: ret217entry:218 %vaddv.i = tail call float @llvm.aarch64.neon.faddv.f32.v2f32(<2 x float> %a1)219 ret float %vaddv.i220}221 222define float @test_vaddv_v4f32(<4 x float> %a1) {223; CHECK-LABEL: test_vaddv_v4f32:224; CHECK: // %bb.0: // %entry225; CHECK-NEXT: faddp v0.4s, v0.4s, v0.4s226; CHECK-NEXT: faddp s0, v0.2s227; CHECK-NEXT: ret228entry:229 %vaddv.i = tail call float @llvm.aarch64.neon.faddv.f32.v4f32(<4 x float> %a1)230 ret float %vaddv.i231}232 233define double @test_vaddv_f64(<2 x double> %a1) {234; CHECK-LABEL: test_vaddv_f64:235; CHECK: // %bb.0: // %entry236; CHECK-NEXT: faddp d0, v0.2d237; CHECK-NEXT: ret238entry:239 %vaddv.i = tail call double @llvm.aarch64.neon.faddv.f64.v2f64(<2 x double> %a1)240 ret double %vaddv.i241}242 243define i64 @test_vaddv_u64(<2 x i64> %a1) {244; CHECK-LABEL: test_vaddv_u64:245; CHECK: // %bb.0: // %entry246; CHECK-NEXT: addp d0, v0.2d247; CHECK-NEXT: fmov x0, d0248; CHECK-NEXT: ret249entry:250 %vaddv.i = tail call i64 @llvm.aarch64.neon.uaddv.i64.v2i64(<2 x i64> %a1)251 ret i64 %vaddv.i252}253 254define <2 x i64> @test_vaddv_u64_used_by_laneop(<2 x i64> %a1, <2 x i64> %a2) {255; CHECK-LABEL: test_vaddv_u64_used_by_laneop:256; CHECK: // %bb.0: // %entry257; CHECK-NEXT: addp d1, v1.2d258; CHECK-NEXT: mov v0.d[1], v1.d[0]259; CHECK-NEXT: ret260entry:261 %0 = tail call i64 @llvm.aarch64.neon.uaddv.i64.v2i64(<2 x i64> %a2)262 %1 = insertelement <2 x i64> %a1, i64 %0, i64 1263 ret <2 x i64> %1264}265 266define <1 x i64> @test_vaddv_u64_to_vec(<2 x i64> %a1) {267; CHECK-LABEL: test_vaddv_u64_to_vec:268; CHECK: // %bb.0: // %entry269; CHECK-NEXT: addp d0, v0.2d270; CHECK-NEXT: ret271entry:272 %vaddv.i = tail call i64 @llvm.aarch64.neon.uaddv.i64.v2i64(<2 x i64> %a1)273 %vec = insertelement <1 x i64> undef, i64 %vaddv.i, i32 0274 ret <1 x i64> %vec275}276 277define signext i8 @test_vaddvq_s8(<16 x i8> %a1) {278; CHECK-LABEL: test_vaddvq_s8:279; CHECK: // %bb.0: // %entry280; CHECK-NEXT: addv b0, v0.16b281; CHECK-NEXT: smov w0, v0.b[0]282; CHECK-NEXT: ret283entry:284 %vaddv.i = tail call i32 @llvm.aarch64.neon.saddv.i32.v16i8(<16 x i8> %a1)285 %0 = trunc i32 %vaddv.i to i8286 ret i8 %0287}288 289define <16 x i8> @test_vaddvq_s8_used_by_laneop(<16 x i8> %a1, <16 x i8> %a2) {290; CHECK-LABEL: test_vaddvq_s8_used_by_laneop:291; CHECK: // %bb.0: // %entry292; CHECK-NEXT: addv b1, v1.16b293; CHECK-NEXT: mov v0.b[3], v1.b[0]294; CHECK-NEXT: ret295entry:296 %0 = tail call i32 @llvm.aarch64.neon.saddv.i32.v16i8(<16 x i8> %a2)297 %1 = trunc i32 %0 to i8298 %2 = insertelement <16 x i8> %a1, i8 %1, i32 3299 ret <16 x i8> %2300}301 302define signext i16 @test_vaddvq_s16(<8 x i16> %a1) {303; CHECK-LABEL: test_vaddvq_s16:304; CHECK: // %bb.0: // %entry305; CHECK-NEXT: addv h0, v0.8h306; CHECK-NEXT: smov w0, v0.h[0]307; CHECK-NEXT: ret308entry:309 %vaddv.i = tail call i32 @llvm.aarch64.neon.saddv.i32.v8i16(<8 x i16> %a1)310 %0 = trunc i32 %vaddv.i to i16311 ret i16 %0312}313 314define <8 x i16> @test_vaddvq_s16_used_by_laneop(<8 x i16> %a1, <8 x i16> %a2) {315; CHECK-LABEL: test_vaddvq_s16_used_by_laneop:316; CHECK: // %bb.0: // %entry317; CHECK-NEXT: addv h1, v1.8h318; CHECK-NEXT: mov v0.h[3], v1.h[0]319; CHECK-NEXT: ret320entry:321 %0 = tail call i32 @llvm.aarch64.neon.saddv.i32.v8i16(<8 x i16> %a2)322 %1 = trunc i32 %0 to i16323 %2 = insertelement <8 x i16> %a1, i16 %1, i32 3324 ret <8 x i16> %2325}326 327define i32 @test_vaddvq_s32(<4 x i32> %a1) {328; CHECK-LABEL: test_vaddvq_s32:329; CHECK: // %bb.0: // %entry330; CHECK-NEXT: addv s0, v0.4s331; CHECK-NEXT: fmov w0, s0332; CHECK-NEXT: ret333entry:334 %vaddv.i = tail call i32 @llvm.aarch64.neon.saddv.i32.v4i32(<4 x i32> %a1)335 ret i32 %vaddv.i336}337 338define <4 x i32> @test_vaddvq_s32_used_by_laneop(<4 x i32> %a1, <4 x i32> %a2) {339; CHECK-LABEL: test_vaddvq_s32_used_by_laneop:340; CHECK: // %bb.0: // %entry341; CHECK-NEXT: addv s1, v1.4s342; CHECK-NEXT: mov v0.s[3], v1.s[0]343; CHECK-NEXT: ret344entry:345 %0 = tail call i32 @llvm.aarch64.neon.saddv.i32.v4i32(<4 x i32> %a2)346 %1 = insertelement <4 x i32> %a1, i32 %0, i32 3347 ret <4 x i32> %1348}349 350define zeroext i8 @test_vaddvq_u8(<16 x i8> %a1) {351; CHECK-LABEL: test_vaddvq_u8:352; CHECK: // %bb.0: // %entry353; CHECK-NEXT: addv b0, v0.16b354; CHECK-NEXT: fmov w0, s0355; CHECK-NEXT: ret356entry:357 %vaddv.i = tail call i32 @llvm.aarch64.neon.uaddv.i32.v16i8(<16 x i8> %a1)358 %0 = trunc i32 %vaddv.i to i8359 ret i8 %0360}361 362define <16 x i8> @test_vaddvq_u8_used_by_laneop(<16 x i8> %a1, <16 x i8> %a2) {363; CHECK-LABEL: test_vaddvq_u8_used_by_laneop:364; CHECK: // %bb.0: // %entry365; CHECK-NEXT: addv b1, v1.16b366; CHECK-NEXT: mov v0.b[3], v1.b[0]367; CHECK-NEXT: ret368entry:369 %0 = tail call i32 @llvm.aarch64.neon.uaddv.i32.v16i8(<16 x i8> %a2)370 %1 = trunc i32 %0 to i8371 %2 = insertelement <16 x i8> %a1, i8 %1, i32 3372 ret <16 x i8> %2373}374 375define zeroext i16 @test_vaddvq_u16(<8 x i16> %a1) {376; CHECK-LABEL: test_vaddvq_u16:377; CHECK: // %bb.0: // %entry378; CHECK-NEXT: addv h0, v0.8h379; CHECK-NEXT: fmov w0, s0380; CHECK-NEXT: ret381entry:382 %vaddv.i = tail call i32 @llvm.aarch64.neon.uaddv.i32.v8i16(<8 x i16> %a1)383 %0 = trunc i32 %vaddv.i to i16384 ret i16 %0385}386 387define <8 x i16> @test_vaddvq_u16_used_by_laneop(<8 x i16> %a1, <8 x i16> %a2) {388; CHECK-LABEL: test_vaddvq_u16_used_by_laneop:389; CHECK: // %bb.0: // %entry390; CHECK-NEXT: addv h1, v1.8h391; CHECK-NEXT: mov v0.h[3], v1.h[0]392; CHECK-NEXT: ret393entry:394 %0 = tail call i32 @llvm.aarch64.neon.uaddv.i32.v8i16(<8 x i16> %a2)395 %1 = trunc i32 %0 to i16396 %2 = insertelement <8 x i16> %a1, i16 %1, i32 3397 ret <8 x i16> %2398}399 400define i32 @test_vaddvq_u32(<4 x i32> %a1) {401; CHECK-LABEL: test_vaddvq_u32:402; CHECK: // %bb.0: // %entry403; CHECK-NEXT: addv s0, v0.4s404; CHECK-NEXT: fmov w0, s0405; CHECK-NEXT: ret406entry:407 %vaddv.i = tail call i32 @llvm.aarch64.neon.uaddv.i32.v4i32(<4 x i32> %a1)408 ret i32 %vaddv.i409}410 411define <4 x i32> @test_vaddvq_u32_used_by_laneop(<4 x i32> %a1, <4 x i32> %a2) {412; CHECK-LABEL: test_vaddvq_u32_used_by_laneop:413; CHECK: // %bb.0: // %entry414; CHECK-NEXT: addv s1, v1.4s415; CHECK-NEXT: mov v0.s[3], v1.s[0]416; CHECK-NEXT: ret417entry:418 %0 = tail call i32 @llvm.aarch64.neon.uaddv.i32.v4i32(<4 x i32> %a2)419 %1 = insertelement <4 x i32> %a1, i32 %0, i32 3420 ret <4 x i32> %1421}422 423declare i32 @llvm.aarch64.neon.uaddv.i32.v4i32(<4 x i32>)424 425declare i32 @llvm.aarch64.neon.uaddv.i32.v8i16(<8 x i16>)426 427declare i32 @llvm.aarch64.neon.uaddv.i32.v16i8(<16 x i8>)428 429declare i32 @llvm.aarch64.neon.saddv.i32.v4i32(<4 x i32>)430 431declare i32 @llvm.aarch64.neon.saddv.i32.v8i16(<8 x i16>)432 433declare i32 @llvm.aarch64.neon.saddv.i32.v16i8(<16 x i8>)434 435declare i64 @llvm.aarch64.neon.uaddv.i64.v2i64(<2 x i64>)436 437declare i32 @llvm.aarch64.neon.uaddv.i32.v2i32(<2 x i32>)438 439declare i32 @llvm.aarch64.neon.uaddv.i32.v4i16(<4 x i16>)440 441declare i32 @llvm.aarch64.neon.uaddv.i32.v8i8(<8 x i8>)442 443declare i32 @llvm.aarch64.neon.saddv.i32.v2i32(<2 x i32>)444 445declare i64 @llvm.aarch64.neon.saddv.i64.v2i64(<2 x i64>)446 447declare i32 @llvm.aarch64.neon.saddv.i32.v4i16(<4 x i16>)448 449declare i32 @llvm.aarch64.neon.saddv.i32.v8i8(<8 x i8>)450 451declare float @llvm.aarch64.neon.faddv.f32.v2f32(<2 x float> %a1)452declare float @llvm.aarch64.neon.faddv.f32.v4f32(<4 x float> %a1)453declare double @llvm.aarch64.neon.faddv.f64.v2f64(<2 x double> %a1)454