diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp --- a/llvm/lib/CodeGen/AtomicExpandPass.cpp +++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp @@ -125,6 +125,14 @@ CreateCmpXchgInstFun CreateCmpXchg); }; +// IRBuilder to be used for replacement atomic instructions. +struct ReplacementIRBuilder : IRBuilder<> { + // Preserves the DebugLoc from I, and preserves still valid metadata. + explicit ReplacementIRBuilder(Instruction *I) : IRBuilder<>(I) { + this->CollectMetadataToCopy(I, {LLVMContext::MD_pcsections}); + } +}; + } // end anonymous namespace char AtomicExpand::ID = 0; @@ -328,7 +336,7 @@ } bool AtomicExpand::bracketInstWithFences(Instruction *I, AtomicOrdering Order) { - IRBuilder<> Builder(I); + ReplacementIRBuilder Builder(I); auto LeadingFence = TLI->emitLeadingFence(Builder, I, Order); @@ -357,7 +365,7 @@ auto *M = LI->getModule(); Type *NewTy = getCorrespondingIntegerType(LI->getType(), M->getDataLayout()); - IRBuilder<> Builder(LI); + ReplacementIRBuilder Builder(LI); Value *Addr = LI->getPointerOperand(); Type *PT = PointerType::get(NewTy, Addr->getType()->getPointerAddressSpace()); @@ -381,7 +389,7 @@ Type *NewTy = getCorrespondingIntegerType(RMWI->getType(), M->getDataLayout()); - IRBuilder<> Builder(RMWI); + ReplacementIRBuilder Builder(RMWI); Value *Addr = RMWI->getPointerOperand(); Value *Val = RMWI->getValOperand(); @@ -443,7 +451,7 @@ } bool AtomicExpand::expandAtomicLoadToLL(LoadInst *LI) { - IRBuilder<> Builder(LI); + ReplacementIRBuilder Builder(LI); // On some architectures, load-linked instructions are atomic for larger // sizes than normal loads. For example, the only 64-bit load guaranteed @@ -459,7 +467,7 @@ } bool AtomicExpand::expandAtomicLoadToCmpXchg(LoadInst *LI) { - IRBuilder<> Builder(LI); + ReplacementIRBuilder Builder(LI); AtomicOrdering Order = LI->getOrdering(); if (Order == AtomicOrdering::Unordered) Order = AtomicOrdering::Monotonic; @@ -488,7 +496,7 @@ /// mechanism, we convert back to the old format which the backends understand. /// Each backend will need individual work to recognize the new format. StoreInst *AtomicExpand::convertAtomicStoreToIntegerType(StoreInst *SI) { - IRBuilder<> Builder(SI); + ReplacementIRBuilder Builder(SI); auto *M = SI->getModule(); Type *NewTy = getCorrespondingIntegerType(SI->getValueOperand()->getType(), M->getDataLayout()); @@ -514,7 +522,7 @@ // or lock cmpxchg8/16b on X86, as these are atomic for larger sizes. // It is the responsibility of the target to only signal expansion via // shouldExpandAtomicRMW in cases where this is required and possible. - IRBuilder<> Builder(SI); + ReplacementIRBuilder Builder(SI); AtomicOrdering Ordering = SI->getOrdering(); assert(Ordering != AtomicOrdering::NotAtomic); AtomicOrdering RMWOrdering = Ordering == AtomicOrdering::Unordered @@ -816,7 +824,7 @@ AtomicOrdering MemOpOrder = AI->getOrdering(); SyncScope::ID SSID = AI->getSyncScopeID(); - IRBuilder<> Builder(AI); + ReplacementIRBuilder Builder(AI); PartwordMaskValues PMV = createMaskInstrs(Builder, AI, AI->getType(), AI->getPointerOperand(), @@ -850,7 +858,7 @@ // Widen the bitwise atomicrmw (or/xor/and) to the minimum supported width. AtomicRMWInst *AtomicExpand::widenPartwordAtomicRMW(AtomicRMWInst *AI) { - IRBuilder<> Builder(AI); + ReplacementIRBuilder Builder(AI); AtomicRMWInst::BinOp Op = AI->getOperation(); assert((Op == AtomicRMWInst::Or || Op == AtomicRMWInst::Xor || @@ -925,7 +933,7 @@ BasicBlock *BB = CI->getParent(); Function *F = BB->getParent(); - IRBuilder<> Builder(CI); + ReplacementIRBuilder Builder(CI); LLVMContext &Ctx = Builder.getContext(); BasicBlock *EndBB = @@ -1012,7 +1020,7 @@ Instruction *I, Type *ResultType, Value *Addr, Align AddrAlign, AtomicOrdering MemOpOrder, function_ref &, Value *)> PerformOp) { - IRBuilder<> Builder(I); + ReplacementIRBuilder Builder(I); Value *Loaded = insertRMWLLSCLoop(Builder, ResultType, Addr, AddrAlign, MemOpOrder, PerformOp); @@ -1021,7 +1029,7 @@ } void AtomicExpand::expandAtomicRMWToMaskedIntrinsic(AtomicRMWInst *AI) { - IRBuilder<> Builder(AI); + ReplacementIRBuilder Builder(AI); PartwordMaskValues PMV = createMaskInstrs(Builder, AI, AI->getType(), AI->getPointerOperand(), @@ -1047,7 +1055,7 @@ } void AtomicExpand::expandAtomicCmpXchgToMaskedIntrinsic(AtomicCmpXchgInst *CI) { - IRBuilder<> Builder(CI); + ReplacementIRBuilder Builder(CI); PartwordMaskValues PMV = createMaskInstrs( Builder, CI, CI->getCompareOperand()->getType(), CI->getPointerOperand(), @@ -1134,7 +1142,7 @@ Type *NewTy = getCorrespondingIntegerType(CI->getCompareOperand()->getType(), M->getDataLayout()); - IRBuilder<> Builder(CI); + ReplacementIRBuilder Builder(CI); Value *Addr = CI->getPointerOperand(); Type *PT = PointerType::get(NewTy, Addr->getType()->getPointerAddressSpace()); @@ -1258,8 +1266,7 @@ BasicBlock::Create(Ctx, "cmpxchg.fencedstore", F, TryStoreBB); auto StartBB = BasicBlock::Create(Ctx, "cmpxchg.start", F, ReleasingStoreBB); - // This grabs the DebugLoc from CI - IRBuilder<> Builder(CI); + ReplacementIRBuilder Builder(CI); // The split call above "helpfully" added a branch at the end of BB (to the // wrong place), but we might want a fence too. It's easiest to just remove @@ -1524,7 +1531,7 @@ // Note: This function is exposed externally by AtomicExpandUtils.h bool llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI, CreateCmpXchgInstFun CreateCmpXchg) { - IRBuilder<> Builder(AI); + ReplacementIRBuilder Builder(AI); Value *Loaded = AtomicExpand::insertRMWCmpXchgLoop( Builder, AI->getType(), AI->getPointerOperand(), AI->getAlign(), AI->getOrdering(), AI->getSyncScopeID(), diff --git a/llvm/test/CodeGen/AArch64/pcsections.ll b/llvm/test/CodeGen/AArch64/pcsections.ll --- a/llvm/test/CodeGen/AArch64/pcsections.ll +++ b/llvm/test/CodeGen/AArch64/pcsections.ll @@ -1,8 +1,8 @@ ; BROKEN: llc -O0 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-UNOPT,DEFCM -; BROKEN: llc -O1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,DEFCM -; BROKEN: llc -O2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,DEFCM -; BROKEN: llc -O3 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,DEFCM -; BROKEN: llc -O1 -code-model=large < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,LARGE +; RUN: llc -O1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,DEFCM +; RUN: llc -O2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,DEFCM +; RUN: llc -O3 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,DEFCM +; RUN: llc -O1 -code-model=large < %s | FileCheck %s --check-prefixes=CHECK,CHECK-OPT,LARGE target triple = "aarch64-unknown-linux-gnu"