Skip to content

Commit 0f25140

Browse files
committed
[RISCV][ISel] Add codegen support for the experimental zabha extension
1 parent 0c36127 commit 0f25140

File tree

7 files changed

+11436
-4075
lines changed

7 files changed

+11436
-4075
lines changed

llvm/docs/RISCVUsage.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ LLVM supports (to various degrees) a number of experimental extensions. All exp
227227
The primary goal of experimental support is to assist in the process of ratification by providing an existence proof of an implementation, and simplifying efforts to validate the value of a proposed extension against large code bases. Experimental extensions are expected to either transition to ratified status, or be eventually removed. The decision on whether to accept an experimental extension is currently done on an entirely case by case basis; if you want to propose one, attending the bi-weekly RISC-V sync-up call is strongly advised.
228228

229229
``experimental-zabha``
230-
LLVM implements assembler support for the `v1.0-rc1 draft specification <https://github.com/riscv/riscv-zabha/tree/v1.0-rc1>`_.
230+
LLVM implements the `v1.0-rc1 draft specification <https://github.com/riscv/riscv-zabha/tree/v1.0-rc1>`_.
231231

232232
``experimental-zacas``
233233
LLVM implements the `1.0-rc1 draft specification <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc1>`_.

llvm/docs/ReleaseNotes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Changes to the RISC-V Backend
9393
-----------------------------
9494

9595
* Support for the Zicond extension is no longer experimental.
96-
* Added assembler/disassembler support for the experimental Zabha (Byte and Halfword Atomic Memory Operations) extension.
96+
* Added full support for the experimental Zabha (Byte and Halfword Atomic Memory Operations) extension.
9797

9898
Changes to the WebAssembly Backend
9999
----------------------------------

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,10 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
629629

630630
if (Subtarget.hasStdExtA()) {
631631
setMaxAtomicSizeInBitsSupported(Subtarget.getXLen());
632-
setMinCmpXchgSizeInBits(32);
632+
if (Subtarget.hasStdExtZabha())
633+
setMinCmpXchgSizeInBits(8);
634+
else
635+
setMinCmpXchgSizeInBits(32);
633636
} else if (Subtarget.hasForcedAtomics()) {
634637
setMaxAtomicSizeInBitsSupported(Subtarget.getXLen());
635638
} else {
@@ -19512,8 +19515,13 @@ RISCVTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
1951219515
return AtomicExpansionKind::None;
1951319516

1951419517
unsigned Size = AI->getType()->getPrimitiveSizeInBits();
19515-
if (Size == 8 || Size == 16)
19516-
return AtomicExpansionKind::MaskedIntrinsic;
19518+
if (Size == 8 || Size == 16) {
19519+
if (!Subtarget.hasStdExtZabha())
19520+
return AtomicExpansionKind::MaskedIntrinsic;
19521+
if (AI->getOperation() == AtomicRMWInst::Nand)
19522+
return Subtarget.hasStdExtZacas() ? AtomicExpansionKind::CmpXChg
19523+
: AtomicExpansionKind::MaskedIntrinsic;
19524+
}
1951719525

1951819526
if (Subtarget.hasStdExtZacas() && AI->getOperation() == AtomicRMWInst::Nand &&
1951919527
(Size == Subtarget.getXLen() || Size == 32))
@@ -19627,6 +19635,8 @@ Value *RISCVTargetLowering::emitMaskedAtomicRMWIntrinsic(
1962719635
Builder.CreateCall(LrwOpScwLoop, {AlignedAddr, Incr, Mask, Ordering});
1962819636
}
1962919637

19638+
if (Subtarget.hasStdExtZabha())
19639+
return Builder.CreateTrunc(Result, AI->getValOperand()->getType());
1963019640
if (XLen == 64)
1963119641
Result = Builder.CreateTrunc(Result, Builder.getInt32Ty());
1963219642
return Result;
@@ -19640,7 +19650,8 @@ RISCVTargetLowering::shouldExpandAtomicCmpXchgInIR(
1964019650
return AtomicExpansionKind::None;
1964119651

1964219652
unsigned Size = CI->getCompareOperand()->getType()->getPrimitiveSizeInBits();
19643-
if (Size == 8 || Size == 16)
19653+
if (!(Subtarget.hasStdExtZabha() && Subtarget.hasStdExtZacas()) &&
19654+
(Size == 8 || Size == 16))
1964419655
return AtomicExpansionKind::MaskedIntrinsic;
1964519656
return AtomicExpansionKind::None;
1964619657
}
@@ -19662,6 +19673,9 @@ Value *RISCVTargetLowering::emitMaskedAtomicCmpXchgIntrinsic(
1966219673
Intrinsic::getDeclaration(CI->getModule(), CmpXchgIntrID, Tys);
1966319674
Value *Result = Builder.CreateCall(
1966419675
MaskedCmpXchg, {AlignedAddr, CmpVal, NewVal, Mask, Ordering});
19676+
19677+
if (Subtarget.hasStdExtZabha())
19678+
return Builder.CreateTrunc(Result, CI->getCompareOperand()->getType());
1966519679
if (XLen == 64)
1966619680
Result = Builder.CreateTrunc(Result, Builder.getInt32Ty());
1966719681
return Result;

llvm/lib/Target/RISCV/RISCVInstrInfoZa.td

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,30 @@ let Predicates = [HasStdExtZabha, HasStdExtZacas] in {
185185
defm AMOCAS_B : AMO_cas_aq_rl<0b00101, 0b000, "amocas.b", GPR>;
186186
defm AMOCAS_H : AMO_cas_aq_rl<0b00101, 0b001, "amocas.h", GPR>;
187187
}
188+
189+
/// AMOs
190+
191+
defm : AMOPat<"atomic_swap_8", "AMOSWAP_B", XLenVT, [HasStdExtZabha]>;
192+
defm : AMOPat<"atomic_load_add_8", "AMOADD_B", XLenVT, [HasStdExtZabha]>;
193+
defm : AMOPat<"atomic_load_and_8", "AMOAND_B", XLenVT, [HasStdExtZabha]>;
194+
defm : AMOPat<"atomic_load_or_8", "AMOOR_B", XLenVT, [HasStdExtZabha]>;
195+
defm : AMOPat<"atomic_load_xor_8", "AMOXOR_B", XLenVT, [HasStdExtZabha]>;
196+
defm : AMOPat<"atomic_load_max_8", "AMOMAX_B", XLenVT, [HasStdExtZabha]>;
197+
defm : AMOPat<"atomic_load_min_8", "AMOMIN_B", XLenVT, [HasStdExtZabha]>;
198+
defm : AMOPat<"atomic_load_umax_8", "AMOMAXU_B", XLenVT, [HasStdExtZabha]>;
199+
defm : AMOPat<"atomic_load_umin_8", "AMOMINU_B", XLenVT, [HasStdExtZabha]>;
200+
201+
defm : AMOPat<"atomic_swap_16", "AMOSWAP_H", XLenVT, [HasStdExtZabha]>;
202+
defm : AMOPat<"atomic_load_add_16", "AMOADD_H", XLenVT, [HasStdExtZabha]>;
203+
defm : AMOPat<"atomic_load_and_16", "AMOAND_H", XLenVT, [HasStdExtZabha]>;
204+
defm : AMOPat<"atomic_load_or_16", "AMOOR_H", XLenVT, [HasStdExtZabha]>;
205+
defm : AMOPat<"atomic_load_xor_16", "AMOXOR_H", XLenVT, [HasStdExtZabha]>;
206+
defm : AMOPat<"atomic_load_max_16", "AMOMAX_H", XLenVT, [HasStdExtZabha]>;
207+
defm : AMOPat<"atomic_load_min_16", "AMOMIN_H", XLenVT, [HasStdExtZabha]>;
208+
defm : AMOPat<"atomic_load_umax_16", "AMOMAXU_H", XLenVT, [HasStdExtZabha]>;
209+
defm : AMOPat<"atomic_load_umin_16", "AMOMINU_H", XLenVT, [HasStdExtZabha]>;
210+
211+
/// AMOCAS
212+
213+
defm : AMOCASPat<"atomic_cmp_swap_8", "AMOCAS_B", XLenVT, [HasStdExtZabha]>;
214+
defm : AMOCASPat<"atomic_cmp_swap_16", "AMOCAS_H", XLenVT, [HasStdExtZabha]>;

llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
; RUN: | FileCheck -check-prefixes=NOZACAS,RV64IA %s
88
; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-zacas -verify-machineinstrs < %s \
99
; RUN: | FileCheck -check-prefixes=ZACAS,RV64IA-ZACAS %s
10+
; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-zacas,+experimental-zabha -verify-machineinstrs < %s \
11+
; RUN: | FileCheck -check-prefixes=ZACAS,RV64IA-ZABHA %s
1012

1113
; Test cmpxchg followed by a branch on the cmpxchg success value to see if the
1214
; branch is folded into the cmpxchg expansion.
@@ -209,6 +211,16 @@ define void @cmpxchg_masked_and_branch1(ptr %ptr, i8 signext %cmp, i8 signext %v
209211
; RV64IA-ZACAS-NEXT: # %bb.5: # %do_cmpxchg
210212
; RV64IA-ZACAS-NEXT: # %bb.2: # %exit
211213
; RV64IA-ZACAS-NEXT: ret
214+
;
215+
; RV64IA-ZABHA-LABEL: cmpxchg_masked_and_branch1:
216+
; RV64IA-ZABHA: # %bb.0: # %entry
217+
; RV64IA-ZABHA-NEXT: .LBB2_1: # %do_cmpxchg
218+
; RV64IA-ZABHA-NEXT: # =>This Inner Loop Header: Depth=1
219+
; RV64IA-ZABHA-NEXT: mv a3, a1
220+
; RV64IA-ZABHA-NEXT: amocas.b.aqrl a3, a2, (a0)
221+
; RV64IA-ZABHA-NEXT: bne a3, a1, .LBB2_1
222+
; RV64IA-ZABHA-NEXT: # %bb.2: # %exit
223+
; RV64IA-ZABHA-NEXT: ret
212224
entry:
213225
br label %do_cmpxchg
214226
do_cmpxchg:
@@ -351,6 +363,16 @@ define void @cmpxchg_masked_and_branch2(ptr %ptr, i8 signext %cmp, i8 signext %v
351363
; RV64IA-ZACAS-NEXT: beq a1, a4, .LBB3_1
352364
; RV64IA-ZACAS-NEXT: # %bb.2: # %exit
353365
; RV64IA-ZACAS-NEXT: ret
366+
;
367+
; RV64IA-ZABHA-LABEL: cmpxchg_masked_and_branch2:
368+
; RV64IA-ZABHA: # %bb.0: # %entry
369+
; RV64IA-ZABHA-NEXT: .LBB3_1: # %do_cmpxchg
370+
; RV64IA-ZABHA-NEXT: # =>This Inner Loop Header: Depth=1
371+
; RV64IA-ZABHA-NEXT: mv a3, a1
372+
; RV64IA-ZABHA-NEXT: amocas.b.aqrl a3, a2, (a0)
373+
; RV64IA-ZABHA-NEXT: beq a3, a1, .LBB3_1
374+
; RV64IA-ZABHA-NEXT: # %bb.2: # %exit
375+
; RV64IA-ZABHA-NEXT: ret
354376
entry:
355377
br label %do_cmpxchg
356378
do_cmpxchg:

0 commit comments

Comments
 (0)