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<RISCVOpcode opcode, string opcodestr> - : RVInstR4<0b01, opcode, (outs FPR64:$rd), - (ins FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, frmarg:$funct3), - opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; - -class FPFMADDynFrmAlias<FPFMAD_rrr_frm Inst, string OpcodeStr> - : InstAlias<OpcodeStr#" $rd, $rs1, $rs2, $rs3", - (Inst FPR64:$rd, FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; +multiclass FPFMAD_mc<RISCVOpcode opcode, string OpcodeStr> { + def _gen : FPFMA_gen<opcode, OpcodeStr, 0b01, FPR64>; + def _def : FPFMA_def<opcode, OpcodeStr, 0b01, FPR64>; + def : InstAlias<OpcodeStr#" $rd, $rs1, $rs2, $rs3", + (!cast<Instruction>(NAME # "_gen") + FPR64:$rd, FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; +} let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class FPALUD_rr<bits<7> funct7, bits<3> funct3, string opcodestr> @@ -81,18 +79,14 @@ "fsd", "$rs2, ${imm12}(${rs1})">, Sched<[WriteFST64, ReadStoreData, ReadFMemBase]>; -def FMADD_D : FPFMAD_rrr_frm<OPC_MADD, "fmadd.d">, - Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; -def : FPFMADDynFrmAlias<FMADD_D, "fmadd.d">; -def FMSUB_D : FPFMAD_rrr_frm<OPC_MSUB, "fmsub.d">, - Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; -def : FPFMADDynFrmAlias<FMSUB_D, "fmsub.d">; -def FNMSUB_D : FPFMAD_rrr_frm<OPC_NMSUB, "fnmsub.d">, - Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; -def : FPFMADDynFrmAlias<FNMSUB_D, "fnmsub.d">; -def FNMADD_D : FPFMAD_rrr_frm<OPC_NMADD, "fnmadd.d">, - Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; -def : FPFMADDynFrmAlias<FNMADD_D, "fnmadd.d">; +defm FMADD_D : FPFMAD_mc<OPC_MADD, "fmadd.d">, + Sched<[WriteFMulAdd64, ReadFMulAdd64, ReadFMulAdd64, ReadFMulAdd64]>; +defm FMSUB_D : FPFMAD_mc<OPC_MSUB, "fmsub.d">, + Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; +defm FNMSUB_D : FPFMAD_mc<OPC_NMSUB, "fnmsub.d">, + Sched<[WriteFMulSub64, ReadFMulSub64, ReadFMulSub64, ReadFMulSub64]>; +defm FNMADD_D : FPFMAD_mc<OPC_NMADD, "fnmadd.d">, + 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<RISCVOpcode opcode, string opcodestr> - : 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<RISCVOpcode opcode, string opcodestr, + bits<2> kind, RegisterClass rty> + : RVInstR4<kind, opcode, (outs rty:$rd), + (ins rty:$rs1, rty:$rs2, rty:$rs3, frmarg:$funct3), + opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3"> { + let Defs = [FFLAGS]; + let Uses = [FRM]; + } + + class FPFMA_def<RISCVOpcode opcode, string opcodestr, + bits<2> kind, RegisterClass rty> + : RVInstR4<kind, opcode, (outs rty:$rd), + (ins rty:$rs1, rty:$rs2, rty:$rs3), + opcodestr, "$rd, $rs1, $rs2, $rs3, dyn"> { + let isCodeGenOnly = 1; + // FIXME: Until constrained intrinsics are supported by RISCV codegen, use + // dynamic rounding mode. + let funct3 = 0b111; + } +} -class FPFMASDynFrmAlias<FPFMAS_rrr_frm Inst, string OpcodeStr> - : InstAlias<OpcodeStr#" $rd, $rs1, $rs2, $rs3", - (Inst FPR32:$rd, FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; +multiclass FPFMAS_mc<RISCVOpcode opcode, string OpcodeStr> { + def _gen : FPFMA_gen<opcode, OpcodeStr, 0b00, FPR32>; + def _def : FPFMA_def<opcode, OpcodeStr, 0b00, FPR32>; + def : InstAlias<OpcodeStr#" $rd, $rs1, $rs2, $rs3", + (!cast<Instruction>(NAME # "_gen") + FPR32:$rd, FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; +} let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class FPALUS_rr<bits<7> funct7, bits<3> funct3, string opcodestr> @@ -116,18 +143,14 @@ "fsw", "$rs2, ${imm12}(${rs1})">, Sched<[WriteFST32, ReadStoreData, ReadFMemBase]>; -def FMADD_S : FPFMAS_rrr_frm<OPC_MADD, "fmadd.s">, - Sched<[WriteFMulAdd32, ReadFMulAdd32, ReadFMulAdd32, ReadFMulAdd32]>; -def : FPFMASDynFrmAlias<FMADD_S, "fmadd.s">; -def FMSUB_S : FPFMAS_rrr_frm<OPC_MSUB, "fmsub.s">, - Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; -def : FPFMASDynFrmAlias<FMSUB_S, "fmsub.s">; -def FNMSUB_S : FPFMAS_rrr_frm<OPC_NMSUB, "fnmsub.s">, - Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; -def : FPFMASDynFrmAlias<FNMSUB_S, "fnmsub.s">; -def FNMADD_S : FPFMAS_rrr_frm<OPC_NMADD, "fnmadd.s">, - Sched<[WriteFMulAdd32, ReadFMulAdd32, ReadFMulAdd32, ReadFMulAdd32]>; -def : FPFMASDynFrmAlias<FNMADD_S, "fnmadd.s">; +defm FMADD_S : FPFMAS_mc<OPC_MADD, "fmadd.s">, + Sched<[WriteFMulAdd32, ReadFMulAdd32, ReadFMulAdd32, ReadFMulAdd32]>; +defm FMSUB_S : FPFMAS_mc<OPC_MSUB, "fmsub.s">, + Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; +defm FNMSUB_S : FPFMAS_mc<OPC_NMSUB, "fnmsub.s">, + Sched<[WriteFMulSub32, ReadFMulSub32, ReadFMulSub32, ReadFMulSub32]>; +defm FNMADD_S : FPFMAS_mc<OPC_NMADD, "fnmadd.s">, + 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<RISCVOpcode opcode, string opcodestr> - : RVInstR4<0b10, opcode, (outs FPR16:$rd), - (ins FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, frmarg:$funct3), - opcodestr, "$rd, $rs1, $rs2, $rs3, $funct3">; - -class FPFMAHDynFrmAlias<FPFMAH_rrr_frm Inst, string OpcodeStr> - : InstAlias<OpcodeStr#" $rd, $rs1, $rs2, $rs3", - (Inst FPR16:$rd, FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, 0b111)>; +multiclass FPFMAH_mc<RISCVOpcode opcode, string OpcodeStr> { + def _gen : FPFMA_gen<opcode, OpcodeStr, 0b10, FPR16>; + def _def : FPFMA_def<opcode, OpcodeStr, 0b10, FPR16>; + def : InstAlias<OpcodeStr#" $rd, $rs1, $rs2, $rs3", + (!cast<Instruction>(NAME # "_gen") + FPR16:$rd, FPR16:$rs1, FPR16:$rs2, FPR16:$rs3, 0b111)>; +} let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class FPALUH_rr<bits<7> funct7, bits<3> funct3, string opcodestr> @@ -82,18 +80,14 @@ "fsh", "$rs2, ${imm12}(${rs1})">, Sched<[WriteFST16, ReadStoreData, ReadFMemBase]>; -def FMADD_H : FPFMAH_rrr_frm<OPC_MADD, "fmadd.h">, - Sched<[WriteFMulAdd16, ReadFMulAdd16, ReadFMulAdd16, ReadFMulAdd16]>; -def : FPFMAHDynFrmAlias<FMADD_H, "fmadd.h">; -def FMSUB_H : FPFMAH_rrr_frm<OPC_MSUB, "fmsub.h">, - Sched<[WriteFMulSub16, ReadFMulSub16, ReadFMulSub16, ReadFMulSub16]>; -def : FPFMAHDynFrmAlias<FMSUB_H, "fmsub.h">; -def FNMSUB_H : FPFMAH_rrr_frm<OPC_NMSUB, "fnmsub.h">, - Sched<[WriteFMulSub16, ReadFMulSub16, ReadFMulSub16, ReadFMulSub16]>; -def : FPFMAHDynFrmAlias<FNMSUB_H, "fnmsub.h">; -def FNMADD_H : FPFMAH_rrr_frm<OPC_NMADD, "fnmadd.h">, - Sched<[WriteFMulAdd16, ReadFMulAdd16, ReadFMulAdd16, ReadFMulAdd16]>; -def : FPFMAHDynFrmAlias<FNMADD_H, "fnmadd.h">; +defm FMADD_H : FPFMAH_mc<OPC_MADD, "fmadd.h">, + Sched<[WriteFMulAdd16, ReadFMulAdd16, ReadFMulAdd16, ReadFMulAdd16]>; +defm FMSUB_H : FPFMAH_mc<OPC_MSUB, "fmsub.h">, + Sched<[WriteFMulSub16, ReadFMulSub16, ReadFMulSub16, ReadFMulSub16]>; +defm FNMSUB_H : FPFMAH_mc<OPC_NMSUB, "fnmsub.h">, + Sched<[WriteFMulSub16, ReadFMulSub16, ReadFMulSub16, ReadFMulSub16]>; +defm FNMADD_H : FPFMAH_mc<OPC_NMADD, "fnmadd.h">, + 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<fminnum, FMIN_H>; def : PatFpr16Fpr16<fmaxnum, FMAX_H>;