Skip to content

Commit 3c1ef5c

Browse files
committed
AArch64: Use consistent atomicrmw expansion for FP operations
Use LLSC or cmpxchg in the same cases as for the unsupported integer operations. This required some fixups to the LLSC implementatation to deal with the fp128 case.
1 parent 38ce457 commit 3c1ef5c

File tree

5 files changed

+420
-1230
lines changed

5 files changed

+420
-1230
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27067,9 +27067,6 @@ AArch64TargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
2706727067
unsigned Size = AI->getType()->getPrimitiveSizeInBits();
2706827068
assert(Size <= 128 && "AtomicExpandPass should've handled larger sizes.");
2706927069

27070-
if (AI->isFloatingPointOperation())
27071-
return AtomicExpansionKind::CmpXChg;
27072-
2707327070
bool CanUseLSE128 = Subtarget->hasLSE128() && Size == 128 &&
2707427071
(AI->getOperation() == AtomicRMWInst::Xchg ||
2707527072
AI->getOperation() == AtomicRMWInst::Or ||
@@ -27079,7 +27076,8 @@ AArch64TargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
2707927076

2708027077
// Nand is not supported in LSE.
2708127078
// Leave 128 bits to LLSC or CmpXChg.
27082-
if (AI->getOperation() != AtomicRMWInst::Nand && Size < 128) {
27079+
if (AI->getOperation() != AtomicRMWInst::Nand && Size < 128 &&
27080+
!AI->isFloatingPointOperation()) {
2708327081
if (Subtarget->hasLSE())
2708427082
return AtomicExpansionKind::None;
2708527083
if (Subtarget->outlineAtomics()) {
@@ -27152,10 +27150,14 @@ Value *AArch64TargetLowering::emitLoadLinked(IRBuilderBase &Builder,
2715227150

2715327151
Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
2715427152
Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
27155-
Lo = Builder.CreateZExt(Lo, ValueTy, "lo64");
27156-
Hi = Builder.CreateZExt(Hi, ValueTy, "hi64");
27157-
return Builder.CreateOr(
27158-
Lo, Builder.CreateShl(Hi, ConstantInt::get(ValueTy, 64)), "val64");
27153+
27154+
auto *Int128Ty = Type::getInt128Ty(Builder.getContext());
27155+
Lo = Builder.CreateZExt(Lo, Int128Ty, "lo64");
27156+
Hi = Builder.CreateZExt(Hi, Int128Ty, "hi64");
27157+
27158+
Value *Or = Builder.CreateOr(
27159+
Lo, Builder.CreateShl(Hi, ConstantInt::get(Int128Ty, 64)), "val64");
27160+
return Builder.CreateBitCast(Or, ValueTy);
2715927161
}
2716027162

2716127163
Type *Tys[] = { Addr->getType() };
@@ -27166,8 +27168,8 @@ Value *AArch64TargetLowering::emitLoadLinked(IRBuilderBase &Builder,
2716627168
const DataLayout &DL = M->getDataLayout();
2716727169
IntegerType *IntEltTy = Builder.getIntNTy(DL.getTypeSizeInBits(ValueTy));
2716827170
CallInst *CI = Builder.CreateCall(Ldxr, Addr);
27169-
CI->addParamAttr(
27170-
0, Attribute::get(Builder.getContext(), Attribute::ElementType, ValueTy));
27171+
CI->addParamAttr(0, Attribute::get(Builder.getContext(),
27172+
Attribute::ElementType, IntEltTy));
2717127173
Value *Trunc = Builder.CreateTrunc(CI, IntEltTy);
2717227174

2717327175
return Builder.CreateBitCast(Trunc, ValueTy);
@@ -27193,9 +27195,13 @@ Value *AArch64TargetLowering::emitStoreConditional(IRBuilderBase &Builder,
2719327195
IsRelease ? Intrinsic::aarch64_stlxp : Intrinsic::aarch64_stxp;
2719427196
Function *Stxr = Intrinsic::getDeclaration(M, Int);
2719527197
Type *Int64Ty = Type::getInt64Ty(M->getContext());
27198+
Type *Int128Ty = Type::getInt128Ty(M->getContext());
27199+
27200+
Value *CastVal = Builder.CreateBitCast(Val, Int128Ty);
2719627201

27197-
Value *Lo = Builder.CreateTrunc(Val, Int64Ty, "lo");
27198-
Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 64), Int64Ty, "hi");
27202+
Value *Lo = Builder.CreateTrunc(CastVal, Int64Ty, "lo");
27203+
Value *Hi =
27204+
Builder.CreateTrunc(Builder.CreateLShr(CastVal, 64), Int64Ty, "hi");
2719927205
return Builder.CreateCall(Stxr, {Lo, Hi, Addr});
2720027206
}
2720127207

0 commit comments

Comments
 (0)