diff --git a/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h b/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h --- a/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h +++ b/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h @@ -134,6 +134,10 @@ /// Create a static initializer for our data, on platforms that need it, /// and for any profile output file that was specified. void emitInitialization(); + + /// Check if our target supports 8 byte/ 64 bit Atomics. Don't use + /// them if it doesn't. + bool targetSupportsAtomic() const; }; } // end namespace llvm diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -451,10 +451,13 @@ } bool InstrProfiling::isCounterPromotionEnabled() const { - if (DoCounterPromotion.getNumOccurrences() > 0) - return DoCounterPromotion; + if (targetSupportsAtomic()) { + if (DoCounterPromotion.getNumOccurrences() > 0) + return DoCounterPromotion; - return Options.DoCounterPromotion; + return Options.DoCounterPromotion; + } + return false; } void InstrProfiling::promoteCounterLoadStores(Function *F) { @@ -714,8 +717,9 @@ auto *Addr = getCounterAddress(Inc); IRBuilder<> Builder(Inc); - if (Options.Atomic || AtomicCounterUpdateAll || - (Inc->getIndex()->isZeroValue() && AtomicFirstCounter)) { + if (targetSupportsAtomic() && + (Options.Atomic || AtomicCounterUpdateAll || + (Inc->getIndex()->isZeroValue() && AtomicFirstCounter))) { Builder.CreateAtomicRMW(AtomicRMWInst::Add, Addr, Inc->getStep(), MaybeAlign(), AtomicOrdering::Monotonic); } else { @@ -1288,3 +1292,12 @@ appendToGlobalCtors(*M, F, 0); } + +bool InstrProfiling::targetSupportsAtomic() const { + // As far as I can tell, we don't have access to specific enough target + // details here to really know if they support the atomic add or not. It seems + // like a safe assumption though that only 64 bit targets will support the 64 + // bit atomic operation we're going to inject. + // If this assumption is incorrect, additional logic can be added here. + return TT.isArch64Bit(); +}