diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -175,20 +175,6 @@ return TSFlags & HasRoundModeOpMask; } -/// \returns the index to the rounding mode immediate value if any, otherwise -/// returns -1. -static inline int getRoundModeOpNum(const MCInstrDesc &Desc) { - const uint64_t TSFlags = Desc.TSFlags; - if (!hasRoundModeOp(TSFlags)) - return -1; - // The operand order - // ------------------------------------- - // | n-1 (if any) | n-2 | n-3 | n-4 | - // | policy | sew | vl | rm | - // ------------------------------------- - return Desc.getNumOperands() - hasVecPolicyOp(TSFlags) - 3; -} - /// \returns true if this instruction uses vxrm static inline bool usesVXRM(uint64_t TSFlags) { return TSFlags & UsesVXRMMask; } @@ -217,6 +203,35 @@ return Desc.getNumOperands() - 1; } +/// \returns the index to the rounding mode immediate value if any, otherwise +/// returns -1. +static inline int getFRMOpNum(const MCInstrDesc &Desc) { + const uint64_t TSFlags = Desc.TSFlags; + if (!hasRoundModeOp(TSFlags) || usesVXRM(TSFlags)) + return -1; + + // The operand order + // -------------------------------------- + // | n-1 (if any) | n-2 | n-3 | n-4 | + // | policy | sew | vl | frm | + // -------------------------------------- + return getVLOpNum(Desc) - 1; +} + +/// \returns the index to the rounding mode immediate value if any, otherwise +/// returns -1. +static inline int getVXRMOpNum(const MCInstrDesc &Desc) { + const uint64_t TSFlags = Desc.TSFlags; + if (!hasRoundModeOp(TSFlags) || !usesVXRM(TSFlags)) + return -1; + // The operand order + // -------------------------------------- + // | n-1 (if any) | n-2 | n-3 | n-4 | + // | policy | sew | vl | vxrm | + // -------------------------------------- + return getVLOpNum(Desc) - 1; +} + // Is the first def operand tied to the first use operand. This is true for // vector pseudo instructions that have a merge operand for tail/mask // undisturbed. It's also true for vector FMA instructions where one of the diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -779,13 +779,14 @@ uint64_t TSFlags = MCID.TSFlags; unsigned NumOps = MI->getNumExplicitOperands(); - // Skip policy, VL and SEW operands which are the last operands if present. + // Skip policy, SEW, VL, VXRM/FRM operands which are the last operands if + // present. if (RISCVII::hasVecPolicyOp(TSFlags)) --NumOps; - if (RISCVII::hasVLOp(TSFlags)) - --NumOps; if (RISCVII::hasSEWOp(TSFlags)) --NumOps; + if (RISCVII::hasVLOp(TSFlags)) + --NumOps; if (RISCVII::hasRoundModeOp(TSFlags)) --NumOps; diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -14925,22 +14925,14 @@ void RISCVTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const { - // Add FRM dependency to vector floating-point instructions with dynamic - // rounding mode. - int RoundModeIdx = RISCVII::getRoundModeOpNum(MI.getDesc()); - if (RoundModeIdx >= 0) { - unsigned FRMImm = MI.getOperand(RoundModeIdx).getImm(); - if (FRMImm == RISCVFPRndMode::DYN && !MI.readsRegister(RISCV::FRM)) { - MI.addOperand(MachineOperand::CreateReg(RISCV::FRM, /*isDef*/ false, - /*isImp*/ true)); - } - } - // Add FRM dependency to any instructions with dynamic rounding mode. - unsigned Opc = MI.getOpcode(); - auto Idx = RISCV::getNamedOperandIdx(Opc, RISCV::OpName::frm); - if (Idx < 0) - return; + int Idx = RISCV::getNamedOperandIdx(MI.getOpcode(), RISCV::OpName::frm); + if (Idx < 0) { + // Vector pseudos have FRM index indicated by TSFlags. + Idx = RISCVII::getFRMOpNum(MI.getDesc()); + if (Idx < 0) + return; + } if (MI.getOperand(Idx).getImm() != RISCVFPRndMode::DYN) return; // If the instruction already reads FRM, don't add another read. diff --git a/llvm/lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp b/llvm/lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp --- a/llvm/lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp +++ b/llvm/lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp @@ -64,12 +64,9 @@ bool RISCVInsertReadWriteCSR::emitWriteRoundingMode(MachineBasicBlock &MBB) { bool Changed = false; for (MachineInstr &MI : MBB) { - int RoundModeIdx = RISCVII::getRoundModeOpNum(MI.getDesc()); - if (RoundModeIdx < 0) - continue; - - if (RISCVII::usesVXRM(MI.getDesc().TSFlags)) { - unsigned VXRMImm = MI.getOperand(RoundModeIdx).getImm(); + int VXRMIdx = RISCVII::getVXRMOpNum(MI.getDesc()); + if (VXRMIdx >= 0) { + unsigned VXRMImm = MI.getOperand(VXRMIdx).getImm(); Changed = true; @@ -77,29 +74,34 @@ .addImm(VXRMImm); MI.addOperand(MachineOperand::CreateReg(RISCV::VXRM, /*IsDef*/ false, /*IsImp*/ true)); - } else { // FRM - unsigned FRMImm = MI.getOperand(RoundModeIdx).getImm(); + continue; + } + + int FRMIdx = RISCVII::getFRMOpNum(MI.getDesc()); + if (FRMIdx < 0) + continue; - // The value is a hint to this pass to not alter the frm value. - if (FRMImm == RISCVFPRndMode::DYN) - continue; + unsigned FRMImm = MI.getOperand(FRMIdx).getImm(); - Changed = true; + // The value is a hint to this pass to not alter the frm value. + if (FRMImm == RISCVFPRndMode::DYN) + continue; - // Save - MachineRegisterInfo *MRI = &MBB.getParent()->getRegInfo(); - Register SavedFRM = MRI->createVirtualRegister(&RISCV::GPRRegClass); - BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::SwapFRMImm), - SavedFRM) - .addImm(FRMImm); - MI.addOperand(MachineOperand::CreateReg(RISCV::FRM, /*IsDef*/ false, - /*IsImp*/ true)); - // Restore - MachineInstrBuilder MIB = - BuildMI(*MBB.getParent(), {}, TII->get(RISCV::WriteFRM)) - .addReg(SavedFRM); - MBB.insertAfter(MI, MIB); - } + Changed = true; + + // Save + MachineRegisterInfo *MRI = &MBB.getParent()->getRegInfo(); + Register SavedFRM = MRI->createVirtualRegister(&RISCV::GPRRegClass); + BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::SwapFRMImm), + SavedFRM) + .addImm(FRMImm); + MI.addOperand(MachineOperand::CreateReg(RISCV::FRM, /*IsDef*/ false, + /*IsImp*/ true)); + // Restore + MachineInstrBuilder MIB = + BuildMI(*MBB.getParent(), {}, TII->get(RISCV::WriteFRM)) + .addReg(SavedFRM); + MBB.insertAfter(MI, MIB); } return Changed; }