Skip to content

Commit 21d6ac7

Browse files
committed
[AArch64] Add support for 16/32/64-bit floating-point atomic read-modify-write ops
Add support for 16/32/64-bit floating-point atomic read-modify-write operations (FADD, FMAX, FMIN) using LDFADD, LDFMAX, LDFMIN atomic instructions.
1 parent 563d545 commit 21d6ac7

File tree

6 files changed

+261
-2192
lines changed

6 files changed

+261
-2192
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,20 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
975975
#undef LCALLNAME5
976976
}
977977

978+
if (Subtarget->outlineAtomics() && !Subtarget->hasLSFE()) {
979+
setOperationAction(ISD::ATOMIC_LOAD_FADD, MVT::f16, LibCall);
980+
setOperationAction(ISD::ATOMIC_LOAD_FADD, MVT::f32, LibCall);
981+
setOperationAction(ISD::ATOMIC_LOAD_FADD, MVT::f64, LibCall);
982+
983+
setOperationAction(ISD::ATOMIC_LOAD_FMAX, MVT::f16, LibCall);
984+
setOperationAction(ISD::ATOMIC_LOAD_FMAX, MVT::f32, LibCall);
985+
setOperationAction(ISD::ATOMIC_LOAD_FMAX, MVT::f64, LibCall);
986+
987+
setOperationAction(ISD::ATOMIC_LOAD_FMIN, MVT::f16, LibCall);
988+
setOperationAction(ISD::ATOMIC_LOAD_FMIN, MVT::f32, LibCall);
989+
setOperationAction(ISD::ATOMIC_LOAD_FMIN, MVT::f64, LibCall);
990+
}
991+
978992
if (Subtarget->hasLSE128()) {
979993
// Custom lowering because i128 is not legal. Must be replaced by 2x64
980994
// values. ATOMIC_LOAD_AND also needs op legalisation to emit LDCLRP.
@@ -27831,6 +27845,14 @@ AArch64TargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
2783127845
if (CanUseLSE128)
2783227846
return AtomicExpansionKind::None;
2783327847

27848+
// Add support for LDFADD and friends
27849+
bool CanUseAtomicFP =
27850+
Subtarget->hasLSFE() && (AI->getOperation() == AtomicRMWInst::FAdd ||
27851+
AI->getOperation() == AtomicRMWInst::FMax ||
27852+
AI->getOperation() == AtomicRMWInst::FMin);
27853+
if (CanUseAtomicFP)
27854+
return AtomicExpansionKind::None;
27855+
2783427856
// Nand is not supported in LSE.
2783527857
// Leave 128 bits to LLSC or CmpXChg.
2783627858
if (AI->getOperation() != AtomicRMWInst::Nand && Size < 128 &&

llvm/lib/Target/AArch64/AArch64InstrAtomics.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,16 @@ let Predicates = [HasLSE] in {
543543
defm : LDOPregister_patterns_mod<"LDCLR", "atomic_load_and", "ORN">;
544544
}
545545

546+
defm atomic_load_fadd : binary_atomic_op_fp<atomic_load_fadd>;
547+
defm atomic_load_fmin : binary_atomic_op_fp<atomic_load_fmin>;
548+
defm atomic_load_fmax : binary_atomic_op_fp<atomic_load_fmax>;
549+
550+
let Predicates = [HasLSFE] in {
551+
defm : LDFPOPregister_patterns<"LDFADD", "atomic_load_fadd">;
552+
defm : LDFPOPregister_patterns<"LDFMAX", "atomic_load_fmax">;
553+
defm : LDFPOPregister_patterns<"LDFMIN", "atomic_load_fmin">;
554+
}
555+
546556
// v8.9a/v9.4a FEAT_LRCPC patterns
547557
let Predicates = [HasRCPC3, HasNEON] in {
548558
// LDAP1 loads

llvm/lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12483,6 +12483,32 @@ multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
1248312483
(i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
1248412484
}
1248512485

12486+
let Predicates = [HasLSFE] in
12487+
multiclass LDFPOPregister_patterns_ord_dag<string inst, string suffix, string op,
12488+
ValueType vt, dag SrcRHS, dag DstRHS> {
12489+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") FPR64:$Rn, SrcRHS),
12490+
(!cast<Instruction>(inst # suffix) DstRHS, FPR64:$Rn)>;
12491+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") FPR64:$Rn, SrcRHS),
12492+
(!cast<Instruction>(inst # "A" # suffix) DstRHS, FPR64:$Rn)>;
12493+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") FPR64:$Rn, SrcRHS),
12494+
(!cast<Instruction>(inst # "L" # suffix) DstRHS, FPR64:$Rn)>;
12495+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") FPR64:$Rn, SrcRHS),
12496+
(!cast<Instruction>(inst # "AL" # suffix) DstRHS, FPR64:$Rn)>;
12497+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") FPR64:$Rn, SrcRHS),
12498+
(!cast<Instruction>(inst # "AL" # suffix) DstRHS, FPR64:$Rn)>;
12499+
}
12500+
12501+
multiclass LDFPOPregister_patterns_ord<string inst, string suffix, string op,
12502+
ValueType vt, dag RHS> {
12503+
defm : LDFPOPregister_patterns_ord_dag<inst, suffix, op, vt, RHS, RHS>;
12504+
}
12505+
12506+
multiclass LDFPOPregister_patterns<string inst, string op> {
12507+
defm : LDFPOPregister_patterns_ord<inst, "H", op, f16, (f16 FPR16:$Rm)>;
12508+
defm : LDFPOPregister_patterns_ord<inst, "S", op, f32, (f32 FPR32:$Rm)>;
12509+
defm : LDFPOPregister_patterns_ord<inst, "D", op, f64, (f64 FPR64:$Rm)>;
12510+
}
12511+
1248612512
let Predicates = [HasLSE] in
1248712513
multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
1248812514
ValueType vt, dag OLD, dag NEW> {

0 commit comments

Comments
 (0)