diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index b1794b78a3e2a..d68dc3c8d991f 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -636,6 +636,11 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) .libcallFor({{s32, s32}, {s64, s32}}) .libcallFor(ST.is64Bit(), {s128, s32}); + getActionDefinitionsBuilder(G_FCANONICALIZE) + .legalFor(ST.hasStdExtF(), {s32}) + .legalFor(ST.hasStdExtD(), {s64}) + .legalFor(ST.hasStdExtZfh(), {s16}); + getActionDefinitionsBuilder(G_VASTART).customFor({p0}); // va_list must be a pointer, but most sized types are pretty easy to handle diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/fp-fcanonicalize.ll b/llvm/test/CodeGen/RISCV/GlobalISel/fp-fcanonicalize.ll new file mode 100644 index 0000000000000..d983082083ecb --- /dev/null +++ b/llvm/test/CodeGen/RISCV/GlobalISel/fp-fcanonicalize.ll @@ -0,0 +1,66 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; FIXME: @llvm.canonicalize doesn't support soft-float abi yet. +; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-FP16-RV64 +; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-FP16-RV32 + +declare half @llvm.fcanonicalize.f16(half) +declare float @llvm.fcanonicalize.f32(float) +declare double @llvm.fcanonicalize.f64(double) + +define half @fcanonicalize_f16(half %x) { +; CHECK-LABEL: fcanonicalize_f16: +; CHECK: # %bb.0: +; CHECK-NEXT: fmin.h fa0, fa0, fa0 +; CHECK-NEXT: ret + %z = call half @llvm.canonicalize.f16(half %x) + ret half %z +} + +define half @fcanonicalize_f16_nnan(half %x) { +; CHECK-LABEL: fcanonicalize_f16_nnan: +; CHECK: # %bb.0: +; CHECK-NEXT: fmin.h fa0, fa0, fa0 +; CHECK-NEXT: ret + %z = call nnan half @llvm.canonicalize.f16(half %x) + ret half %z +} + +define float @fcanonicalize_f32(float %x) { +; CHECK-LABEL: fcanonicalize_f32: +; CHECK: # %bb.0: +; CHECK-NEXT: fmin.s fa0, fa0, fa0 +; CHECK-NEXT: ret + %z = call float @llvm.canonicalize.f32(float %x) + ret float %z +} + +define float @fcanonicalize_f32_nnan(float %x) { +; CHECK-LABEL: fcanonicalize_f32_nnan: +; CHECK: # %bb.0: +; CHECK-NEXT: fmin.s fa0, fa0, fa0 +; CHECK-NEXT: ret + %z = call nnan float @llvm.canonicalize.f32(float %x) + ret float %z +} + +define double @fcanonicalize_f64(double %x) { +; CHECK-LABEL: fcanonicalize_f64: +; CHECK: # %bb.0: +; CHECK-NEXT: fmin.d fa0, fa0, fa0 +; CHECK-NEXT: ret + %z = call double @llvm.canonicalize.f64(double %x) + ret double %z +} + +define double @fcanonicalize_f64_nnan(double %x) { +; CHECK-LABEL: fcanonicalize_f64_nnan: +; CHECK: # %bb.0: +; CHECK-NEXT: fmin.d fa0, fa0, fa0 +; CHECK-NEXT: ret + %z = call nnan double @llvm.canonicalize.f64(double %x) + ret double %z +} + +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CHECK-FP16-RV32: {{.*}} +; CHECK-FP16-RV64: {{.*}} diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir index da7546e12e58b..5f9b647112a50 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir @@ -587,8 +587,8 @@ # DEBUG-NEXT: .. the first uncovered type index: 2, OK # DEBUG-NEXT: .. the first uncovered imm index: 0, OK # DEBUG-NEXT: G_FCANONICALIZE (opcode {{[0-9]+}}): 1 type index, 0 imm indices -# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined -# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. the first uncovered type index: 1, OK +# DEBUG-NEXT: .. the first uncovered imm index: 0, OK # DEBUG-NEXT: G_FMINNUM (opcode {{[0-9]+}}): 1 type index # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. the first uncovered type index: 1, OK