@@ -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+
57515803TargetLowering::AtomicExpansionKind
57525804LoongArchTargetLowering::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;
0 commit comments