diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -11550,6 +11550,8 @@ return false; switch (VT.getSimpleVT().SimpleTy) { + case MVT::f16: + return Subtarget->hasFullFP16(); case MVT::f32: case MVT::f64: return true; diff --git a/llvm/test/CodeGen/AArch64/f16-instructions.ll b/llvm/test/CodeGen/AArch64/f16-instructions.ll --- a/llvm/test/CodeGen/AArch64/f16-instructions.ll +++ b/llvm/test/CodeGen/AArch64/f16-instructions.ll @@ -62,6 +62,26 @@ ret half %r } +; CHECK-CVT-LABEL: test_fmadd: +; CHECK-CVT-NEXT: fcvt s1, h1 +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fmul s0, s0, s1 +; CHECK-CVT-NEXT: fcvt h0, s0 +; CHECK-CVT-NEXT: fcvt s0, h0 +; CHECK-CVT-NEXT: fcvt s1, h2 +; CHECK-CVT-NEXT: fadd s0, s0, s1 +; CHECK-CVT-NEXT: fcvt h0, s0 +; CHECK-CVT-NEXT: ret + +; CHECK-FP16-LABEL: test_fmadd: +; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2 +; CHECK-FP16-NEXT: ret + +define half @test_fmadd(half %a, half %b, half %c) #0 { + %mul = fmul fast half %a, %b + %r = fadd fast half %mul, %c + ret half %r +} ; CHECK-CVT-LABEL: test_fdiv: ; CHECK-CVT-NEXT: fcvt s1, h1 ; CHECK-CVT-NEXT: fcvt s0, h0 @@ -1305,8 +1325,7 @@ ; CHECK-CVT-NEXT: ret ; CHECK-FP16-LABEL: test_fmuladd: -; CHECK-FP16-NEXT: fmul h0, h0, h1 -; CHECK-FP16-NEXT: fadd h0, h0, h2 +; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2 ; CHECK-FP16-NEXT: ret define half @test_fmuladd(half %a, half %b, half %c) #0 { diff --git a/llvm/test/CodeGen/AArch64/sve-fp-combine.ll b/llvm/test/CodeGen/AArch64/sve-fp-combine.ll --- a/llvm/test/CodeGen/AArch64/sve-fp-combine.ll +++ b/llvm/test/CodeGen/AArch64/sve-fp-combine.ll @@ -1,5 +1,16 @@ ; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve < %s | FileCheck %s +define @fmla_h_sel( %pred, %acc, + %m1, %m2) { +; CHECK-LABEL: fmla_h_sel: +; CHECK: fmla z0.h, p0/m, z1.h, z2.h +; CHECK: ret + %mul = fmul fast %m1, %m2 + %add = fadd fast %acc, %mul + %res = select %pred, %add, %acc + ret %res +} + define @fmla_s_sel( %pred, %acc, %m1, %m2) { ; CHECK-LABEL: fmla_s_sel: @@ -33,6 +44,17 @@ ret %res } +define @fmls_h_sel( %pred, %acc, + %m1, %m2) { +; CHECK-LABEL: fmls_h_sel: +; CHECK: fmls z0.h, p0/m, z1.h, z2.h +; CHECK: ret + %mul = fmul fast %m1, %m2 + %sub = fsub fast %acc, %mul + %res = select %pred, %sub, %acc + ret %res +} + define @fmls_s_sel( %pred, %acc, %m1, %m2) { ; CHECK-LABEL: fmls_s_sel: @@ -66,6 +88,16 @@ ret %res } +define @fmad_h( %m1, %m2, %acc) { +; CHECK-LABEL: fmad_h: +; CHECK: ptrue [[PG:p[0-9]+]].h +; CHECK-NEXT: fmad z0.h, [[PG]]/m, z1.h, z2.h +; CHECK-NEXT: ret + %mul = fmul fast %m1, %m2 + %res = fadd fast %acc, %mul + ret %res +} + define @fmad_s( %m1, %m2, %acc) { ; CHECK-LABEL: fmad_s: ; CHECK: ptrue [[PG:p[0-9]+]].s @@ -126,6 +158,16 @@ ret %res } +define @fmls_h( %acc, %m1, %m2) { +; CHECK-LABEL: fmls_h: +; CHECK: ptrue [[PG:p[0-9]+]].h +; CHECK-NEXT: fmls z0.h, [[PG]]/m, z1.h, z2.h +; CHECK-NEXT: ret + %mul = fmul fast %m1, %m2 + %res = fsub fast %acc, %mul + ret %res +} + define @fmls_s( %acc, %m1, %m2) { ; CHECK-LABEL: fmls_s: ; CHECK: ptrue [[PG:p[0-9]+]].s @@ -237,6 +279,23 @@ ret %res } +define @fnmla_h( %acc, %m1, %m2) { +; CHECK-LABEL: fnmla_h: +; CHECK: ptrue [[PG:p[0-9]+]].h +; CHECK-NEXT: fnmla z0.h, [[PG]]/m, z1.h, z2.h +; CHECK-NEXT: ret + %neg_m1 = fsub fast + shufflevector ( + insertelement ( undef, half -0.000000e+00, i32 0), + undef, + zeroinitializer), + %m1 + + %mul = fmul fast %neg_m1, %m2 + %res = fsub fast %mul, %acc + ret %res +} + define @fnmla_s( %acc, %m1, %m2) { ; CHECK-LABEL: fnmla_s: ; CHECK: ptrue [[PG:p[0-9]+]].s @@ -288,6 +347,22 @@ ret %res } +define @fnmla_h_reversed( %acc, %m1, %m2) { +; CHECK-LABEL: fnmla_h_reversed: +; CHECK: ptrue [[PG:p[0-9]+]].h +; CHECK-NEXT: fnmla z0.h, [[PG]]/m, z1.h, z2.h +; CHECK-NEXT: ret + %mul = fmul fast %m1, %m2 + %add = fadd fast %mul, %acc + %res = fsub fast + shufflevector ( + insertelement ( undef, half -0.000000e+00, i32 0), + undef, + zeroinitializer), + %add + ret %res +} + define @fnmla_s_reversed( %acc, %m1, %m2) { ; CHECK-LABEL: fnmla_s_reversed: ; CHECK: ptrue [[PG:p[0-9]+]].s @@ -336,6 +411,16 @@ ret %res } +define @fnmls_h( %acc, %m1, %m2) { +; CHECK-LABEL: fnmls_h: +; CHECK: ptrue [[PG:p[0-9]+]].h +; CHECK-NEXT: fnmls z0.h, [[PG]]/m, z1.h, z2.h +; CHECK-NEXT: ret + %mul = fmul fast %m1, %m2 + %res = fsub fast %mul, %acc + ret %res +} + define @fnmls_s( %acc, %m1, %m2) { ; CHECK-LABEL: fnmls_s: ; CHECK: ptrue [[PG:p[0-9]+]].s