diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td @@ -29,15 +29,14 @@ // Instruction Class Templates //===----------------------------------------------------------------------===// -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPFMAD_rrr_frm - : RVInstR4<0b01, opcode, (outs FPR64:$rd), - (ins FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, frmarg:$funct3), - opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; - -class FPFMADDynFrmAlias - : InstAlias; +multiclass FPFMAD_mc { + def _sta : FPFMA_sta; + def _dyn : FPFMA_dyn; + def _def : FPFMA_def; + def : InstAlias(NAME # "_sta") + FPR64:$rd, FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; +} let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class FPALUD_rr funct7, bits<3> funct3, string opcodestr> @@ -81,18 +80,14 @@ "fsd", "$rs2, ${imm12}(${rs1})">, Sched<[WriteFST64, ReadStoreData, ReadFMemBase]>; -def FMADD_D : FPFMAD_rrr_frm, - Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; -def : FPFMADDynFrmAlias; -def FMSUB_D : FPFMAD_rrr_frm, - Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; -def : FPFMADDynFrmAlias; -def FNMSUB_D : FPFMAD_rrr_frm, - Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; -def : FPFMADDynFrmAlias; -def FNMADD_D : FPFMAD_rrr_frm, - Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; -def : FPFMADDynFrmAlias; +defm FMADD_D : FPFMAD_mc, + Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; +defm FMSUB_D : FPFMAD_mc, + Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; +defm FNMSUB_D : FPFMAD_mc, + Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; +defm FNMADD_D : FPFMAD_mc, + Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; def FADD_D : FPALUD_rr_frm<0b0000001, "fadd.d">, Sched<[WriteFALU64, ReadFALU64, ReadFALU64]>; @@ -267,19 +262,19 @@ // fmadd: rs1 * rs2 + rs3 def : Pat<(fma FPR64:$rs1, FPR64:$rs2, FPR64:$rs3), - (FMADD_D $rs1, $rs2, $rs3, 0b111)>; + (FMADD_D_def $rs1, $rs2, $rs3)>; // fmsub: rs1 * rs2 - rs3 def : Pat<(fma FPR64:$rs1, FPR64:$rs2, (fneg FPR64:$rs3)), - (FMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; + (FMSUB_D_def FPR64:$rs1, FPR64:$rs2, FPR64:$rs3)>; // fnmsub: -rs1 * rs2 + rs3 def : Pat<(fma (fneg FPR64:$rs1), FPR64:$rs2, FPR64:$rs3), - (FNMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; + (FNMSUB_D_def FPR64:$rs1, FPR64:$rs2, FPR64:$rs3)>; // fnmadd: -rs1 * rs2 - rs3 def : Pat<(fma (fneg FPR64:$rs1), FPR64:$rs2, (fneg FPR64:$rs3)), - (FNMADD_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; + (FNMADD_D_def FPR64:$rs1, FPR64:$rs2, FPR64:$rs3)>; // 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 diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td @@ -47,17 +47,45 @@ // Instruction class templates //===----------------------------------------------------------------------===// -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPFMAS_rrr_frm - : RVInstR4<0b00, opcode, (outs FPR32:$rd), - (ins FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, frmarg:$funct3), - opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { + class FPFMA_sta kind, RegisterClass rty> + : RVInstR4 { + let Defs = [FFLAGSReg]; + } + + class FPFMA_dyn kind, RegisterClass rty> + : RVInstR4 { + let isCodeGenOnly = 1; + let Defs = [FFLAGSReg]; + let Uses = [FRMReg]; + let funct3 = 0b111; + } + + class FPFMA_def kind, RegisterClass rty> + : RVInstR4 { + let isCodeGenOnly = 1; + let funct3 = 0b000; + } +} -class FPFMASDynFrmAlias - : InstAlias; +multiclass FPFMAS_mc { + def _sta : FPFMA_sta; + def _dyn : FPFMA_dyn; + def _def : FPFMA_def; + def : InstAlias(NAME # "_sta") + FPR32:$rd, FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; +} -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class FPALUS_rr funct7, bits<3> funct3, string opcodestr> : RVInstR; @@ -116,18 +144,14 @@ "fsw", "$rs2, ${imm12}(${rs1})">, Sched<[WriteFST32, ReadStoreData, ReadFMemBase]>; -def FMADD_S : FPFMAS_rrr_frm, - Sched<[WriteFMulAdd32, ReadFMulAdd32, ReadFMulAdd32, ReadFMulAdd32]>; -def : FPFMASDynFrmAlias; -def FMSUB_S : FPFMAS_rrr_frm, - Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; -def : FPFMASDynFrmAlias; -def FNMSUB_S : FPFMAS_rrr_frm, - Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; -def : FPFMASDynFrmAlias; -def FNMADD_S : FPFMAS_rrr_frm, - Sched<[WriteFMulAdd32, ReadFMulAdd32, ReadFMulAdd32, ReadFMulAdd32]>; -def : FPFMASDynFrmAlias; +defm FMADD_S : FPFMAS_mc, + Sched<[WriteFMulAdd32, ReadFMulAdd32, ReadFMulAdd32, ReadFMulAdd32]>; +defm FMSUB_S : FPFMAS_mc, + Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; +defm FNMSUB_S : FPFMAS_mc, + Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; +defm FNMADD_S : FPFMAS_mc, + Sched<[WriteFMulAdd32, ReadFMulAdd32, ReadFMulAdd32, ReadFMulAdd32]>; def FADD_S : FPALUS_rr_frm<0b0000000, "fadd.s">, Sched<[WriteFALU32, ReadFALU32, ReadFALU32]>; @@ -323,19 +347,19 @@ // fmadd: rs1 * rs2 + rs3 def : Pat<(fma FPR32:$rs1, FPR32:$rs2, FPR32:$rs3), - (FMADD_S $rs1, $rs2, $rs3, 0b111)>; + (FMADD_S_def $rs1, $rs2, $rs3)>; // fmsub: rs1 * rs2 - rs3 def : Pat<(fma FPR32:$rs1, FPR32:$rs2, (fneg FPR32:$rs3)), - (FMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; + (FMSUB_S_def FPR32:$rs1, FPR32:$rs2, FPR32:$rs3)>; // fnmsub: -rs1 * rs2 + rs3 def : Pat<(fma (fneg FPR32:$rs1), FPR32:$rs2, FPR32:$rs3), - (FNMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; + (FNMSUB_S_def FPR32:$rs1, FPR32:$rs2, FPR32:$rs3)>; // fnmadd: -rs1 * rs2 - rs3 def : Pat<(fma (fneg FPR32:$rs1), FPR32:$rs2, (fneg FPR32:$rs3)), - (FNMADD_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; + (FNMADD_S_def FPR32:$rs1, FPR32:$rs2, FPR32:$rs3)>; // 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 diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td @@ -31,15 +31,14 @@ // Instruction class templates //===----------------------------------------------------------------------===// -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class FPFMAH_rrr_frm - : RVInstR4<0b10, opcode, (outs FPR16:$rd), - (ins FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, frmarg:$funct3), - opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; - -class FPFMAHDynFrmAlias - : InstAlias; +multiclass FPFMAH_mc { + def _sta : FPFMA_sta; + def _dyn : FPFMA_dyn; + def _def : FPFMA_def; + def : InstAlias(NAME # "_sta") + FPR16:$rd, FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, 0b111)>; +} let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class FPALUH_rr funct7, bits<3> funct3, string opcodestr> @@ -82,18 +81,14 @@ "fsh", "$rs2, ${imm12}(${rs1})">, Sched<[]>; -def FMADD_H : FPFMAH_rrr_frm, - Sched<[]>; -def : FPFMAHDynFrmAlias; -def FMSUB_H : FPFMAH_rrr_frm, - Sched<[]>; -def : FPFMAHDynFrmAlias; -def FNMSUB_H : FPFMAH_rrr_frm, - Sched<[]>; -def : FPFMAHDynFrmAlias; -def FNMADD_H : FPFMAH_rrr_frm, - Sched<[]>; -def : FPFMAHDynFrmAlias; +defm FMADD_H : FPFMAH_mc, + Sched<[]>; +defm FMSUB_H : FPFMAH_mc, + Sched<[]>; +defm FNMSUB_H : FPFMAH_mc, + Sched<[]>; +defm FNMADD_H : FPFMAH_mc, + Sched<[]>; def FADD_H : FPALUH_rr_frm<0b0000010, "fadd.h">, Sched<[]>; @@ -287,19 +282,19 @@ // fmadd: rs1 * rs2 + rs3 def : Pat<(fma FPR16:$rs1, FPR16:$rs2, FPR16:$rs3), - (FMADD_H $rs1, $rs2, $rs3, 0b111)>; + (FMADD_H_def $rs1, $rs2, $rs3)>; // fmsub: rs1 * rs2 - rs3 def : Pat<(fma FPR16:$rs1, FPR16:$rs2, (fneg FPR16:$rs3)), - (FMSUB_H FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, 0b111)>; + (FMSUB_H_def FPR16:$rs1, FPR16:$rs2, FPR16:$rs3)>; // fnmsub: -rs1 * rs2 + rs3 def : Pat<(fma (fneg FPR16:$rs1), FPR16:$rs2, FPR16:$rs3), - (FNMSUB_H FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, 0b111)>; + (FNMSUB_H_def FPR16:$rs1, FPR16:$rs2, FPR16:$rs3)>; // fnmadd: -rs1 * rs2 - rs3 def : Pat<(fma (fneg FPR16:$rs1), FPR16:$rs2, (fneg FPR16:$rs3)), - (FNMADD_H FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, 0b111)>; + (FNMADD_H_def FPR16:$rs1, FPR16:$rs2, FPR16:$rs3)>; def : PatFpr16Fpr16; def : PatFpr16Fpr16; diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -451,3 +451,8 @@ def VMV0 : RegisterClass<"RISCV", VMaskVTs, 64, (add V0)> { let Size = 64; } + +// Special registers +def FFLAGSReg : RISCVReg<1, "fflags">; +def FRMReg : RISCVReg<2, "frm">; +def FCSRReg : RISCVReg<3, "fcsr">; diff --git a/llvm/test/CodeGen/RISCV/double-arith.ll b/llvm/test/CodeGen/RISCV/double-arith.ll --- a/llvm/test/CodeGen/RISCV/double-arith.ll +++ b/llvm/test/CodeGen/RISCV/double-arith.ll @@ -428,7 +428,7 @@ ; 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: fmadd.d ft0, ft2, ft1, ft0, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -440,7 +440,7 @@ ; RV64IFD-NEXT: fmv.d.x ft0, a2 ; RV64IFD-NEXT: fmv.d.x ft1, a1 ; RV64IFD-NEXT: fmv.d.x ft2, a0 -; RV64IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0 +; RV64IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %1 = call double @llvm.fma.f64(double %a, double %b, double %c) @@ -462,7 +462,7 @@ ; RV32IFD-NEXT: fld ft2, 8(sp) ; RV32IFD-NEXT: fcvt.d.w ft3, zero ; RV32IFD-NEXT: fadd.d ft2, ft2, ft3 -; RV32IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2 +; RV32IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -476,7 +476,7 @@ ; RV64IFD-NEXT: fmv.d.x ft2, a2 ; RV64IFD-NEXT: fmv.d.x ft3, zero ; RV64IFD-NEXT: fadd.d ft2, ft2, ft3 -; RV64IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2 +; RV64IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %c_ = fadd double 0.0, %c ; avoid negation using xor @@ -501,7 +501,7 @@ ; RV32IFD-NEXT: fcvt.d.w ft3, zero ; RV32IFD-NEXT: fadd.d ft2, ft2, ft3 ; RV32IFD-NEXT: fadd.d ft1, ft1, ft3 -; RV32IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1 +; RV32IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -516,7 +516,7 @@ ; RV64IFD-NEXT: fmv.d.x ft3, zero ; RV64IFD-NEXT: fadd.d ft2, ft2, ft3 ; RV64IFD-NEXT: fadd.d ft1, ft1, ft3 -; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1 +; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %a_ = fadd double 0.0, %a @@ -543,7 +543,7 @@ ; RV32IFD-NEXT: fcvt.d.w ft3, zero ; RV32IFD-NEXT: fadd.d ft2, ft2, ft3 ; RV32IFD-NEXT: fadd.d ft1, ft1, ft3 -; RV32IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1 +; RV32IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -558,7 +558,7 @@ ; RV64IFD-NEXT: fmv.d.x ft3, zero ; RV64IFD-NEXT: fadd.d ft2, ft2, ft3 ; RV64IFD-NEXT: fadd.d ft1, ft1, ft3 -; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1 +; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %b_ = fadd double 0.0, %b @@ -584,7 +584,7 @@ ; RV32IFD-NEXT: fld ft2, 8(sp) ; RV32IFD-NEXT: fcvt.d.w ft3, zero ; RV32IFD-NEXT: fadd.d ft2, ft2, ft3 -; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0 +; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -598,7 +598,7 @@ ; RV64IFD-NEXT: fmv.d.x ft2, a0 ; RV64IFD-NEXT: fmv.d.x ft3, zero ; RV64IFD-NEXT: fadd.d ft2, ft2, ft3 -; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0 +; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %a_ = fadd double 0.0, %a @@ -622,7 +622,7 @@ ; RV32IFD-NEXT: fld ft2, 8(sp) ; RV32IFD-NEXT: fcvt.d.w ft3, zero ; RV32IFD-NEXT: fadd.d ft2, ft2, ft3 -; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0 +; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -636,7 +636,7 @@ ; RV64IFD-NEXT: fmv.d.x ft2, a1 ; RV64IFD-NEXT: fmv.d.x ft3, zero ; RV64IFD-NEXT: fadd.d ft2, ft2, ft3 -; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0 +; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %b_ = fadd double 0.0, %b @@ -658,7 +658,7 @@ ; 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: fmadd.d ft0, ft2, ft1, ft0, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -670,7 +670,7 @@ ; RV64IFD-NEXT: fmv.d.x ft0, a2 ; RV64IFD-NEXT: fmv.d.x ft1, a1 ; RV64IFD-NEXT: fmv.d.x ft2, a0 -; RV64IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0 +; RV64IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %1 = fmul contract double %a, %b @@ -693,7 +693,7 @@ ; RV32IFD-NEXT: fld ft2, 8(sp) ; RV32IFD-NEXT: fcvt.d.w ft3, zero ; RV32IFD-NEXT: fadd.d ft2, ft2, ft3 -; RV32IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2 +; RV32IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -707,7 +707,7 @@ ; RV64IFD-NEXT: fmv.d.x ft2, a2 ; RV64IFD-NEXT: fmv.d.x ft3, zero ; RV64IFD-NEXT: fadd.d ft2, ft2, ft3 -; RV64IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2 +; RV64IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %c_ = fadd double 0.0, %c ; avoid negation using xor @@ -733,7 +733,7 @@ ; RV32IFD-NEXT: fadd.d ft2, ft2, ft3 ; RV32IFD-NEXT: fadd.d ft1, ft1, ft3 ; RV32IFD-NEXT: fadd.d ft0, ft0, ft3 -; RV32IFD-NEXT: fnmadd.d ft0, ft2, ft1, ft0 +; RV32IFD-NEXT: fnmadd.d ft0, ft2, ft1, ft0, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -749,7 +749,7 @@ ; RV64IFD-NEXT: fadd.d ft2, ft2, ft3 ; RV64IFD-NEXT: fadd.d ft1, ft1, ft3 ; RV64IFD-NEXT: fadd.d ft0, ft0, ft3 -; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft1, ft0 +; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft1, ft0, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %a_ = fadd double 0.0, %a ; avoid negation using xor @@ -777,7 +777,7 @@ ; RV32IFD-NEXT: fcvt.d.w ft3, zero ; RV32IFD-NEXT: fadd.d ft2, ft2, ft3 ; RV32IFD-NEXT: fadd.d ft1, ft1, ft3 -; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0 +; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0, rne ; RV32IFD-NEXT: fsd ft0, 8(sp) ; RV32IFD-NEXT: lw a0, 8(sp) ; RV32IFD-NEXT: lw a1, 12(sp) @@ -792,7 +792,7 @@ ; RV64IFD-NEXT: fmv.d.x ft3, zero ; RV64IFD-NEXT: fadd.d ft2, ft2, ft3 ; RV64IFD-NEXT: fadd.d ft1, ft1, ft3 -; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0 +; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0, rne ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret %a_ = fadd double 0.0, %a ; avoid negation using xor diff --git a/llvm/test/CodeGen/RISCV/float-arith.ll b/llvm/test/CodeGen/RISCV/float-arith.ll --- a/llvm/test/CodeGen/RISCV/float-arith.ll +++ b/llvm/test/CodeGen/RISCV/float-arith.ll @@ -320,7 +320,7 @@ ; 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: fmadd.s ft0, ft2, ft1, ft0, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -329,7 +329,7 @@ ; RV64IF-NEXT: fmv.w.x ft0, a2 ; RV64IF-NEXT: fmv.w.x ft1, a1 ; RV64IF-NEXT: fmv.w.x ft2, a0 -; RV64IF-NEXT: fmadd.s ft0, ft2, ft1, ft0 +; RV64IF-NEXT: fmadd.s ft0, ft2, ft1, ft0, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %1 = call float @llvm.fma.f32(float %a, float %b, float %c) @@ -344,7 +344,7 @@ ; RV32IF-NEXT: fmv.w.x ft2, a2 ; RV32IF-NEXT: fmv.w.x ft3, zero ; RV32IF-NEXT: fadd.s ft2, ft2, ft3 -; RV32IF-NEXT: fmsub.s ft0, ft1, ft0, ft2 +; RV32IF-NEXT: fmsub.s ft0, ft1, ft0, ft2, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -355,7 +355,7 @@ ; RV64IF-NEXT: fmv.w.x ft2, a2 ; RV64IF-NEXT: fmv.w.x ft3, zero ; RV64IF-NEXT: fadd.s ft2, ft2, ft3 -; RV64IF-NEXT: fmsub.s ft0, ft1, ft0, ft2 +; RV64IF-NEXT: fmsub.s ft0, ft1, ft0, ft2, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %c_ = fadd float 0.0, %c ; avoid negation using xor @@ -373,7 +373,7 @@ ; RV32IF-NEXT: fmv.w.x ft3, zero ; RV32IF-NEXT: fadd.s ft2, ft2, ft3 ; RV32IF-NEXT: fadd.s ft1, ft1, ft3 -; RV32IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1 +; RV32IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -385,7 +385,7 @@ ; RV64IF-NEXT: fmv.w.x ft3, zero ; RV64IF-NEXT: fadd.s ft2, ft2, ft3 ; RV64IF-NEXT: fadd.s ft1, ft1, ft3 -; RV64IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1 +; RV64IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %a_ = fadd float 0.0, %a @@ -405,7 +405,7 @@ ; RV32IF-NEXT: fmv.w.x ft3, zero ; RV32IF-NEXT: fadd.s ft2, ft2, ft3 ; RV32IF-NEXT: fadd.s ft1, ft1, ft3 -; RV32IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1 +; RV32IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -417,7 +417,7 @@ ; RV64IF-NEXT: fmv.w.x ft3, zero ; RV64IF-NEXT: fadd.s ft2, ft2, ft3 ; RV64IF-NEXT: fadd.s ft1, ft1, ft3 -; RV64IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1 +; RV64IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %b_ = fadd float 0.0, %b @@ -436,7 +436,7 @@ ; RV32IF-NEXT: fmv.w.x ft2, a0 ; RV32IF-NEXT: fmv.w.x ft3, zero ; RV32IF-NEXT: fadd.s ft2, ft2, ft3 -; RV32IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0 +; RV32IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -447,7 +447,7 @@ ; RV64IF-NEXT: fmv.w.x ft2, a0 ; RV64IF-NEXT: fmv.w.x ft3, zero ; RV64IF-NEXT: fadd.s ft2, ft2, ft3 -; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0 +; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %a_ = fadd float 0.0, %a @@ -464,7 +464,7 @@ ; RV32IF-NEXT: fmv.w.x ft2, a1 ; RV32IF-NEXT: fmv.w.x ft3, zero ; RV32IF-NEXT: fadd.s ft2, ft2, ft3 -; RV32IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0 +; RV32IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -475,7 +475,7 @@ ; RV64IF-NEXT: fmv.w.x ft2, a1 ; RV64IF-NEXT: fmv.w.x ft3, zero ; RV64IF-NEXT: fadd.s ft2, ft2, ft3 -; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0 +; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %b_ = fadd float 0.0, %b @@ -490,7 +490,7 @@ ; 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: fmadd.s ft0, ft2, ft1, ft0, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -499,7 +499,7 @@ ; RV64IF-NEXT: fmv.w.x ft0, a2 ; RV64IF-NEXT: fmv.w.x ft1, a1 ; RV64IF-NEXT: fmv.w.x ft2, a0 -; RV64IF-NEXT: fmadd.s ft0, ft2, ft1, ft0 +; RV64IF-NEXT: fmadd.s ft0, ft2, ft1, ft0, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %1 = fmul contract float %a, %b @@ -515,7 +515,7 @@ ; RV32IF-NEXT: fmv.w.x ft2, a2 ; RV32IF-NEXT: fmv.w.x ft3, zero ; RV32IF-NEXT: fadd.s ft2, ft2, ft3 -; RV32IF-NEXT: fmsub.s ft0, ft1, ft0, ft2 +; RV32IF-NEXT: fmsub.s ft0, ft1, ft0, ft2, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -526,7 +526,7 @@ ; RV64IF-NEXT: fmv.w.x ft2, a2 ; RV64IF-NEXT: fmv.w.x ft3, zero ; RV64IF-NEXT: fadd.s ft2, ft2, ft3 -; RV64IF-NEXT: fmsub.s ft0, ft1, ft0, ft2 +; RV64IF-NEXT: fmsub.s ft0, ft1, ft0, ft2, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %c_ = fadd float 0.0, %c ; avoid negation using xor @@ -545,7 +545,7 @@ ; RV32IF-NEXT: fadd.s ft2, ft2, ft3 ; RV32IF-NEXT: fadd.s ft1, ft1, ft3 ; RV32IF-NEXT: fadd.s ft0, ft0, ft3 -; RV32IF-NEXT: fnmadd.s ft0, ft2, ft1, ft0 +; RV32IF-NEXT: fnmadd.s ft0, ft2, ft1, ft0, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -558,7 +558,7 @@ ; RV64IF-NEXT: fadd.s ft2, ft2, ft3 ; RV64IF-NEXT: fadd.s ft1, ft1, ft3 ; RV64IF-NEXT: fadd.s ft0, ft0, ft3 -; RV64IF-NEXT: fnmadd.s ft0, ft2, ft1, ft0 +; RV64IF-NEXT: fnmadd.s ft0, ft2, ft1, ft0, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %a_ = fadd float 0.0, %a ; avoid negation using xor @@ -579,7 +579,7 @@ ; RV32IF-NEXT: fmv.w.x ft3, zero ; RV32IF-NEXT: fadd.s ft2, ft2, ft3 ; RV32IF-NEXT: fadd.s ft1, ft1, ft3 -; RV32IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0 +; RV32IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0, rne ; RV32IF-NEXT: fmv.x.w a0, ft0 ; RV32IF-NEXT: ret ; @@ -591,7 +591,7 @@ ; RV64IF-NEXT: fmv.w.x ft3, zero ; RV64IF-NEXT: fadd.s ft2, ft2, ft3 ; RV64IF-NEXT: fadd.s ft1, ft1, ft3 -; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0 +; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0, rne ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret %a_ = fadd float 0.0, %a ; avoid negation using xor diff --git a/llvm/test/CodeGen/RISCV/half-arith.ll b/llvm/test/CodeGen/RISCV/half-arith.ll --- a/llvm/test/CodeGen/RISCV/half-arith.ll +++ b/llvm/test/CodeGen/RISCV/half-arith.ll @@ -247,12 +247,12 @@ define half @fmadd_s(half %a, half %b, half %c) nounwind { ; RV32IZFH-LABEL: fmadd_s: ; RV32IZFH: # %bb.0: -; RV32IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2 +; RV32IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fmadd_s: ; RV64IZFH: # %bb.0: -; RV64IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2 +; RV64IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2, rne ; RV64IZFH-NEXT: ret %1 = call half @llvm.fma.f16(half %a, half %b, half %c) ret half %1 @@ -263,14 +263,14 @@ ; RV32IZFH: # %bb.0: ; RV32IZFH-NEXT: fmv.h.x ft0, zero ; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV32IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0 +; RV32IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fmsub_s: ; RV64IZFH: # %bb.0: ; RV64IZFH-NEXT: fmv.h.x ft0, zero ; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV64IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0 +; RV64IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0, rne ; RV64IZFH-NEXT: ret %c_ = fadd half 0.0, %c ; avoid negation using xor %negc = fsub half -0.0, %c_ @@ -284,7 +284,7 @@ ; RV32IZFH-NEXT: fmv.h.x ft0, zero ; RV32IZFH-NEXT: fadd.h ft1, fa0, ft0 ; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV32IZFH-NEXT: fnmadd.h fa0, ft1, fa1, ft0 +; RV32IZFH-NEXT: fnmadd.h fa0, ft1, fa1, ft0, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fnmadd_s: @@ -292,7 +292,7 @@ ; RV64IZFH-NEXT: fmv.h.x ft0, zero ; RV64IZFH-NEXT: fadd.h ft1, fa0, ft0 ; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV64IZFH-NEXT: fnmadd.h fa0, ft1, fa1, ft0 +; RV64IZFH-NEXT: fnmadd.h fa0, ft1, fa1, ft0, rne ; RV64IZFH-NEXT: ret %a_ = fadd half 0.0, %a %c_ = fadd half 0.0, %c @@ -308,7 +308,7 @@ ; RV32IZFH-NEXT: fmv.h.x ft0, zero ; RV32IZFH-NEXT: fadd.h ft1, fa1, ft0 ; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV32IZFH-NEXT: fnmadd.h fa0, ft1, fa0, ft0 +; RV32IZFH-NEXT: fnmadd.h fa0, ft1, fa0, ft0, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fnmadd_s_2: @@ -316,7 +316,7 @@ ; RV64IZFH-NEXT: fmv.h.x ft0, zero ; RV64IZFH-NEXT: fadd.h ft1, fa1, ft0 ; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV64IZFH-NEXT: fnmadd.h fa0, ft1, fa0, ft0 +; RV64IZFH-NEXT: fnmadd.h fa0, ft1, fa0, ft0, rne ; RV64IZFH-NEXT: ret %b_ = fadd half 0.0, %b %c_ = fadd half 0.0, %c @@ -331,14 +331,14 @@ ; RV32IZFH: # %bb.0: ; RV32IZFH-NEXT: fmv.h.x ft0, zero ; RV32IZFH-NEXT: fadd.h ft0, fa0, ft0 -; RV32IZFH-NEXT: fnmsub.h fa0, ft0, fa1, fa2 +; RV32IZFH-NEXT: fnmsub.h fa0, ft0, fa1, fa2, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fnmsub_s: ; RV64IZFH: # %bb.0: ; RV64IZFH-NEXT: fmv.h.x ft0, zero ; RV64IZFH-NEXT: fadd.h ft0, fa0, ft0 -; RV64IZFH-NEXT: fnmsub.h fa0, ft0, fa1, fa2 +; RV64IZFH-NEXT: fnmsub.h fa0, ft0, fa1, fa2, rne ; RV64IZFH-NEXT: ret %a_ = fadd half 0.0, %a %nega = fsub half -0.0, %a_ @@ -351,14 +351,14 @@ ; RV32IZFH: # %bb.0: ; RV32IZFH-NEXT: fmv.h.x ft0, zero ; RV32IZFH-NEXT: fadd.h ft0, fa1, ft0 -; RV32IZFH-NEXT: fnmsub.h fa0, ft0, fa0, fa2 +; RV32IZFH-NEXT: fnmsub.h fa0, ft0, fa0, fa2, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fnmsub_s_2: ; RV64IZFH: # %bb.0: ; RV64IZFH-NEXT: fmv.h.x ft0, zero ; RV64IZFH-NEXT: fadd.h ft0, fa1, ft0 -; RV64IZFH-NEXT: fnmsub.h fa0, ft0, fa0, fa2 +; RV64IZFH-NEXT: fnmsub.h fa0, ft0, fa0, fa2, rne ; RV64IZFH-NEXT: ret %b_ = fadd half 0.0, %b %negb = fsub half -0.0, %b_ @@ -369,12 +369,12 @@ define half @fmadd_s_contract(half %a, half %b, half %c) nounwind { ; RV32IZFH-LABEL: fmadd_s_contract: ; RV32IZFH: # %bb.0: -; RV32IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2 +; RV32IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fmadd_s_contract: ; RV64IZFH: # %bb.0: -; RV64IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2 +; RV64IZFH-NEXT: fmadd.h fa0, fa0, fa1, fa2, rne ; RV64IZFH-NEXT: ret %1 = fmul contract half %a, %b %2 = fadd contract half %1, %c @@ -386,14 +386,14 @@ ; RV32IZFH: # %bb.0: ; RV32IZFH-NEXT: fmv.h.x ft0, zero ; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV32IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0 +; RV32IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fmsub_s_contract: ; RV64IZFH: # %bb.0: ; RV64IZFH-NEXT: fmv.h.x ft0, zero ; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV64IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0 +; RV64IZFH-NEXT: fmsub.h fa0, fa0, fa1, ft0, rne ; RV64IZFH-NEXT: ret %c_ = fadd half 0.0, %c ; avoid negation using xor %1 = fmul contract half %a, %b @@ -408,7 +408,7 @@ ; RV32IZFH-NEXT: fadd.h ft1, fa0, ft0 ; RV32IZFH-NEXT: fadd.h ft2, fa1, ft0 ; RV32IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV32IZFH-NEXT: fnmadd.h fa0, ft1, ft2, ft0 +; RV32IZFH-NEXT: fnmadd.h fa0, ft1, ft2, ft0, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fnmadd_s_contract: @@ -417,7 +417,7 @@ ; RV64IZFH-NEXT: fadd.h ft1, fa0, ft0 ; RV64IZFH-NEXT: fadd.h ft2, fa1, ft0 ; RV64IZFH-NEXT: fadd.h ft0, fa2, ft0 -; RV64IZFH-NEXT: fnmadd.h fa0, ft1, ft2, ft0 +; RV64IZFH-NEXT: fnmadd.h fa0, ft1, ft2, ft0, rne ; RV64IZFH-NEXT: ret %a_ = fadd half 0.0, %a ; avoid negation using xor %b_ = fadd half 0.0, %b ; avoid negation using xor @@ -434,7 +434,7 @@ ; RV32IZFH-NEXT: fmv.h.x ft0, zero ; RV32IZFH-NEXT: fadd.h ft1, fa0, ft0 ; RV32IZFH-NEXT: fadd.h ft0, fa1, ft0 -; RV32IZFH-NEXT: fnmsub.h fa0, ft1, ft0, fa2 +; RV32IZFH-NEXT: fnmsub.h fa0, ft1, ft0, fa2, rne ; RV32IZFH-NEXT: ret ; ; RV64IZFH-LABEL: fnmsub_s_contract: @@ -442,7 +442,7 @@ ; RV64IZFH-NEXT: fmv.h.x ft0, zero ; RV64IZFH-NEXT: fadd.h ft1, fa0, ft0 ; RV64IZFH-NEXT: fadd.h ft0, fa1, ft0 -; RV64IZFH-NEXT: fnmsub.h fa0, ft1, ft0, fa2 +; RV64IZFH-NEXT: fnmsub.h fa0, ft1, ft0, fa2, rne ; RV64IZFH-NEXT: ret %a_ = fadd half 0.0, %a ; avoid negation using xor %b_ = fadd half 0.0, %b ; avoid negation using xor