Skip to content

Commit bb3c18b

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 3fff86f commit bb3c18b

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

27111-
if (AI->isFloatingPointOperation())
27112-
return AtomicExpansionKind::CmpXChg;
27113-
2711427111
bool CanUseLSE128 = Subtarget->hasLSE128() && Size == 128 &&
2711527112
(AI->getOperation() == AtomicRMWInst::Xchg ||
2711627113
AI->getOperation() == AtomicRMWInst::Or ||
@@ -27120,7 +27117,8 @@ AArch64TargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
2712027117

2712127118
// Nand is not supported in LSE.
2712227119
// Leave 128 bits to LLSC or CmpXChg.
27123-
if (AI->getOperation() != AtomicRMWInst::Nand && Size < 128) {
27120+
if (AI->getOperation() != AtomicRMWInst::Nand && Size < 128 &&
27121+
!AI->isFloatingPointOperation()) {
2712427122
if (Subtarget->hasLSE())
2712527123
return AtomicExpansionKind::None;
2712627124
if (Subtarget->outlineAtomics()) {
@@ -27193,10 +27191,14 @@ Value *AArch64TargetLowering::emitLoadLinked(IRBuilderBase &Builder,
2719327191

2719427192
Value *Lo = Builder.CreateExtractValue(LoHi, 0, "lo");
2719527193
Value *Hi = Builder.CreateExtractValue(LoHi, 1, "hi");
27196-
Lo = Builder.CreateZExt(Lo, ValueTy, "lo64");
27197-
Hi = Builder.CreateZExt(Hi, ValueTy, "hi64");
27198-
return Builder.CreateOr(
27199-
Lo, Builder.CreateShl(Hi, ConstantInt::get(ValueTy, 64)), "val64");
27194+
27195+
auto *Int128Ty = Type::getInt128Ty(Builder.getContext());
27196+
Lo = Builder.CreateZExt(Lo, Int128Ty, "lo64");
27197+
Hi = Builder.CreateZExt(Hi, Int128Ty, "hi64");
27198+
27199+
Value *Or = Builder.CreateOr(
27200+
Lo, Builder.CreateShl(Hi, ConstantInt::get(Int128Ty, 64)), "val64");
27201+
return Builder.CreateBitCast(Or, ValueTy);
2720027202
}
2720127203

2720227204
Type *Tys[] = { Addr->getType() };
@@ -27207,8 +27209,8 @@ Value *AArch64TargetLowering::emitLoadLinked(IRBuilderBase &Builder,
2720727209
const DataLayout &DL = M->getDataLayout();
2720827210
IntegerType *IntEltTy = Builder.getIntNTy(DL.getTypeSizeInBits(ValueTy));
2720927211
CallInst *CI = Builder.CreateCall(Ldxr, Addr);
27210-
CI->addParamAttr(
27211-
0, Attribute::get(Builder.getContext(), Attribute::ElementType, ValueTy));
27212+
CI->addParamAttr(0, Attribute::get(Builder.getContext(),
27213+
Attribute::ElementType, IntEltTy));
2721227214
Value *Trunc = Builder.CreateTrunc(CI, IntEltTy);
2721327215

2721427216
return Builder.CreateBitCast(Trunc, ValueTy);
@@ -27234,9 +27236,13 @@ Value *AArch64TargetLowering::emitStoreConditional(IRBuilderBase &Builder,
2723427236
IsRelease ? Intrinsic::aarch64_stlxp : Intrinsic::aarch64_stxp;
2723527237
Function *Stxr = Intrinsic::getDeclaration(M, Int);
2723627238
Type *Int64Ty = Type::getInt64Ty(M->getContext());
27239+
Type *Int128Ty = Type::getInt128Ty(M->getContext());
27240+
27241+
Value *CastVal = Builder.CreateBitCast(Val, Int128Ty);
2723727242

27238-
Value *Lo = Builder.CreateTrunc(Val, Int64Ty, "lo");
27239-
Value *Hi = Builder.CreateTrunc(Builder.CreateLShr(Val, 64), Int64Ty, "hi");
27243+
Value *Lo = Builder.CreateTrunc(CastVal, Int64Ty, "lo");
27244+
Value *Hi =
27245+
Builder.CreateTrunc(Builder.CreateLShr(CastVal, 64), Int64Ty, "hi");
2724027246
return Builder.CreateCall(Stxr, {Lo, Hi, Addr});
2724127247
}
2724227248

0 commit comments

Comments
 (0)