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,13 @@ // 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 _gen : FPFMA_gen; + def _def : FPFMA_def; + def : InstAlias(NAME # "_gen") + 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 +79,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 +261,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,15 +47,42 @@ // 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">; +// Instructions that may depend on dynamic rounding mode in FRM or set accrued +// flags in FFLAGs exist in two forms: +// - generic, which depends on FRM and defined FFLAGS. Constrained intrinsics +// are lowered to this form. +// - default, which ignores dependency on FRM and influence on FFLAGS. It is +// used to lower regular IR FP operations. + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { + class FPFMA_gen kind, RegisterClass rty> + : RVInstR4 { + let Defs = [FFLAGS]; + let Uses = [FRM]; + } + + class FPFMA_def kind, RegisterClass rty> + : RVInstR4 { + let isCodeGenOnly = 1; + // FIXME: Until constrained intrinsics are supported by RISCV codegen, use + // dynamic rounding mode. + let funct3 = 0b111; + } +} -class FPFMASDynFrmAlias - : InstAlias; +multiclass FPFMAS_mc { + def _gen : FPFMA_gen; + def _def : FPFMA_def; + def : InstAlias(NAME # "_gen") + 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> @@ -116,18 +143,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 +346,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,13 @@ // 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 _gen : FPFMA_gen; + def _def : FPFMA_def; + def : InstAlias(NAME # "_gen") + 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 +80,14 @@ "fsh", "$rs2, ${imm12}(${rs1})">, Sched<[WriteFST16, ReadStoreData, ReadFMemBase]>; -def FMADD_H : FPFMAH_rrr_frm, - Sched<[WriteFMulAdd16, ReadFMulAdd16, ReadFMulAdd16, ReadFMulAdd16]>; -def : FPFMAHDynFrmAlias; -def FMSUB_H : FPFMAH_rrr_frm, - Sched<[WriteFMulSub16, ReadFMulSub16, ReadFMulSub16, ReadFMulSub16]>; -def : FPFMAHDynFrmAlias; -def FNMSUB_H : FPFMAH_rrr_frm, - Sched<[WriteFMulSub16, ReadFMulSub16, ReadFMulSub16, ReadFMulSub16]>; -def : FPFMAHDynFrmAlias; -def FNMADD_H : FPFMAH_rrr_frm, - Sched<[WriteFMulAdd16, ReadFMulAdd16, ReadFMulAdd16, ReadFMulAdd16]>; -def : FPFMAHDynFrmAlias; +defm FMADD_H : FPFMAH_mc, + Sched<[WriteFMulAdd16, ReadFMulAdd16, ReadFMulAdd16, ReadFMulAdd16]>; +defm FMSUB_H : FPFMAH_mc, + Sched<[WriteFMulSub16, ReadFMulSub16, ReadFMulSub16, ReadFMulSub16]>; +defm FNMSUB_H : FPFMAH_mc, + Sched<[WriteFMulSub16, ReadFMulSub16, ReadFMulSub16, ReadFMulSub16]>; +defm FNMADD_H : FPFMAH_mc, + Sched<[WriteFMulAdd16, ReadFMulAdd16, ReadFMulAdd16, ReadFMulAdd16]>; def FADD_H : FPALUH_rr_frm<0b0000010, "fadd.h">, Sched<[WriteFALU16, ReadFALU16, ReadFALU16]>; @@ -283,19 +277,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;