[llvm] [RISCV][GlobalISel] Legalize readcyclecounter/readsteadycounter (PR #217535)
Sam Elliott via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 12:02:20 PDT 2026
================
@@ -889,6 +896,106 @@ bool RISCVLegalizerInfo::legalizeVAStart(MachineInstr &MI,
return true;
}
+bool RISCVLegalizerInfo::legalizeReadCounter(
+ MachineInstr &MI, MachineIRBuilder &MIRBuilder,
+ GISelChangeObserver &Observer) const {
+ assert((MI.getOpcode() == TargetOpcode::G_READCYCLECOUNTER ||
+ MI.getOpcode() == TargetOpcode::G_READSTEADYCOUNTER) &&
+ "Unexpected opcode");
+ assert(!STI.is64Bit() && "READCYCLECOUNTER/READSTEADYCOUNTER only "
+ "has custom type legalization on riscv32");
+
+ // On RV32 a 64-bit counter CSR must be read as two 32-bit halves. Because
+ // the count may wrap between the two reads, re-read the high half and loop
+ // until the two high reads agree.
+ int64_t LoCounter, HiCounter;
+ if (MI.getOpcode() == TargetOpcode::G_READCYCLECOUNTER) {
+ LoCounter = RISCVSysReg::cycle;
+ HiCounter = RISCVSysReg::cycleh;
+ } else {
+ LoCounter = RISCVSysReg::time;
+ HiCounter = RISCVSysReg::timeh;
+ }
+
+ MachineBasicBlock *BB = MI.getParent();
+ MachineFunction &MF = *BB->getParent();
+ const BasicBlock *LLVMBB = BB->getBasicBlock();
+ DebugLoc DL = MI.getDebugLoc();
+ MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
+
+ // Split BB into an entry that falls through into a loop block, and a done
+ // block that receives the remainder of BB and its original successors.
+ MachineFunction::iterator It = std::next(BB->getIterator());
----------------
lenary wrote:
That was only introduced because SDag cannot introduce control flow. I think GISel has no such restriction so we can just introduce the control flow directly - @arsenm asked for this change earlier in the review.
https://github.com/llvm/llvm-project/pull/217535
More information about the llvm-commits
mailing list