1717#include < llvm/IR/InstIterator.h>
1818#include < llvm/IR/Instructions.h>
1919#include < llvm/IR/IntrinsicInst.h>
20+ #include " llvm/IR/MemoryModelRelaxationAnnotations.h"
2021#include < llvm/IR/Module.h>
2122#include < llvm/IR/Operator.h>
2223#include < llvm/IR/PassManager.h>
@@ -141,12 +142,28 @@ std::pair<Value *, Value *> insertRMWCmpXchgLoop(
141142}
142143
143144// from AtomicExpandImpl
144- struct ReplacementIRBuilder : IRBuilder<InstSimplifyFolder> {
145+ // IRBuilder to be used for replacement atomic instructions.
146+ struct ReplacementIRBuilder
147+ : IRBuilder<InstSimplifyFolder, IRBuilderCallbackInserter> {
148+ MDNode *MMRAMD = nullptr ;
149+
145150 // Preserves the DebugLoc from I, and preserves still valid metadata.
151+ // Enable StrictFP builder mode when appropriate.
146152 explicit ReplacementIRBuilder (Instruction *I, const DataLayout &DL)
147- : IRBuilder(I->getContext (), DL) {
153+ : IRBuilder(I->getContext (), InstSimplifyFolder(DL),
154+ IRBuilderCallbackInserter(
155+ [this ](Instruction *I) { addMMRAMD (I); })) {
148156 SetInsertPoint (I);
149157 this ->CollectMetadataToCopy (I, {LLVMContext::MD_pcsections});
158+ if (BB->getParent ()->getAttributes ().hasFnAttr (Attribute::StrictFP))
159+ this ->setIsFPConstrained (true );
160+
161+ MMRAMD = I->getMetadata (LLVMContext::MD_mmra);
162+ }
163+
164+ void addMMRAMD (Instruction *I) {
165+ if (canInstructionHaveMMRAs (*I))
166+ I->setMetadata (LLVMContext::MD_mmra, MMRAMD);
150167 }
151168};
152169
@@ -321,7 +338,6 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
321338 Type *Ty = Modify.getFunctionType ()->getReturnType ()->getStructElementType (0 );
322339
323340 ReplacementIRBuilder Builder (&Modify, Modify.getModule ()->getDataLayout ());
324- Builder.setIsFPConstrained (Modify.hasFnAttr (Attribute::StrictFP));
325341
326342 CallInst *ModifyOp;
327343 {
@@ -366,7 +382,7 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
366382 ModifyOp = cast<CallInst>(ValOp->getUser ());
367383 LoadedOp = ValOp;
368384 assert (LoadedOp->get () == RMW);
369- RMW->moveBefore (ModifyOp); // NewValInst is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
385+ RMW->moveBeforePreserving (ModifyOp-> getIterator () ); // NewValInst is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
370386 BinOp = false ;
371387 if (++attempts > 3 )
372388 break ;
@@ -383,7 +399,7 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
383399 assert (isa<UndefValue>(RMW->getOperand (1 ))); // RMW was previously being used as the placeholder for Val
384400 Value *Val;
385401 if (ValOp != nullptr ) {
386- RMW->moveBefore (cast<Instruction>(ValOp->getUser ())); // ValOp is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
402+ RMW->moveBeforePreserving (cast<Instruction>(ValOp->getUser ())-> getIterator ( )); // ValOp is a user of RMW, and RMW has no other dependants (per patternMatchAtomicRMWOp)
387403 Val = ValOp->get ();
388404 } else if (RMWOp == AtomicRMWInst::Xchg) {
389405 Val = NewVal;
@@ -411,7 +427,7 @@ void expandAtomicModifyToCmpXchg(CallInst &Modify,
411427 Builder, Ty, Ptr, *Alignment, Ordering, SSID, Modify,
412428 [&](IRBuilderBase &Builder, Value *Loaded) JL_NOTSAFEPOINT {
413429 LoadedOp->set (Loaded);
414- ModifyOp->moveBefore (*Builder.GetInsertBlock (), Builder.GetInsertPoint ());
430+ ModifyOp->moveBeforePreserving (*Builder.GetInsertBlock (), Builder.GetInsertPoint ());
415431 return ModifyOp;
416432 },
417433 CreateWeakCmpXchg);
0 commit comments