diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 456ca9894e6a7..f02bf7a00797b 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -582,12 +582,19 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) .libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}}); // FIXME: We can do custom inline expansion like SelectionDAG. - // FIXME: Legal with Zfa. getActionDefinitionsBuilder({G_FCEIL, G_FFLOOR, G_FRINT, G_FNEARBYINT, G_INTRINSIC_TRUNC, G_INTRINSIC_ROUND, G_INTRINSIC_ROUNDEVEN}) + .legalFor(ST.hasStdExtZfa(), {s32}) + .legalFor(ST.hasStdExtZfa() && ST.hasStdExtD(), {s64}) + .legalFor(ST.hasStdExtZfa() && ST.hasStdExtZfh(), {s16}) .libcallFor({s32, s64}); + getActionDefinitionsBuilder({G_FMAXIMUM, G_FMINIMUM}) + .legalFor(ST.hasStdExtZfa(), {s32}) + .legalFor(ST.hasStdExtZfa() && ST.hasStdExtD(), {s64}) + .legalFor(ST.hasStdExtZfa() && ST.hasStdExtZfh(), {s16}); + getActionDefinitionsBuilder({G_FCOS, G_FSIN, G_FTAN, G_FPOW, G_FLOG, G_FLOG2, G_FLOG10, G_FEXP, G_FEXP2, G_FEXP10, G_FACOS, G_FASIN, G_FATAN, G_FATAN2, G_FCOSH, G_FSINH, diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-zfa.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-zfa.ll new file mode 100644 index 0000000000000..385156b3b99d4 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-zfa.ll @@ -0,0 +1,88 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 + +; RUN: llc -mtriple=riscv32 -mattr=+zfa,d -global-isel < %s \ +; RUN: | FileCheck %s +; RUN: llc -mtriple=riscv64 -mattr=+zfa,d -global-isel < %s \ +; RUN: | FileCheck %s + + +define double @fceil(double %a) { +; CHECK-LABEL: fceil: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.d fa0, fa0, rup +; CHECK-NEXT: ret + %b = call double @llvm.ceil.f64(double %a) + ret double %b +} + +define double @ffloor(double %a) { +; CHECK-LABEL: ffloor: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.d fa0, fa0, rdn +; CHECK-NEXT: ret + %b = call double @llvm.floor.f64(double %a) + ret double %b +} + +define double @frint(double %a) { +; CHECK-LABEL: frint: +; CHECK: # %bb.0: +; CHECK-NEXT: froundnx.d fa0, fa0 +; CHECK-NEXT: ret + %b = call double @llvm.rint.f64(double %a) + ret double %b +} + +define double @fnearbyint(double %a) { +; CHECK-LABEL: fnearbyint: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.d fa0, fa0 +; CHECK-NEXT: ret + %b = call double @llvm.nearbyint.f64(double %a) + ret double %b +} + +define double @fround(double %a) { +; CHECK-LABEL: fround: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.d fa0, fa0, rmm +; CHECK-NEXT: ret + %b = call double @llvm.round.f64(double %a) + ret double %b +} + +define double @froundeven(double %a) { +; CHECK-LABEL: froundeven: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.d fa0, fa0, rne +; CHECK-NEXT: ret + %b = call double @llvm.roundeven.f64(double %a) + ret double %b +} + +define double @ftrunc(double %a) { +; CHECK-LABEL: ftrunc: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.d fa0, fa0, rtz +; CHECK-NEXT: ret + %b = call double @llvm.trunc.f64(double %a) + ret double %b +} + +define double @fmaximum(double %a, double %b) { +; CHECK-LABEL: fmaximum: +; CHECK: # %bb.0: +; CHECK-NEXT: fmaxm.d fa0, fa0, fa1 +; CHECK-NEXT: ret + %c = call double @llvm.maximum.f64(double %a, double %b) + ret double %c +} + +define double @fminimum(double %a, double %b) { +; CHECK-LABEL: fminimum: +; CHECK: # %bb.0: +; CHECK-NEXT: fminm.d fa0, fa0, fa1 +; CHECK-NEXT: ret + %c = call double @llvm.minimum.f64(double %a, double %b) + ret double %c +} diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-zfa.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-zfa.ll new file mode 100644 index 0000000000000..b95200bf90904 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-zfa.ll @@ -0,0 +1,88 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 + +; RUN: llc -mtriple=riscv32 -mattr=+zfa -global-isel < %s \ +; RUN: | FileCheck %s +; RUN: llc -mtriple=riscv64 -mattr=+zfa -global-isel < %s \ +; RUN: | FileCheck %s + + +define float @fceil(float %a) { +; CHECK-LABEL: fceil: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.s fa0, fa0, rup +; CHECK-NEXT: ret + %b = call float @llvm.ceil.f32(float %a) + ret float %b +} + +define float @ffloor(float %a) { +; CHECK-LABEL: ffloor: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.s fa0, fa0, rdn +; CHECK-NEXT: ret + %b = call float @llvm.floor.f32(float %a) + ret float %b +} + +define float @frint(float %a) { +; CHECK-LABEL: frint: +; CHECK: # %bb.0: +; CHECK-NEXT: froundnx.s fa0, fa0 +; CHECK-NEXT: ret + %b = call float @llvm.rint.f32(float %a) + ret float %b +} + +define float @fnearbyint(float %a) { +; CHECK-LABEL: fnearbyint: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.s fa0, fa0 +; CHECK-NEXT: ret + %b = call float @llvm.nearbyint.f32(float %a) + ret float %b +} + +define float @fround(float %a) { +; CHECK-LABEL: fround: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.s fa0, fa0, rmm +; CHECK-NEXT: ret + %b = call float @llvm.round.f32(float %a) + ret float %b +} + +define float @froundeven(float %a) { +; CHECK-LABEL: froundeven: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.s fa0, fa0, rne +; CHECK-NEXT: ret + %b = call float @llvm.roundeven.f32(float %a) + ret float %b +} + +define float @ftrunc(float %a) { +; CHECK-LABEL: ftrunc: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.s fa0, fa0, rtz +; CHECK-NEXT: ret + %b = call float @llvm.trunc.f32(float %a) + ret float %b +} + +define float @fmaximum(float %a, float %b) { +; CHECK-LABEL: fmaximum: +; CHECK: # %bb.0: +; CHECK-NEXT: fmaxm.s fa0, fa0, fa1 +; CHECK-NEXT: ret + %c = call float @llvm.maximum.f32(float %a, float %b) + ret float %c +} + +define float @fminimum(float %a, float %b) { +; CHECK-LABEL: fminimum: +; CHECK: # %bb.0: +; CHECK-NEXT: fminm.s fa0, fa0, fa1 +; CHECK-NEXT: ret + %c = call float @llvm.minimum.f32(float %a, float %b) + ret float %c +} diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/half-zfa.ll b/llvm/test/CodeGen/RISCV/GlobalISel/half-zfa.ll new file mode 100644 index 0000000000000..2ccb3c63e3f21 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/half-zfa.ll @@ -0,0 +1,88 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 + +; RUN: llc -mtriple=riscv32 -mattr=+zfa,+zfh -global-isel < %s \ +; RUN: | FileCheck %s +; RUN: llc -mtriple=riscv64 -mattr=+zfa,+zfh -global-isel < %s \ +; RUN: | FileCheck %s + + +define half @fceil(half %a) { +; CHECK-LABEL: fceil: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.h fa0, fa0, rup +; CHECK-NEXT: ret + %b = call half @llvm.ceil.f16(half %a) + ret half %b +} + +define half @ffloor(half %a) { +; CHECK-LABEL: ffloor: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.h fa0, fa0, rdn +; CHECK-NEXT: ret + %b = call half @llvm.floor.f16(half %a) + ret half %b +} + +define half @frint(half %a) { +; CHECK-LABEL: frint: +; CHECK: # %bb.0: +; CHECK-NEXT: froundnx.h fa0, fa0 +; CHECK-NEXT: ret + %b = call half @llvm.rint.f16(half %a) + ret half %b +} + +define half @fnearbyint(half %a) { +; CHECK-LABEL: fnearbyint: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.h fa0, fa0 +; CHECK-NEXT: ret + %b = call half @llvm.nearbyint.f16(half %a) + ret half %b +} + +define half @fround(half %a) { +; CHECK-LABEL: fround: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.h fa0, fa0, rmm +; CHECK-NEXT: ret + %b = call half @llvm.round.f16(half %a) + ret half %b +} + +define half @froundeven(half %a) { +; CHECK-LABEL: froundeven: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.h fa0, fa0, rne +; CHECK-NEXT: ret + %b = call half @llvm.roundeven.f16(half %a) + ret half %b +} + +define half @ftrunc(half %a) { +; CHECK-LABEL: ftrunc: +; CHECK: # %bb.0: +; CHECK-NEXT: fround.h fa0, fa0, rtz +; CHECK-NEXT: ret + %b = call half @llvm.trunc.f16(half %a) + ret half %b +} + +define half @fmaximum(half %a, half %b) { +; CHECK-LABEL: fmaximum: +; CHECK: # %bb.0: +; CHECK-NEXT: fmaxm.h fa0, fa0, fa1 +; CHECK-NEXT: ret + %c = call half @llvm.maximum.f16(half %a, half %b) + ret half %c +} + +define half @fminimum(half %a, half %b) { +; CHECK-LABEL: fminimum: +; CHECK: # %bb.0: +; CHECK-NEXT: fminm.h fa0, fa0, fa1 +; CHECK-NEXT: ret + %c = call half @llvm.minimum.f16(half %a, half %b) + ret half %c +} diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir index a05d0f605df1d..fb28a260c8271 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir @@ -579,6 +579,7 @@ # DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined # DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined # DEBUG-NEXT: G_FMINIMUM (opcode {{[0-9]+}}): 1 type index +# DEBUG-NEXT: .. opcode 212 is aliased to 213 # DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined # DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined # DEBUG-NEXT: G_FMAXIMUM (opcode {{[0-9]+}}): 1 type index