Skip to content

Commit

Permalink
[RISCV] Separate hasRoundModeOpNum into separate VXRM and FRM functions.
Browse files Browse the repository at this point in the history
Preparation for developing a new rounding mode insertion algorithm
that is going to be different between them since VXRM doesn't need
to be save/restored.

This also unifies the FRM handling in RISCVISelLowering.cpp between
scalar and vector.

Fixes outdated comments in RISCVAsmPrinter and sorts the predicate
function by the reverse order of the operands being skipped.

Reviewed By: eopXD

Differential Revision: https://reviews.llvm.org/D158326
  • Loading branch information
topperc committed Aug 21, 2023
1 parent 46d2d75 commit b441fd6
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 58 deletions.
43 changes: 29 additions & 14 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,20 +175,6 @@ static inline bool hasRoundModeOp(uint64_t TSFlags) {
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; }

Expand Down Expand Up @@ -217,6 +203,35 @@ static inline unsigned getVecPolicyOpNum(const MCInstrDesc &Desc) {
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
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,13 +779,14 @@ static bool lowerRISCVVMachineInstrToMCInst(const MachineInstr *MI,
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;

Expand Down
22 changes: 7 additions & 15 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14925,22 +14925,14 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,

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.
Expand Down
54 changes: 28 additions & 26 deletions llvm/lib/Target/RISCV/RISCVInsertReadWriteCSR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,42 +64,44 @@ INITIALIZE_PASS(RISCVInsertReadWriteCSR, DEBUG_TYPE,
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;

BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::WriteVXRMImm))
.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;
}
Expand Down

0 comments on commit b441fd6

Please sign in to comment.