Skip to content

Commit 4e088ed

Browse files
committed
implement emitExpandAtomicRMW to custom expand i8/i16 atomicrmw and/or/xor
1 parent 88daeba commit 4e088ed

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
@@ -5748,6 +5748,58 @@ bool LoongArchTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
57485748
}
57495749
}
57505750

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

57715823
unsigned Size = AI->getType()->getPrimitiveSizeInBits();
5772-
if (Subtarget.hasLAMCAS() &&
5773-
(AI->getOperation() == AtomicRMWInst::Nand || Size < 32))
5774-
return AtomicExpansionKind::CmpXChg;
5824+
if (Subtarget.hasLAMCAS()) {
5825+
if (Size < 32 && (AI->getOperation() == AtomicRMWInst::And ||
5826+
AI->getOperation() == AtomicRMWInst::Or ||
5827+
AI->getOperation() == AtomicRMWInst::Xor))
5828+
return AtomicExpansionKind::Expand;
5829+
if ((AI->getOperation() == AtomicRMWInst::Nand || Size < 32))
5830+
return AtomicExpansionKind::CmpXChg;
5831+
}
57755832

57765833
if (Size == 8 || Size == 16)
57775834
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)