| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 |
| ; RUN: llc < %s | FileCheck %s |
| target triple = "arm64-none-linux-gnu" |
| |
| define <4 x half> @test_vsqrt_f16(<4 x half> %a) #0 { |
| ; CHECK-LABEL: test_vsqrt_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fsqrt v0.4h, v0.4h |
| ; CHECK-NEXT: ret |
| entry: |
| %vsqrt.i = call <4 x half> @llvm.experimental.constrained.sqrt.v4f16(<4 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <4 x half> %vsqrt.i |
| } |
| |
| define <8 x half> @test_vsqrtq_f16(<8 x half> %a) #0 { |
| ; CHECK-LABEL: test_vsqrtq_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fsqrt v0.8h, v0.8h |
| ; CHECK-NEXT: ret |
| entry: |
| %vsqrt.i = call <8 x half> @llvm.experimental.constrained.sqrt.v8f16(<8 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <8 x half> %vsqrt.i |
| } |
| |
| define <4 x half> @test_vfma_f16(<4 x half> %a, <4 x half> %b, <4 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfma_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fmla v0.4h, v2.4h, v1.4h |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %b, <4 x half> %c, <4 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <4 x half> %0 |
| } |
| |
| define <8 x half> @test_vfmaq_f16(<8 x half> %a, <8 x half> %b, <8 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmaq_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fmla v0.8h, v2.8h, v1.8h |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %b, <8 x half> %c, <8 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <8 x half> %0 |
| } |
| |
| define <4 x half> @test_vfms_f16(<4 x half> %a, <4 x half> %b, <4 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfms_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fmls v0.4h, v2.4h, v1.4h |
| ; CHECK-NEXT: ret |
| entry: |
| %fneg.i = fneg <4 x half> %b |
| %0 = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %fneg.i, <4 x half> %c, <4 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <4 x half> %0 |
| } |
| |
| define <8 x half> @test_vfmsq_f16(<8 x half> %a, <8 x half> %b, <8 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmsq_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fmls v0.8h, v2.8h, v1.8h |
| ; CHECK-NEXT: ret |
| entry: |
| %fneg.i = fneg <8 x half> %b |
| %0 = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %fneg.i, <8 x half> %c, <8 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <8 x half> %0 |
| } |
| |
| define <4 x half> @test_vfma_lane_f16(<4 x half> %a, <4 x half> %b, <4 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfma_lane_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2 |
| ; CHECK-NEXT: fmla v0.4h, v1.4h, v2.h[3] |
| ; CHECK-NEXT: ret |
| entry: |
| %lane = shufflevector <4 x half> %c, <4 x half> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3> |
| %fmla2 = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %b, <4 x half> %lane, <4 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <4 x half> %fmla2 |
| } |
| |
| define <8 x half> @test_vfmaq_lane_f16(<8 x half> %a, <8 x half> %b, <4 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmaq_lane_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2 |
| ; CHECK-NEXT: fmla v0.8h, v1.8h, v2.h[3] |
| ; CHECK-NEXT: ret |
| entry: |
| %lane = shufflevector <4 x half> %c, <4 x half> poison, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> |
| %fmla2 = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %b, <8 x half> %lane, <8 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <8 x half> %fmla2 |
| } |
| |
| define <4 x half> @test_vfma_laneq_f16(<4 x half> %a, <4 x half> %b, <8 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfma_laneq_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fmla v0.4h, v1.4h, v2.h[7] |
| ; CHECK-NEXT: ret |
| entry: |
| %lane = shufflevector <8 x half> %c, <8 x half> poison, <4 x i32> <i32 7, i32 7, i32 7, i32 7> |
| %0 = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %lane, <4 x half> %b, <4 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <4 x half> %0 |
| } |
| |
| define <8 x half> @test_vfmaq_laneq_f16(<8 x half> %a, <8 x half> %b, <8 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmaq_laneq_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fmla v0.8h, v1.8h, v2.h[7] |
| ; CHECK-NEXT: ret |
| entry: |
| %lane = shufflevector <8 x half> %c, <8 x half> poison, <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7> |
| %0 = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %lane, <8 x half> %b, <8 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <8 x half> %0 |
| } |
| |
| define <4 x half> @test_vfma_n_f16(<4 x half> %a, <4 x half> %b, half %c) #0 { |
| ; CHECK-LABEL: test_vfma_n_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: // kill: def $h2 killed $h2 def $q2 |
| ; CHECK-NEXT: fmla v0.4h, v1.4h, v2.h[0] |
| ; CHECK-NEXT: ret |
| entry: |
| %vecinit = insertelement <4 x half> poison, half %c, i64 0 |
| %vecinit3 = shufflevector <4 x half> %vecinit, <4 x half> poison, <4 x i32> zeroinitializer |
| %0 = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %b, <4 x half> %vecinit3, <4 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <4 x half> %0 |
| } |
| |
| define <8 x half> @test_vfmaq_n_f16(<8 x half> %a, <8 x half> %b, half %c) #0 { |
| ; CHECK-LABEL: test_vfmaq_n_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: // kill: def $h2 killed $h2 def $q2 |
| ; CHECK-NEXT: fmla v0.8h, v1.8h, v2.h[0] |
| ; CHECK-NEXT: ret |
| entry: |
| %vecinit = insertelement <8 x half> poison, half %c, i64 0 |
| %vecinit7 = shufflevector <8 x half> %vecinit, <8 x half> poison, <8 x i32> zeroinitializer |
| %0 = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %b, <8 x half> %vecinit7, <8 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <8 x half> %0 |
| } |
| |
| define half @test_vfmah_lane_f16(half %a, half %b, <4 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmah_lane_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2 |
| ; CHECK-NEXT: fmla h0, h1, v2.h[3] |
| ; CHECK-NEXT: ret |
| entry: |
| %extract = extractelement <4 x half> %c, i64 3 |
| %0 = call half @llvm.experimental.constrained.fma.f16(half %b, half %extract, half %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret half %0 |
| } |
| |
| define half @test_vfmah_laneq_f16(half %a, half %b, <8 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmah_laneq_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fmla h0, h1, v2.h[7] |
| ; CHECK-NEXT: ret |
| entry: |
| %extract = extractelement <8 x half> %c, i64 7 |
| %0 = call half @llvm.experimental.constrained.fma.f16(half %b, half %extract, half %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret half %0 |
| } |
| |
| define <4 x half> @test_vfms_lane_f16(<4 x half> %a, <4 x half> %b, <4 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfms_lane_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2 |
| ; CHECK-NEXT: fmls v0.4h, v1.4h, v2.h[3] |
| ; CHECK-NEXT: ret |
| entry: |
| %fneg = fneg <4 x half> %b |
| %lane = shufflevector <4 x half> %c, <4 x half> poison, <4 x i32> <i32 3, i32 3, i32 3, i32 3> |
| %fmla2 = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %fneg, <4 x half> %lane, <4 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <4 x half> %fmla2 |
| } |
| |
| define <8 x half> @test_vfmsq_lane_f16(<8 x half> %a, <8 x half> %b, <4 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmsq_lane_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2 |
| ; CHECK-NEXT: fmls v0.8h, v1.8h, v2.h[3] |
| ; CHECK-NEXT: ret |
| entry: |
| %fneg = fneg <8 x half> %b |
| %lane = shufflevector <4 x half> %c, <4 x half> poison, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3> |
| %fmla2 = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %fneg, <8 x half> %lane, <8 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <8 x half> %fmla2 |
| } |
| |
| define <4 x half> @test_vfms_laneq_f16(<4 x half> %a, <4 x half> %b, <8 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfms_laneq_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fmls v0.4h, v1.4h, v2.h[7] |
| ; CHECK-NEXT: ret |
| entry: |
| %fneg = fneg <4 x half> %b |
| %lane = shufflevector <8 x half> %c, <8 x half> poison, <4 x i32> <i32 7, i32 7, i32 7, i32 7> |
| %0 = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %lane, <4 x half> %fneg, <4 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <4 x half> %0 |
| } |
| |
| define <8 x half> @test_vfmsq_laneq_f16(<8 x half> %a, <8 x half> %b, <8 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmsq_laneq_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fmls v0.8h, v1.8h, v2.h[7] |
| ; CHECK-NEXT: ret |
| entry: |
| %fneg = fneg <8 x half> %b |
| %lane = shufflevector <8 x half> %c, <8 x half> poison, <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7> |
| %0 = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %lane, <8 x half> %fneg, <8 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <8 x half> %0 |
| } |
| |
| define <4 x half> @test_vfms_n_f16(<4 x half> %a, <4 x half> %b, half %c) #0 { |
| ; CHECK-LABEL: test_vfms_n_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: // kill: def $h2 killed $h2 def $q2 |
| ; CHECK-NEXT: fmls v0.4h, v1.4h, v2.h[0] |
| ; CHECK-NEXT: ret |
| entry: |
| %fneg = fneg <4 x half> %b |
| %vecinit = insertelement <4 x half> poison, half %c, i64 0 |
| %vecinit3 = shufflevector <4 x half> %vecinit, <4 x half> poison, <4 x i32> zeroinitializer |
| %0 = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %fneg, <4 x half> %vecinit3, <4 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <4 x half> %0 |
| } |
| |
| define <8 x half> @test_vfmsq_n_f16(<8 x half> %a, <8 x half> %b, half %c) #0 { |
| ; CHECK-LABEL: test_vfmsq_n_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: // kill: def $h2 killed $h2 def $q2 |
| ; CHECK-NEXT: fmls v0.8h, v1.8h, v2.h[0] |
| ; CHECK-NEXT: ret |
| entry: |
| %fneg = fneg <8 x half> %b |
| %vecinit = insertelement <8 x half> poison, half %c, i64 0 |
| %vecinit7 = shufflevector <8 x half> %vecinit, <8 x half> poison, <8 x i32> zeroinitializer |
| %0 = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %fneg, <8 x half> %vecinit7, <8 x half> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret <8 x half> %0 |
| } |
| |
| define half @test_vfmsh_lane_f16(half %a, half %b, <4 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmsh_lane_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fcvt s1, h1 |
| ; CHECK-NEXT: // kill: def $d2 killed $d2 def $q2 |
| ; CHECK-NEXT: fneg s1, s1 |
| ; CHECK-NEXT: fcvt h1, s1 |
| ; CHECK-NEXT: fmla h0, h1, v2.h[3] |
| ; CHECK-NEXT: ret |
| entry: |
| %conv = call float @llvm.experimental.constrained.fpext.f32.f16(half %b, metadata !"fpexcept.strict") #1 |
| %fneg = fneg float %conv |
| %0 = call half @llvm.experimental.constrained.fptrunc.f16.f32(float %fneg, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| %extract = extractelement <4 x half> %c, i64 3 |
| %1 = call half @llvm.experimental.constrained.fma.f16(half %0, half %extract, half %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret half %1 |
| } |
| |
| define half @test_vfmsh_laneq_f16(half %a, half %b, <8 x half> %c) #0 { |
| ; CHECK-LABEL: test_vfmsh_laneq_f16: |
| ; CHECK: // %bb.0: // %entry |
| ; CHECK-NEXT: fcvt s1, h1 |
| ; CHECK-NEXT: fneg s1, s1 |
| ; CHECK-NEXT: fcvt h1, s1 |
| ; CHECK-NEXT: fmla h0, h1, v2.h[7] |
| ; CHECK-NEXT: ret |
| entry: |
| %conv = call float @llvm.experimental.constrained.fpext.f32.f16(half %b, metadata !"fpexcept.strict") #1 |
| %fneg = fneg float %conv |
| %0 = call half @llvm.experimental.constrained.fptrunc.f16.f32(float %fneg, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| %extract = extractelement <8 x half> %c, i64 7 |
| %1 = call half @llvm.experimental.constrained.fma.f16(half %0, half %extract, half %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #1 |
| ret half %1 |
| } |
| |
| attributes #0 = { noinline nounwind strictfp "target-features"="+crc,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+v8.1a,+v8.2a,+v8a" } |
| attributes #1 = { strictfp } |