Skip to content

Commit 67399ff

Browse files
committed
[RISCV][LLVM] Atomic load min/max pseudo expansion
When the 'Zbb' extension is present it provides min(u)/max(u) instructions. Use these if available in the 'Zalrsc' atomic load min/max pseudo expansions, since they result in smaller and faster code. When 'Zbb' is not present continue to use the longer branch based expansion path.
1 parent b6180fd commit 67399ff

File tree

2 files changed

+8719
-0
lines changed

2 files changed

+8719
-0
lines changed

llvm/lib/Target/RISCV/RISCVExpandAtomicPseudoInsts.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ static void doAtomicBinOpExpansion(const RISCVInstrInfo *TII, MachineInstr &MI,
324324
Register ScratchReg = MI.getOperand(1).getReg();
325325
Register AddrReg = MI.getOperand(2).getReg();
326326
Register IncrReg = MI.getOperand(3).getReg();
327+
bool IsUnsigned = BinOp == AtomicRMWInst::UMin ||
328+
BinOp == AtomicRMWInst::UMax;
329+
bool Zext = IsUnsigned && STI->is64Bit() && Width == 32;
327330
AtomicOrdering Ordering =
328331
static_cast<AtomicOrdering>(MI.getOperand(4).getImm());
329332

@@ -375,6 +378,34 @@ static void doAtomicBinOpExpansion(const RISCVInstrInfo *TII, MachineInstr &MI,
375378
.addReg(ScratchReg)
376379
.addImm(-1);
377380
break;
381+
case AtomicRMWInst::Min:
382+
BuildMI(LoopMBB, DL, TII->get(RISCV::MIN), ScratchReg)
383+
.addReg(DestReg)
384+
.addReg(IncrReg);
385+
break;
386+
case AtomicRMWInst::Max:
387+
BuildMI(LoopMBB, DL, TII->get(RISCV::MAX), ScratchReg)
388+
.addReg(DestReg)
389+
.addReg(IncrReg);
390+
break;
391+
case AtomicRMWInst::UMin:
392+
if (Zext)
393+
BuildMI(LoopMBB, DL, TII->get(RISCV::ADD_UW), ScratchReg)
394+
.addReg(DestReg)
395+
.addReg(RISCV::X0);
396+
BuildMI(LoopMBB, DL, TII->get(RISCV::MINU), ScratchReg)
397+
.addReg(Zext ? ScratchReg : DestReg)
398+
.addReg(IncrReg);
399+
break;
400+
case AtomicRMWInst::UMax:
401+
if (Zext)
402+
BuildMI(LoopMBB, DL, TII->get(RISCV::ADD_UW), ScratchReg)
403+
.addReg(DestReg)
404+
.addReg(RISCV::X0);
405+
BuildMI(LoopMBB, DL, TII->get(RISCV::MAXU), ScratchReg)
406+
.addReg(Zext ? ScratchReg : DestReg)
407+
.addReg(IncrReg);
408+
break;
378409
}
379410
BuildMI(LoopMBB, DL, TII->get(getSCForRMW(Ordering, Width, STI)), ScratchReg)
380411
.addReg(ScratchReg)
@@ -705,6 +736,10 @@ bool RISCVExpandAtomicPseudo::expandAtomicMinMaxOp(
705736
AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width,
706737
MachineBasicBlock::iterator &NextMBBI) {
707738

739+
// Prefer expansion using MIN/MAX/MINU/MAXU instructions if available
740+
if (STI->hasStdExtZbb() && !IsMasked)
741+
return expandAtomicBinOp(MBB, MBBI, BinOp, IsMasked, Width, NextMBBI);
742+
708743
MachineInstr &MI = *MBBI;
709744
DebugLoc DL = MI.getDebugLoc();
710745
MachineFunction *MF = MBB.getParent();

0 commit comments

Comments
 (0)