aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AtomicExpandPass.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2022-09-22 10:51:33 -0400
committerMatt Arsenault <arsenm2@gmail.com>2022-11-10 22:16:11 -0800
commit3cfa03856f32353b57c5f278a1911b14ca57d473 (patch)
treed59f3a611b47d7f08127586e1574333e7e238c56 /llvm/lib/CodeGen/AtomicExpandPass.cpp
parent094c0eccdf959c3b9c85219e33c3fcfbab024b61 (diff)
downloadllvm-3cfa03856f32353b57c5f278a1911b14ca57d473.zip
llvm-3cfa03856f32353b57c5f278a1911b14ca57d473.tar.gz
llvm-3cfa03856f32353b57c5f278a1911b14ca57d473.tar.bz2
AtomicExpand: Support cmpxchg expansion for small FP types
Handles f16 atomics for AMDGPU.
Diffstat (limited to 'llvm/lib/CodeGen/AtomicExpandPass.cpp')
-rw-r--r--llvm/lib/CodeGen/AtomicExpandPass.cpp29
1 files changed, 18 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index 72262b4..fca7a52 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -577,10 +577,6 @@ bool AtomicExpand::tryExpandAtomicRMW(AtomicRMWInst *AI) {
unsigned MinCASSize = TLI->getMinCmpXchgSizeInBits() / 8;
unsigned ValueSize = getAtomicOpSize(AI);
if (ValueSize < MinCASSize) {
- // TODO: Handle atomicrmw fadd/fsub
- if (AI->getType()->isFloatingPointTy())
- return false;
-
expandPartwordAtomicRMW(AI,
TargetLoweringBase::AtomicExpansionKind::CmpXChg);
} else {
@@ -624,6 +620,7 @@ struct PartwordMaskValues {
// These three fields are guaranteed to be set by createMaskInstrs.
Type *WordType = nullptr;
Type *ValueType = nullptr;
+ Type *IntValueType = nullptr;
Value *AlignedAddr = nullptr;
Align AlignedAddrAlignment;
// The remaining fields can be null.
@@ -688,7 +685,11 @@ static PartwordMaskValues createMaskInstrs(IRBuilderBase &Builder,
const DataLayout &DL = M->getDataLayout();
unsigned ValueSize = DL.getTypeStoreSize(ValueType);
- PMV.ValueType = ValueType;
+ PMV.ValueType = PMV.IntValueType = ValueType;
+ if (PMV.ValueType->isFloatingPointTy())
+ PMV.IntValueType =
+ Type::getIntNTy(Ctx, ValueType->getPrimitiveSizeInBits());
+
PMV.WordType = MinWordSize > ValueSize ? Type::getIntNTy(Ctx, MinWordSize * 8)
: ValueType;
if (PMV.ValueType == PMV.WordType) {
@@ -752,8 +753,8 @@ static Value *extractMaskedValue(IRBuilderBase &Builder, Value *WideWord,
return WideWord;
Value *Shift = Builder.CreateLShr(WideWord, PMV.ShiftAmt, "shifted");
- Value *Trunc = Builder.CreateTrunc(Shift, PMV.ValueType, "extracted");
- return Trunc;
+ Value *Trunc = Builder.CreateTrunc(Shift, PMV.IntValueType, "extracted");
+ return Builder.CreateBitCast(Trunc, PMV.ValueType);
}
static Value *insertMaskedValue(IRBuilderBase &Builder, Value *WideWord,
@@ -763,6 +764,8 @@ static Value *insertMaskedValue(IRBuilderBase &Builder, Value *WideWord,
if (PMV.WordType == PMV.ValueType)
return Updated;
+ Updated = Builder.CreateBitCast(Updated, PMV.IntValueType);
+
Value *ZExt = Builder.CreateZExt(Updated, PMV.WordType, "extended");
Value *Shift =
Builder.CreateShl(ZExt, PMV.ShiftAmt, "shifted", /*HasNUW*/ true);
@@ -804,10 +807,14 @@ static Value *performMaskedAtomicOp(AtomicRMWInst::BinOp Op,
case AtomicRMWInst::Max:
case AtomicRMWInst::Min:
case AtomicRMWInst::UMax:
- case AtomicRMWInst::UMin: {
- // Finally, comparison ops will operate on the full value, so
- // truncate down to the original size, and expand out again after
- // doing the operation.
+ case AtomicRMWInst::UMin:
+ case AtomicRMWInst::FAdd:
+ case AtomicRMWInst::FSub:
+ case AtomicRMWInst::FMin:
+ case AtomicRMWInst::FMax: {
+ // Finally, other ops will operate on the full value, so truncate down to
+ // the original size, and expand out again after doing the
+ // operation. Bitcasts will be inserted for FP values.
Value *Loaded_Extract = extractMaskedValue(Builder, Loaded, PMV);
Value *NewVal = buildAtomicRMWValue(Op, Builder, Loaded_Extract, Inc);
Value *FinalVal = insertMaskedValue(Builder, Loaded, NewVal, PMV);