Skip to content

Commit 7a1867b

Browse files
committed
[RISCV] 'Zalrsc' may permit non-base instructions
Provide shorter atomic LR/SC sequences with non-base instructions (eg. ''B'' extension instructions) when implementations opt in to FeaturePermissiveZalrsc. Currently this shortens `atomicrmw {min,max,umin,umax}` pseudo expansions. There is no functional change for machines when this target feature is not requested.
1 parent 0b01b96 commit 7a1867b

File tree

3 files changed

+1113
-0
lines changed

3 files changed

+1113
-0
lines changed

llvm/lib/Target/RISCV/RISCVExpandAtomicPseudoInsts.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,26 @@ static void doAtomicBinOpExpansion(const RISCVInstrInfo *TII, MachineInstr &MI,
373373
.addReg(ScratchReg)
374374
.addImm(-1);
375375
break;
376+
case AtomicRMWInst::Max:
377+
BuildMI(LoopMBB, DL, TII->get(RISCV::MAX), ScratchReg)
378+
.addReg(DestReg)
379+
.addReg(IncrReg);
380+
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::UMax:
387+
BuildMI(LoopMBB, DL, TII->get(RISCV::MAXU), ScratchReg)
388+
.addReg(DestReg)
389+
.addReg(IncrReg);
390+
break;
391+
case AtomicRMWInst::UMin:
392+
BuildMI(LoopMBB, DL, TII->get(RISCV::MINU), ScratchReg)
393+
.addReg(DestReg)
394+
.addReg(IncrReg);
395+
break;
376396
}
377397
BuildMI(LoopMBB, DL, TII->get(getSCForRMW(Ordering, Width, STI)), ScratchReg)
378398
.addReg(ScratchReg)
@@ -682,6 +702,9 @@ bool RISCVExpandAtomicPseudo::expandAtomicMinMaxOp(
682702
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
683703
AtomicRMWInst::BinOp BinOp, bool IsMasked, int Width,
684704
MachineBasicBlock::iterator &NextMBBI) {
705+
// Using MIN(U)/MAX(U) is preferrable if permitted
706+
if (STI->hasPermissiveZalrsc() && STI->hasStdExtZbb() && !IsMasked)
707+
return expandAtomicBinOp(MBB, MBBI, BinOp, IsMasked, Width, NextMBBI);
685708

686709
MachineInstr &MI = *MBBI;
687710
DebugLoc DL = MI.getDebugLoc();

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,6 +1906,22 @@ def FeatureForcedAtomics : SubtargetFeature<
19061906
def HasAtomicLdSt
19071907
: Predicate<"Subtarget->hasStdExtZalrsc() || Subtarget->hasForcedAtomics()">;
19081908

1909+
// The RISCV Unprivileged Architecture defines _constrained_ LR/SC loops:
1910+
// The dynamic code executed between the LR and SC instructions can only
1911+
// contain instructions from the base ''I'' instruction set, excluding loads,
1912+
// stores, backward jumps, taken backward branches, JALR, FENCE, and SYSTEM
1913+
// instructions. Compressed forms of the aforementioned ''I'' instructions in
1914+
// the Zca and Zcb extensions are also permitted.
1915+
// LR/SC loops that do not adhere to the above are _unconstrained_ LR/SC loops,
1916+
// and success is implementation specific. For implementations which know that
1917+
// non-base instructions (such as the ''B'' extension) will not violate any
1918+
// forward progress guarantees, using these instructions to reduce the LR/SC
1919+
// sequence length is desirable.
1920+
def FeaturePermissiveZalrsc
1921+
: SubtargetFeature<
1922+
"permissive-zalrsc", "HasPermissiveZalrsc", "true",
1923+
"Implementation permits non-base instructions between LR/SC pairs">;
1924+
19091925
def FeatureTaggedGlobals : SubtargetFeature<"tagged-globals",
19101926
"AllowTaggedGlobals",
19111927
"true", "Use an instruction sequence for taking the address of a global "

0 commit comments

Comments
 (0)