Skip to content

Commit d940e9b

Browse files
committed
implement emitExpandAtomicRMW to custom expand i8/i16 atomicrmw and/or/xor
1 parent f564e99 commit d940e9b

File tree

3 files changed

+2025
-333
lines changed

3 files changed

+2025
-333
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5751,6 +5751,58 @@ bool LoongArchTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
57515751
}
57525752
}
57535753

5754+
void LoongArchTargetLowering::emitExpandAtomicRMW(AtomicRMWInst *AI) const {
5755+
AtomicRMWInst::BinOp Op = AI->getOperation();
5756+
5757+
assert((Op == AtomicRMWInst::Or || Op == AtomicRMWInst::Xor ||
5758+
Op == AtomicRMWInst::And) &&
5759+
"Unable to expand");
5760+
unsigned MinWordSize = 4;
5761+
5762+
IRBuilder<> Builder(AI);
5763+
LLVMContext &Ctx = Builder.getContext();
5764+
const DataLayout &DL = AI->getDataLayout();
5765+
Type *ValueType = AI->getType();
5766+
Type *WordType = Type::getIntNTy(Ctx, MinWordSize * 8);
5767+
5768+
Value *Addr = AI->getPointerOperand();
5769+
PointerType *PtrTy = cast<PointerType>(Addr->getType());
5770+
IntegerType *IntTy = DL.getIndexType(Ctx, PtrTy->getAddressSpace());
5771+
5772+
Value *AlignedAddr = Builder.CreateIntrinsic(
5773+
Intrinsic::ptrmask, {PtrTy, IntTy},
5774+
{Addr, ConstantInt::get(IntTy, ~(uint64_t)(MinWordSize - 1))}, nullptr,
5775+
"AlignedAddr");
5776+
5777+
Value *AddrInt = Builder.CreatePtrToInt(Addr, IntTy);
5778+
Value *PtrLSB = Builder.CreateAnd(AddrInt, MinWordSize - 1, "PtrLSB");
5779+
Value *ShiftAmt = Builder.CreateShl(PtrLSB, 3);
5780+
ShiftAmt = Builder.CreateTrunc(ShiftAmt, WordType, "ShiftAmt");
5781+
Value *Mask = Builder.CreateShl(
5782+
ConstantInt::get(WordType,
5783+
(1 << (DL.getTypeStoreSize(ValueType) * 8)) - 1),
5784+
ShiftAmt, "Mask");
5785+
Value *Inv_Mask = Builder.CreateNot(Mask, "Inv_Mask");
5786+
Value *ValOperand_Shifted =
5787+
Builder.CreateShl(Builder.CreateZExt(AI->getValOperand(), WordType),
5788+
ShiftAmt, "ValOperand_Shifted");
5789+
Value *NewOperand;
5790+
if (Op == AtomicRMWInst::And)
5791+
NewOperand = Builder.CreateOr(ValOperand_Shifted, Inv_Mask, "AndOperand");
5792+
else
5793+
NewOperand = ValOperand_Shifted;
5794+
5795+
AtomicRMWInst *NewAI =
5796+
Builder.CreateAtomicRMW(Op, AlignedAddr, NewOperand, Align(MinWordSize),
5797+
AI->getOrdering(), AI->getSyncScopeID());
5798+
5799+
Value *Shift = Builder.CreateLShr(NewAI, ShiftAmt, "shifted");
5800+
Value *Trunc = Builder.CreateTrunc(Shift, ValueType, "extracted");
5801+
Value *FinalOldResult = Builder.CreateBitCast(Trunc, ValueType);
5802+
AI->replaceAllUsesWith(FinalOldResult);
5803+
AI->eraseFromParent();
5804+
}
5805+
57545806
TargetLowering::AtomicExpansionKind
57555807
LoongArchTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
57565808
// TODO: Add more AtomicRMWInst that needs to be extended.
@@ -5772,9 +5824,14 @@ LoongArchTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
57725824
}
57735825

57745826
unsigned Size = AI->getType()->getPrimitiveSizeInBits();
5775-
if (Subtarget.hasLAMCAS() &&
5776-
(AI->getOperation() == AtomicRMWInst::Nand || Size < 32))
5777-
return AtomicExpansionKind::CmpXChg;
5827+
if (Subtarget.hasLAMCAS()) {
5828+
if (Size < 32 && (AI->getOperation() == AtomicRMWInst::And ||
5829+
AI->getOperation() == AtomicRMWInst::Or ||
5830+
AI->getOperation() == AtomicRMWInst::Xor))
5831+
return AtomicExpansionKind::Expand;
5832+
if ((AI->getOperation() == AtomicRMWInst::Nand || Size < 32))
5833+
return AtomicExpansionKind::CmpXChg;
5834+
}
57785835

57795836
if (Size == 8 || Size == 16)
57805837
return AtomicExpansionKind::MaskedIntrinsic;

llvm/lib/Target/LoongArch/LoongArchISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ class LoongArchTargetLowering : public TargetLowering {
192192
bool hasAndNot(SDValue Y) const override;
193193
TargetLowering::AtomicExpansionKind
194194
shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;
195+
void emitExpandAtomicRMW(AtomicRMWInst *AI) const override;
195196

196197
Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI,
197198
Value *AlignedAddr, Value *Incr,

0 commit comments

Comments
 (0)