diff --git a/llvm/include/llvm/IR/GCStrategy.h b/llvm/include/llvm/IR/GCStrategy.h --- a/llvm/include/llvm/IR/GCStrategy.h +++ b/llvm/include/llvm/IR/GCStrategy.h @@ -74,6 +74,10 @@ bool NeededSafePoints = false; ///< if set, calls are inferred to be safepoints bool UsesMetadata = false; ///< If set, backend must emit metadata tables. + bool RequiresLoadBarriers = false; ///< If set, GC requires read barriers on object + /// pointer loads + bool RequiresStoreBarriers = false; ///< If set, GC requires store barriers on object + /// pointer stores. public: GCStrategy(); @@ -87,6 +91,17 @@ /// and false otherwise. bool useStatepoints() const { return UseStatepoints; } + /// Returns true if GC requires load barriers on object pointers. + bool requiresLoadBarriers() const { return RequiresLoadBarriers; } + + /// Returns true if GC requires store barriers on object pointers. + bool requiresStoreBarriers() const { return RequiresStoreBarriers; } + + /// Returns true if GC requires load and/or store barriers on object pointers. + bool requiresBarriers() const { + return RequiresLoadBarriers || RequiresStoreBarriers; + } + /** @name Statepoint Specific Properties */ ///@{ diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -68,6 +68,7 @@ #include "llvm/IR/DebugLoc.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/GCStrategy.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IRBuilder.h" @@ -1503,6 +1504,16 @@ } NewCall->setDebugLoc(TheStore->getDebugLoc()); + const auto *F = TheStore->getFunction(); + if (F->hasGC()) + if (auto GC = llvm::getGCStrategy(F->getGC())) + if (GC->requiresBarriers()) { + LLVMContext &Ctx = NewCall->getContext(); + Type *ET = TheLoad->getType(); + NewCall->addParamAttr(0, Attribute::get(Ctx, Attribute::ElementType, ET)); + NewCall->addParamAttr(1, Attribute::get(Ctx, Attribute::ElementType, ET)); + } + if (MSSAU) { MemoryAccess *NewMemAcc = MSSAU->createMemoryAccessInBB( NewCall, nullptr, NewCall->getParent(), MemorySSA::BeforeTerminator);