[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVInsertReadWriteCSR.cpp
blobb807abcc56819bd2ea520bbbfeac12f627503fac
1 //===-- RISCVInsertReadWriteCSR.cpp - Insert Read/Write of RISC-V CSR -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // This file implements the machine function pass to insert read/write of CSR-s
9 // of the RISC-V instructions.
11 // Currently the pass implements:
12 // -Writing and saving frm before an RVV floating-point instruction with a
13 // static rounding mode and restores the value after.
15 //===----------------------------------------------------------------------===//
17 #include "MCTargetDesc/RISCVBaseInfo.h"
18 #include "RISCV.h"
19 #include "RISCVSubtarget.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 using namespace llvm;
23 #define DEBUG_TYPE "riscv-insert-read-write-csr"
24 #define RISCV_INSERT_READ_WRITE_CSR_NAME "RISC-V Insert Read/Write CSR Pass"
26 namespace {
28 class RISCVInsertReadWriteCSR : public MachineFunctionPass {
29 const TargetInstrInfo *TII;
31 public:
32 static char ID;
34 RISCVInsertReadWriteCSR() : MachineFunctionPass(ID) {}
36 bool runOnMachineFunction(MachineFunction &MF) override;
38 void getAnalysisUsage(AnalysisUsage &AU) const override {
39 AU.setPreservesCFG();
40 MachineFunctionPass::getAnalysisUsage(AU);
43 StringRef getPassName() const override {
44 return RISCV_INSERT_READ_WRITE_CSR_NAME;
47 private:
48 bool emitWriteRoundingMode(MachineBasicBlock &MBB);
51 } // end anonymous namespace
53 char RISCVInsertReadWriteCSR::ID = 0;
55 INITIALIZE_PASS(RISCVInsertReadWriteCSR, DEBUG_TYPE,
56 RISCV_INSERT_READ_WRITE_CSR_NAME, false, false)
58 // This function also swaps frm and restores it when encountering an RVV
59 // floating point instruction with a static rounding mode.
60 bool RISCVInsertReadWriteCSR::emitWriteRoundingMode(MachineBasicBlock &MBB) {
61 bool Changed = false;
62 for (MachineInstr &MI : MBB) {
63 int FRMIdx = RISCVII::getFRMOpNum(MI.getDesc());
64 if (FRMIdx < 0)
65 continue;
67 unsigned FRMImm = MI.getOperand(FRMIdx).getImm();
69 // The value is a hint to this pass to not alter the frm value.
70 if (FRMImm == RISCVFPRndMode::DYN)
71 continue;
73 Changed = true;
75 // Save
76 MachineRegisterInfo *MRI = &MBB.getParent()->getRegInfo();
77 Register SavedFRM = MRI->createVirtualRegister(&RISCV::GPRRegClass);
78 BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::SwapFRMImm),
79 SavedFRM)
80 .addImm(FRMImm);
81 MI.addOperand(MachineOperand::CreateReg(RISCV::FRM, /*IsDef*/ false,
82 /*IsImp*/ true));
83 // Restore
84 MachineInstrBuilder MIB =
85 BuildMI(*MBB.getParent(), {}, TII->get(RISCV::WriteFRM))
86 .addReg(SavedFRM);
87 MBB.insertAfter(MI, MIB);
89 return Changed;
92 bool RISCVInsertReadWriteCSR::runOnMachineFunction(MachineFunction &MF) {
93 // Skip if the vector extension is not enabled.
94 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
95 if (!ST.hasVInstructions())
96 return false;
98 TII = ST.getInstrInfo();
100 bool Changed = false;
102 for (MachineBasicBlock &MBB : MF)
103 Changed |= emitWriteRoundingMode(MBB);
105 return Changed;
108 FunctionPass *llvm::createRISCVInsertReadWriteCSRPass() {
109 return new RISCVInsertReadWriteCSR();