forked from OSchip/llvm-project
[RISCV] Add support for the various RISC-V FMA instruction variants
Adds support for the various RISC-V FMA instructions (fmadd, fmsub, fnmsub, fnmadd). The criteria for choosing whether a fused add or subtract is used, as well as whether the product is negated or not, is whether some of the arguments to the llvm.fma.* intrinsic are negated or not. In the tests, extraneous fadd instructions were added to avoid the negation being performed using a xor trick, which prevented the proper FMA forms from being selected and thus tested. The FMA instruction patterns might seem incorrect (e.g., fnmadd: -rs1 * rs2 - rs3), but they should be correct. The misleading names were inherited from MIPS, where the negation happens after computing the sum. The llvm.fmuladd.* intrinsics still do not generate RISC-V FMA instructions, as that depends on TargetLowering::isFMAFasterthanFMulAndFAdd. Some comments in the test files about what type of instructions are there tested were updated, to better reflect the current content of those test files. Differential Revision: https://reviews.llvm.org/D54205 Patch by Luís Marques. llvm-svn: 349023
This commit is contained in:
parent
dfe861087d
commit
919f5fb8ca
|
@ -111,10 +111,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|||
ISD::SETUGT, ISD::SETUGE, ISD::SETULT, ISD::SETULE, ISD::SETUNE,
|
||||
ISD::SETGT, ISD::SETGE, ISD::SETNE};
|
||||
|
||||
// TODO: add proper support for the various FMA variants
|
||||
// (FMADD.S, FMSUB.S, FNMSUB.S, FNMADD.S).
|
||||
ISD::NodeType FPOpToExtend[] = {
|
||||
ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOW, ISD::FMA, ISD::FREM};
|
||||
ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOW, ISD::FREM};
|
||||
|
||||
if (Subtarget.hasStdExtF()) {
|
||||
setOperationAction(ISD::FMINNUM, MVT::f32, Legal);
|
||||
|
|
|
@ -230,6 +230,22 @@ def : Pat<(fabs FPR64:$rs1), (FSGNJX_D $rs1, $rs1)>;
|
|||
def : PatFpr64Fpr64<fcopysign, FSGNJ_D>;
|
||||
def : Pat<(fcopysign FPR64:$rs1, (fneg FPR64:$rs2)), (FSGNJN_D $rs1, $rs2)>;
|
||||
|
||||
// fmadd: rs1 * rs2 + rs3
|
||||
def : Pat<(fma FPR64:$rs1, FPR64:$rs2, FPR64:$rs3),
|
||||
(FMADD_D $rs1, $rs2, $rs3, 0b111)>;
|
||||
|
||||
// fmsub: rs1 * rs2 - rs3
|
||||
def : Pat<(fma FPR64:$rs1, FPR64:$rs2, (fneg FPR64:$rs3)),
|
||||
(FMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>;
|
||||
|
||||
// fnmsub: -rs1 * rs2 + rs3
|
||||
def : Pat<(fma (fneg FPR64:$rs1), FPR64:$rs2, FPR64:$rs3),
|
||||
(FNMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>;
|
||||
|
||||
// fnmadd: -rs1 * rs2 - rs3
|
||||
def : Pat<(fma (fneg FPR64:$rs1), FPR64:$rs2, (fneg FPR64:$rs3)),
|
||||
(FNMADD_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>;
|
||||
|
||||
// The RISC-V 2.2 user-level ISA spec defines fmin and fmax as returning the
|
||||
// canonical NaN when giving a signaling NaN. This doesn't match the LLVM
|
||||
// behaviour (see https://bugs.llvm.org/show_bug.cgi?id=27363). However, the
|
||||
|
|
|
@ -270,6 +270,22 @@ def : Pat<(fabs FPR32:$rs1), (FSGNJX_S $rs1, $rs1)>;
|
|||
def : PatFpr32Fpr32<fcopysign, FSGNJ_S>;
|
||||
def : Pat<(fcopysign FPR32:$rs1, (fneg FPR32:$rs2)), (FSGNJN_S $rs1, $rs2)>;
|
||||
|
||||
// fmadd: rs1 * rs2 + rs3
|
||||
def : Pat<(fma FPR32:$rs1, FPR32:$rs2, FPR32:$rs3),
|
||||
(FMADD_S $rs1, $rs2, $rs3, 0b111)>;
|
||||
|
||||
// fmsub: rs1 * rs2 - rs3
|
||||
def : Pat<(fma FPR32:$rs1, FPR32:$rs2, (fneg FPR32:$rs3)),
|
||||
(FMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>;
|
||||
|
||||
// fnmsub: -rs1 * rs2 + rs3
|
||||
def : Pat<(fma (fneg FPR32:$rs1), FPR32:$rs2, FPR32:$rs3),
|
||||
(FNMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>;
|
||||
|
||||
// fnmadd: -rs1 * rs2 - rs3
|
||||
def : Pat<(fma (fneg FPR32:$rs1), FPR32:$rs2, (fneg FPR32:$rs3)),
|
||||
(FNMADD_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>;
|
||||
|
||||
// The RISC-V 2.2 user-level ISA spec defines fmin and fmax as returning the
|
||||
// canonical NaN when given a signaling NaN. This doesn't match the LLVM
|
||||
// behaviour (see https://bugs.llvm.org/show_bug.cgi?id=27363). However, the
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64I
|
||||
|
||||
; These tests are each targeted at a particular RISC-V ALU instruction. Other
|
||||
; files in this folder exercise LLVM IR instructions that don't directly match a
|
||||
; RISC-V instruction
|
||||
; These tests are each targeted at a particular RISC-V ALU instruction. Most
|
||||
; other files in this folder exercise LLVM IR instructions that don't directly
|
||||
; match a RISC-V instruction.
|
||||
|
||||
; Register-immediate instructions.
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck -check-prefix=RV32IFD %s
|
||||
|
||||
; These tests are each targeted at a particular RISC-V FPU instruction. Most
|
||||
; other files in this folder exercise LLVM IR instructions that don't directly
|
||||
; match a RISC-V instruction.
|
||||
|
||||
define double @fadd_d(double %a, double %b) nounwind {
|
||||
; RV32IFD-LABEL: fadd_d:
|
||||
; RV32IFD: # %bb.0:
|
||||
|
@ -277,3 +281,118 @@ define i32 @fle_d(double %a, double %b) nounwind {
|
|||
%2 = zext i1 %1 to i32
|
||||
ret i32 %2
|
||||
}
|
||||
|
||||
declare double @llvm.fma.f64(double, double, double)
|
||||
|
||||
define double @fmadd_d(double %a, double %b, double %c) nounwind {
|
||||
; RV32IFD-LABEL: fmadd_d:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
; RV32IFD-NEXT: sw a4, 8(sp)
|
||||
; RV32IFD-NEXT: sw a5, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a2, 8(sp)
|
||||
; RV32IFD-NEXT: sw a3, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft1, 8(sp)
|
||||
; RV32IFD-NEXT: sw a0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a1, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft2, 8(sp)
|
||||
; RV32IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0
|
||||
; RV32IFD-NEXT: fsd ft0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a1, 12(sp)
|
||||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.fma.f64(double %a, double %b, double %c)
|
||||
ret double %1
|
||||
}
|
||||
|
||||
define double @fmsub_d(double %a, double %b, double %c) nounwind {
|
||||
; RV32IFD-LABEL: fmsub_d:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
; RV32IFD-NEXT: sw a2, 8(sp)
|
||||
; RV32IFD-NEXT: sw a3, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a1, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft1, 8(sp)
|
||||
; RV32IFD-NEXT: sw a4, 8(sp)
|
||||
; RV32IFD-NEXT: sw a5, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft2, 8(sp)
|
||||
; RV32IFD-NEXT: lui a0, %hi(.LCPI15_0)
|
||||
; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI15_0)
|
||||
; RV32IFD-NEXT: fld ft3, 0(a0)
|
||||
; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
|
||||
; RV32IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2
|
||||
; RV32IFD-NEXT: fsd ft0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a1, 12(sp)
|
||||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%c_ = fadd double 0.0, %c ; avoid negation using xor
|
||||
%negc = fsub double -0.0, %c_
|
||||
%1 = call double @llvm.fma.f64(double %a, double %b, double %negc)
|
||||
ret double %1
|
||||
}
|
||||
|
||||
define double @fnmadd_d(double %a, double %b, double %c) nounwind {
|
||||
; RV32IFD-LABEL: fnmadd_d:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
; RV32IFD-NEXT: sw a2, 8(sp)
|
||||
; RV32IFD-NEXT: sw a3, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a1, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft1, 8(sp)
|
||||
; RV32IFD-NEXT: sw a4, 8(sp)
|
||||
; RV32IFD-NEXT: sw a5, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft2, 8(sp)
|
||||
; RV32IFD-NEXT: lui a0, %hi(.LCPI16_0)
|
||||
; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI16_0)
|
||||
; RV32IFD-NEXT: fld ft3, 0(a0)
|
||||
; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
|
||||
; RV32IFD-NEXT: fadd.d ft1, ft1, ft3
|
||||
; RV32IFD-NEXT: fnmadd.d ft0, ft1, ft0, ft2
|
||||
; RV32IFD-NEXT: fsd ft0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a1, 12(sp)
|
||||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%a_ = fadd double 0.0, %a
|
||||
%c_ = fadd double 0.0, %c
|
||||
%nega = fsub double -0.0, %a_
|
||||
%negc = fsub double -0.0, %c_
|
||||
%1 = call double @llvm.fma.f64(double %nega, double %b, double %negc)
|
||||
ret double %1
|
||||
}
|
||||
|
||||
define double @fnmsub_d(double %a, double %b, double %c) nounwind {
|
||||
; RV32IFD-LABEL: fnmsub_d:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
; RV32IFD-NEXT: sw a4, 8(sp)
|
||||
; RV32IFD-NEXT: sw a5, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a2, 8(sp)
|
||||
; RV32IFD-NEXT: sw a3, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft1, 8(sp)
|
||||
; RV32IFD-NEXT: sw a0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a1, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft2, 8(sp)
|
||||
; RV32IFD-NEXT: lui a0, %hi(.LCPI17_0)
|
||||
; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI17_0)
|
||||
; RV32IFD-NEXT: fld ft3, 0(a0)
|
||||
; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
|
||||
; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0
|
||||
; RV32IFD-NEXT: fsd ft0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a1, 12(sp)
|
||||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%a_ = fadd double 0.0, %a
|
||||
%nega = fsub double -0.0, %a_
|
||||
%1 = call double @llvm.fma.f64(double %nega, double %b, double %c)
|
||||
ret double %1
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
declare double @llvm.sqrt.f64(double)
|
||||
|
||||
define double @sqrt_f64(double %a) {
|
||||
define double @sqrt_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: sqrt_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -18,12 +18,12 @@ define double @sqrt_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.sqrt.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.powi.f64(double, i32)
|
||||
|
||||
define double @powi_f64(double %a, i32 %b) {
|
||||
define double @powi_f64(double %a, i32 %b) nounwind {
|
||||
; RV32IFD-LABEL: powi_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -33,12 +33,12 @@ define double @powi_f64(double %a, i32 %b) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.powi.f64(double %a, i32 %b)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.sin.f64(double)
|
||||
|
||||
define double @sin_f64(double %a) {
|
||||
define double @sin_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: sin_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -48,12 +48,12 @@ define double @sin_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.sin.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.cos.f64(double)
|
||||
|
||||
define double @cos_f64(double %a) {
|
||||
define double @cos_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: cos_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -63,11 +63,11 @@ define double @cos_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.cos.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
; The sin+cos combination results in an FSINCOS SelectionDAG node.
|
||||
define double @sincos_f64(double %a) {
|
||||
define double @sincos_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: sincos_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -32
|
||||
|
@ -104,12 +104,12 @@ define double @sincos_f64(double %a) {
|
|||
%1 = call double @llvm.sin.f64(double %a)
|
||||
%2 = call double @llvm.cos.f64(double %a)
|
||||
%3 = fadd double %1, %2
|
||||
ret double %3
|
||||
ret double %3
|
||||
}
|
||||
|
||||
declare double @llvm.pow.f64(double, double)
|
||||
|
||||
define double @pow_f64(double %a, double %b) {
|
||||
define double @pow_f64(double %a, double %b) nounwind {
|
||||
; RV32IFD-LABEL: pow_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -119,12 +119,12 @@ define double @pow_f64(double %a, double %b) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.pow.f64(double %a, double %b)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.exp.f64(double)
|
||||
|
||||
define double @exp_f64(double %a) {
|
||||
define double @exp_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: exp_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -134,12 +134,12 @@ define double @exp_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.exp.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.exp2.f64(double)
|
||||
|
||||
define double @exp2_f64(double %a) {
|
||||
define double @exp2_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: exp2_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -149,12 +149,12 @@ define double @exp2_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.exp2.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.log.f64(double)
|
||||
|
||||
define double @log_f64(double %a) {
|
||||
define double @log_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: log_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -164,12 +164,12 @@ define double @log_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.log.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.log10.f64(double)
|
||||
|
||||
define double @log10_f64(double %a) {
|
||||
define double @log10_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: log10_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -179,12 +179,12 @@ define double @log10_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.log10.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.log2.f64(double)
|
||||
|
||||
define double @log2_f64(double %a) {
|
||||
define double @log2_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: log2_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -194,28 +194,64 @@ define double @log2_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.log2.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.fma.f64(double, double, double)
|
||||
|
||||
; TODO: Select RISC-V FMA instruction.
|
||||
define double @fma_f64(double %a, double %b, double %c) {
|
||||
define double @fma_f64(double %a, double %b, double %c) nounwind {
|
||||
; RV32IFD-LABEL: fma_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
; RV32IFD-NEXT: sw ra, 12(sp)
|
||||
; RV32IFD-NEXT: call fma
|
||||
; RV32IFD-NEXT: lw ra, 12(sp)
|
||||
; RV32IFD-NEXT: sw a4, 8(sp)
|
||||
; RV32IFD-NEXT: sw a5, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a2, 8(sp)
|
||||
; RV32IFD-NEXT: sw a3, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft1, 8(sp)
|
||||
; RV32IFD-NEXT: sw a0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a1, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft2, 8(sp)
|
||||
; RV32IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0
|
||||
; RV32IFD-NEXT: fsd ft0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a1, 12(sp)
|
||||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.fma.f64(double %a, double %b, double %c)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.fmuladd.f64(double, double, double)
|
||||
|
||||
define double @fmuladd_f64(double %a, double %b, double %c) nounwind {
|
||||
; Use of fmadd depends on TargetLowering::isFMAFasterthanFMulAndFAdd
|
||||
; RV32IFD-LABEL: fmuladd_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
; RV32IFD-NEXT: sw a2, 8(sp)
|
||||
; RV32IFD-NEXT: sw a3, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a0, 8(sp)
|
||||
; RV32IFD-NEXT: sw a1, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft1, 8(sp)
|
||||
; RV32IFD-NEXT: fmul.d ft0, ft1, ft0
|
||||
; RV32IFD-NEXT: sw a4, 8(sp)
|
||||
; RV32IFD-NEXT: sw a5, 12(sp)
|
||||
; RV32IFD-NEXT: fld ft1, 8(sp)
|
||||
; RV32IFD-NEXT: fadd.d ft0, ft0, ft1
|
||||
; RV32IFD-NEXT: fsd ft0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a0, 8(sp)
|
||||
; RV32IFD-NEXT: lw a1, 12(sp)
|
||||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.fmuladd.f64(double %a, double %b, double %c)
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.fabs.f64(double)
|
||||
|
||||
define double @fabs_f64(double %a) {
|
||||
define double @fabs_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: fabs_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -229,7 +265,7 @@ define double @fabs_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.fabs.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.minnum.f64(double, double)
|
||||
|
@ -317,7 +353,7 @@ define double @copysign_f64(double %a, double %b) nounwind {
|
|||
|
||||
declare double @llvm.floor.f64(double)
|
||||
|
||||
define double @floor_f64(double %a) {
|
||||
define double @floor_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: floor_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -327,12 +363,12 @@ define double @floor_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.floor.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.ceil.f64(double)
|
||||
|
||||
define double @ceil_f64(double %a) {
|
||||
define double @ceil_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: ceil_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -342,12 +378,12 @@ define double @ceil_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.ceil.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.trunc.f64(double)
|
||||
|
||||
define double @trunc_f64(double %a) {
|
||||
define double @trunc_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: trunc_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -357,12 +393,12 @@ define double @trunc_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.trunc.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.rint.f64(double)
|
||||
|
||||
define double @rint_f64(double %a) {
|
||||
define double @rint_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: rint_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -372,12 +408,12 @@ define double @rint_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.rint.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.nearbyint.f64(double)
|
||||
|
||||
define double @nearbyint_f64(double %a) {
|
||||
define double @nearbyint_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: nearbyint_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -387,12 +423,12 @@ define double @nearbyint_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.nearbyint.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
||||
declare double @llvm.round.f64(double)
|
||||
|
||||
define double @round_f64(double %a) {
|
||||
define double @round_f64(double %a) nounwind {
|
||||
; RV32IFD-LABEL: round_f64:
|
||||
; RV32IFD: # %bb.0:
|
||||
; RV32IFD-NEXT: addi sp, sp, -16
|
||||
|
@ -402,5 +438,5 @@ define double @round_f64(double %a) {
|
|||
; RV32IFD-NEXT: addi sp, sp, 16
|
||||
; RV32IFD-NEXT: ret
|
||||
%1 = call double @llvm.round.f64(double %a)
|
||||
ret double %1
|
||||
ret double %1
|
||||
}
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck -check-prefix=RV32IF %s
|
||||
|
||||
; These tests are each targeted at a particular RISC-V FPU instruction. Most
|
||||
; other files in this folder exercise LLVM IR instructions that don't directly
|
||||
; match a RISC-V instruction.
|
||||
|
||||
define float @fadd_s(float %a, float %b) nounwind {
|
||||
; RV32IF-LABEL: fadd_s:
|
||||
; RV32IF: # %bb.0:
|
||||
|
@ -186,3 +190,78 @@ define i32 @fle_s(float %a, float %b) nounwind {
|
|||
%2 = zext i1 %1 to i32
|
||||
ret i32 %2
|
||||
}
|
||||
|
||||
declare float @llvm.fma.f32(float, float, float)
|
||||
|
||||
define float @fmadd_s(float %a, float %b, float %c) nounwind {
|
||||
; RV32IF-LABEL: fmadd_s:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fmv.w.x ft0, a2
|
||||
; RV32IF-NEXT: fmv.w.x ft1, a1
|
||||
; RV32IF-NEXT: fmv.w.x ft2, a0
|
||||
; RV32IF-NEXT: fmadd.s ft0, ft2, ft1, ft0
|
||||
; RV32IF-NEXT: fmv.x.w a0, ft0
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.fma.f32(float %a, float %b, float %c)
|
||||
ret float %1
|
||||
}
|
||||
|
||||
define float @fmsub_s(float %a, float %b, float %c) nounwind {
|
||||
; RV32IF-LABEL: fmsub_s:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fmv.w.x ft0, a2
|
||||
; RV32IF-NEXT: lui a2, %hi(.LCPI15_0)
|
||||
; RV32IF-NEXT: addi a2, a2, %lo(.LCPI15_0)
|
||||
; RV32IF-NEXT: flw ft1, 0(a2)
|
||||
; RV32IF-NEXT: fadd.s ft0, ft0, ft1
|
||||
; RV32IF-NEXT: fmv.w.x ft1, a1
|
||||
; RV32IF-NEXT: fmv.w.x ft2, a0
|
||||
; RV32IF-NEXT: fmsub.s ft0, ft2, ft1, ft0
|
||||
; RV32IF-NEXT: fmv.x.w a0, ft0
|
||||
; RV32IF-NEXT: ret
|
||||
%c_ = fadd float 0.0, %c ; avoid negation using xor
|
||||
%negc = fsub float -0.0, %c_
|
||||
%1 = call float @llvm.fma.f32(float %a, float %b, float %negc)
|
||||
ret float %1
|
||||
}
|
||||
|
||||
define float @fnmadd_s(float %a, float %b, float %c) nounwind {
|
||||
; RV32IF-LABEL: fnmadd_s:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fmv.w.x ft0, a2
|
||||
; RV32IF-NEXT: lui a2, %hi(.LCPI16_0)
|
||||
; RV32IF-NEXT: addi a2, a2, %lo(.LCPI16_0)
|
||||
; RV32IF-NEXT: flw ft1, 0(a2)
|
||||
; RV32IF-NEXT: fadd.s ft0, ft0, ft1
|
||||
; RV32IF-NEXT: fmv.w.x ft2, a0
|
||||
; RV32IF-NEXT: fadd.s ft1, ft2, ft1
|
||||
; RV32IF-NEXT: fmv.w.x ft2, a1
|
||||
; RV32IF-NEXT: fnmadd.s ft0, ft1, ft2, ft0
|
||||
; RV32IF-NEXT: fmv.x.w a0, ft0
|
||||
; RV32IF-NEXT: ret
|
||||
%a_ = fadd float 0.0, %a
|
||||
%c_ = fadd float 0.0, %c
|
||||
%nega = fsub float -0.0, %a_
|
||||
%negc = fsub float -0.0, %c_
|
||||
%1 = call float @llvm.fma.f32(float %nega, float %b, float %negc)
|
||||
ret float %1
|
||||
}
|
||||
|
||||
define float @fnmsub_s(float %a, float %b, float %c) nounwind {
|
||||
; RV32IF-LABEL: fnmsub_s:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fmv.w.x ft0, a0
|
||||
; RV32IF-NEXT: lui a0, %hi(.LCPI17_0)
|
||||
; RV32IF-NEXT: addi a0, a0, %lo(.LCPI17_0)
|
||||
; RV32IF-NEXT: flw ft1, 0(a0)
|
||||
; RV32IF-NEXT: fadd.s ft0, ft0, ft1
|
||||
; RV32IF-NEXT: fmv.w.x ft1, a2
|
||||
; RV32IF-NEXT: fmv.w.x ft2, a1
|
||||
; RV32IF-NEXT: fnmsub.s ft0, ft0, ft2, ft1
|
||||
; RV32IF-NEXT: fmv.x.w a0, ft0
|
||||
; RV32IF-NEXT: ret
|
||||
%a_ = fadd float 0.0, %a
|
||||
%nega = fsub float -0.0, %a_
|
||||
%1 = call float @llvm.fma.f32(float %nega, float %b, float %c)
|
||||
ret float %1
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
declare float @llvm.sqrt.f32(float)
|
||||
|
||||
define float @sqrt_f32(float %a) {
|
||||
define float @sqrt_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: sqrt_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fmv.w.x ft0, a0
|
||||
|
@ -14,12 +14,12 @@ define float @sqrt_f32(float %a) {
|
|||
; RV32IF-NEXT: fmv.x.w a0, ft0
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.sqrt.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.powi.f32(float, i32)
|
||||
|
||||
define float @powi_f32(float %a, i32 %b) {
|
||||
define float @powi_f32(float %a, i32 %b) nounwind {
|
||||
; RV32IF-LABEL: powi_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -29,12 +29,12 @@ define float @powi_f32(float %a, i32 %b) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.powi.f32(float %a, i32 %b)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.sin.f32(float)
|
||||
|
||||
define float @sin_f32(float %a) {
|
||||
define float @sin_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: sin_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -44,12 +44,12 @@ define float @sin_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.sin.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.cos.f32(float)
|
||||
|
||||
define float @cos_f32(float %a) {
|
||||
define float @cos_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: cos_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -59,11 +59,11 @@ define float @cos_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.cos.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
; The sin+cos combination results in an FSINCOS SelectionDAG node.
|
||||
define float @sincos_f32(float %a) {
|
||||
define float @sincos_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: sincos_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -87,12 +87,12 @@ define float @sincos_f32(float %a) {
|
|||
%1 = call float @llvm.sin.f32(float %a)
|
||||
%2 = call float @llvm.cos.f32(float %a)
|
||||
%3 = fadd float %1, %2
|
||||
ret float %3
|
||||
ret float %3
|
||||
}
|
||||
|
||||
declare float @llvm.pow.f32(float, float)
|
||||
|
||||
define float @pow_f32(float %a, float %b) {
|
||||
define float @pow_f32(float %a, float %b) nounwind {
|
||||
; RV32IF-LABEL: pow_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -102,12 +102,12 @@ define float @pow_f32(float %a, float %b) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.pow.f32(float %a, float %b)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.exp.f32(float)
|
||||
|
||||
define float @exp_f32(float %a) {
|
||||
define float @exp_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: exp_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -117,12 +117,12 @@ define float @exp_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.exp.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.exp2.f32(float)
|
||||
|
||||
define float @exp2_f32(float %a) {
|
||||
define float @exp2_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: exp2_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -132,12 +132,12 @@ define float @exp2_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.exp2.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.log.f32(float)
|
||||
|
||||
define float @log_f32(float %a) {
|
||||
define float @log_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: log_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -147,12 +147,12 @@ define float @log_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.log.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.log10.f32(float)
|
||||
|
||||
define float @log10_f32(float %a) {
|
||||
define float @log10_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: log10_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -162,12 +162,12 @@ define float @log10_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.log10.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.log2.f32(float)
|
||||
|
||||
define float @log2_f32(float %a) {
|
||||
define float @log2_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: log2_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -177,28 +177,44 @@ define float @log2_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.log2.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.fma.f32(float, float, float)
|
||||
|
||||
; TODO: Select RISC-V FMA instruction.
|
||||
define float @fma_f32(float %a, float %b, float %c) {
|
||||
define float @fma_f32(float %a, float %b, float %c) nounwind {
|
||||
; RV32IF-LABEL: fma_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
; RV32IF-NEXT: sw ra, 12(sp)
|
||||
; RV32IF-NEXT: call fmaf
|
||||
; RV32IF-NEXT: lw ra, 12(sp)
|
||||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: fmv.w.x ft0, a2
|
||||
; RV32IF-NEXT: fmv.w.x ft1, a1
|
||||
; RV32IF-NEXT: fmv.w.x ft2, a0
|
||||
; RV32IF-NEXT: fmadd.s ft0, ft2, ft1, ft0
|
||||
; RV32IF-NEXT: fmv.x.w a0, ft0
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.fma.f32(float %a, float %b, float %c)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.fmuladd.f32(float, float, float)
|
||||
|
||||
define float @fmuladd_f32(float %a, float %b, float %c) nounwind {
|
||||
; Use of fmadd depends on TargetLowering::isFMAFasterthanFMulAndFAdd
|
||||
; RV32IF-LABEL: fmuladd_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fmv.w.x ft0, a1
|
||||
; RV32IF-NEXT: fmv.w.x ft1, a0
|
||||
; RV32IF-NEXT: fmul.s ft0, ft1, ft0
|
||||
; RV32IF-NEXT: fmv.w.x ft1, a2
|
||||
; RV32IF-NEXT: fadd.s ft0, ft0, ft1
|
||||
; RV32IF-NEXT: fmv.x.w a0, ft0
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.fabs.f32(float)
|
||||
|
||||
define float @fabs_f32(float %a) {
|
||||
define float @fabs_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: fabs_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: lui a1, 524288
|
||||
|
@ -206,7 +222,7 @@ define float @fabs_f32(float %a) {
|
|||
; RV32IF-NEXT: and a0, a0, a1
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.fabs.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.minnum.f32(float, float)
|
||||
|
@ -270,7 +286,7 @@ define float @copysign_f32(float %a, float %b) nounwind {
|
|||
|
||||
declare float @llvm.floor.f32(float)
|
||||
|
||||
define float @floor_f32(float %a) {
|
||||
define float @floor_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: floor_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -280,12 +296,12 @@ define float @floor_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.floor.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.ceil.f32(float)
|
||||
|
||||
define float @ceil_f32(float %a) {
|
||||
define float @ceil_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: ceil_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -295,12 +311,12 @@ define float @ceil_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.ceil.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.trunc.f32(float)
|
||||
|
||||
define float @trunc_f32(float %a) {
|
||||
define float @trunc_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: trunc_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -310,12 +326,12 @@ define float @trunc_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.trunc.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.rint.f32(float)
|
||||
|
||||
define float @rint_f32(float %a) {
|
||||
define float @rint_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: rint_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -325,12 +341,12 @@ define float @rint_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.rint.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.nearbyint.f32(float)
|
||||
|
||||
define float @nearbyint_f32(float %a) {
|
||||
define float @nearbyint_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: nearbyint_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -340,12 +356,12 @@ define float @nearbyint_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.nearbyint.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
||||
declare float @llvm.round.f32(float)
|
||||
|
||||
define float @round_f32(float %a) {
|
||||
define float @round_f32(float %a) nounwind {
|
||||
; RV32IF-LABEL: round_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: addi sp, sp, -16
|
||||
|
@ -355,5 +371,5 @@ define float @round_f32(float %a) {
|
|||
; RV32IF-NEXT: addi sp, sp, 16
|
||||
; RV32IF-NEXT: ret
|
||||
%1 = call float @llvm.round.f32(float %a)
|
||||
ret float %1
|
||||
ret float %1
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue