Skip to content

Commit 054a7ad

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 f988002 commit 054a7ad

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
@@ -27079,9 +27079,6 @@ AArch64TargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
2707927079
unsigned Size = AI->getType()->getPrimitiveSizeInBits();
2708027080
assert(Size <= 128 && "AtomicExpandPass should've handled larger sizes.");
2708127081

27082-
if (AI->isFloatingPointOperation())
27083-
return AtomicExpansionKind::CmpXChg;
27084-
2708527082
bool CanUseLSE128 = Subtarget->hasLSE128() && Size == 128 &&
2708627083
(AI->getOperation() == AtomicRMWInst::Xchg ||
2708727084
AI->getOperation() == AtomicRMWInst::Or ||
@@ -27091,7 +27088,8 @@ AArch64TargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
2709127088

2709227089
// Nand is not supported in LSE.
2709327090
// Leave 128 bits to LLSC or CmpXChg.
27094-
if (AI->getOperation() != AtomicRMWInst::Nand && Size < 128) {
27091+
if (AI->getOperation() != AtomicRMWInst::Nand && Size < 128 &&
27092+
!AI->isFloatingPointOperation()) {
2709527093
if (Subtarget->hasLSE())
2709627094
return AtomicExpansionKind::None;
2709727095
if (Subtarget->outlineAtomics()) {
@@ -27164,10 +27162,14 @@ Value *AArch64TargetLowering::emitLoadLinked(IRBuilderBase &Builder,
2716427162

2716527163
Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
2716627164
Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
27167-
Lo = Builder.CreateZExt(Lo, ValueTy, "lo64");
27168-
Hi = Builder.CreateZExt(Hi, ValueTy, "hi64");
27169-
return Builder.CreateOr(
27170-
Lo, Builder.CreateShl(Hi, ConstantInt::get(ValueTy, 64)), "val64");
27165+
27166+
auto *Int128Ty = Type::getInt128Ty(Builder.getContext());
27167+
Lo = Builder.CreateZExt(Lo, Int128Ty, "lo64");
27168+
Hi = Builder.CreateZExt(Hi, Int128Ty, "hi64");
27169+
27170+
Value *Or = Builder.CreateOr(
27171+
Lo, Builder.CreateShl(Hi, ConstantInt::get(Int128Ty, 64)), "val64");
27172+
return Builder.CreateBitCast(Or, ValueTy);
2717127173
}
2717227174

2717327175
Type *Tys[] = { Addr->getType() };
@@ -27178,8 +27180,8 @@ Value *AArch64TargetLowering::emitLoadLinked(IRBuilderBase &Builder,
2717827180
const DataLayout &DL = M->getDataLayout();
2717927181
IntegerType *IntEltTy = Builder.getIntNTy(DL.getTypeSizeInBits(ValueTy));
2718027182
CallInst *CI = Builder.CreateCall(Ldxr, Addr);
27181-
CI->addParamAttr(
27182-
0, Attribute::get(Builder.getContext(), Attribute::ElementType, ValueTy));
27183+
CI->addParamAttr(0, Attribute::get(Builder.getContext(),
27184+
Attribute::ElementType, IntEltTy));
2718327185
Value *Trunc = Builder.CreateTrunc(CI, IntEltTy);
2718427186

2718527187
return Builder.CreateBitCast(Trunc, ValueTy);
@@ -27205,9 +27207,13 @@ Value *AArch64TargetLowering::emitStoreConditional(IRBuilderBase &Builder,
2720527207
IsRelease ? Intrinsic::aarch64_stlxp : Intrinsic::aarch64_stxp;
2720627208
Function *Stxr = Intrinsic::getDeclaration(M, Int);
2720727209
Type *Int64Ty = Type::getInt64Ty(M->getContext());
27210+
Type *Int128Ty = Type::getInt128Ty(M->getContext());
27211+
27212+
Value *CastVal = Builder.CreateBitCast(Val, Int128Ty);
2720827213

27209-
Value *Lo = Builder.CreateTrunc(Val, Int64Ty, "lo");
27210-
Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 64), Int64Ty, "hi");
27214+
Value *Lo = Builder.CreateTrunc(CastVal, Int64Ty, "lo");
27215+
Value *Hi =
27216+
Builder.CreateTrunc(Builder.CreateLShr(CastVal, 64), Int64Ty, "hi");
2721127217
return Builder.CreateCall(Stxr, {Lo, Hi, Addr});
2721227218
}
2721327219

0 commit comments

Comments
 (0)