Skip to content

Commit 74f93aa

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 dcb7a69 commit 74f93aa

File tree

6 files changed

+2006
-4
lines changed

6 files changed

+2006
-4
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

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

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

27842+
// Add support for LDFADD and friends
27843+
bool CanUseAtomicFP =
27844+
Subtarget->hasLSFE() && (AI->getOperation() == AtomicRMWInst::FAdd ||
27845+
AI->getOperation() == AtomicRMWInst::FMax ||
27846+
AI->getOperation() == AtomicRMWInst::FMin);
27847+
if (CanUseAtomicFP)
27848+
return AtomicExpansionKind::None;
27849+
2782827850
// Nand is not supported in LSE.
2782927851
// Leave 128 bits to LLSC or CmpXChg.
2783027852
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
@@ -12474,6 +12474,32 @@ multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
1247412474
(i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
1247512475
}
1247612476

12477+
let Predicates = [HasLSFE] in
12478+
multiclass LDFPOPregister_patterns_ord_dag<string inst, string suffix, string op,
12479+
ValueType vt, dag SrcRHS, dag DstRHS> {
12480+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") FPR64:$Rn, SrcRHS),
12481+
(!cast<Instruction>(inst # suffix) DstRHS, FPR64:$Rn)>;
12482+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") FPR64:$Rn, SrcRHS),
12483+
(!cast<Instruction>(inst # "A" # suffix) DstRHS, FPR64:$Rn)>;
12484+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") FPR64:$Rn, SrcRHS),
12485+
(!cast<Instruction>(inst # "L" # suffix) DstRHS, FPR64:$Rn)>;
12486+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") FPR64:$Rn, SrcRHS),
12487+
(!cast<Instruction>(inst # "AL" # suffix) DstRHS, FPR64:$Rn)>;
12488+
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") FPR64:$Rn, SrcRHS),
12489+
(!cast<Instruction>(inst # "AL" # suffix) DstRHS, FPR64:$Rn)>;
12490+
}
12491+
12492+
multiclass LDFPOPregister_patterns_ord<string inst, string suffix, string op,
12493+
ValueType vt, dag RHS> {
12494+
defm : LDFPOPregister_patterns_ord_dag<inst, suffix, op, vt, RHS, RHS>;
12495+
}
12496+
12497+
multiclass LDFPOPregister_patterns<string inst, string op> {
12498+
defm : LDFPOPregister_patterns_ord<inst, "H", op, f16, (f16 FPR16:$Rm)>;
12499+
defm : LDFPOPregister_patterns_ord<inst, "S", op, f32, (f32 FPR32:$Rm)>;
12500+
defm : LDFPOPregister_patterns_ord<inst, "D", op, f64, (f64 FPR64:$Rm)>;
12501+
}
12502+
1247712503
let Predicates = [HasLSE] in
1247812504
multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
1247912505
ValueType vt, dag OLD, dag NEW> {

0 commit comments

Comments
 (0)