Index: llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h =================================================================== --- llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h +++ llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h @@ -138,6 +138,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 Index: llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -454,6 +454,9 @@ } bool InstrProfiling::isCounterPromotionEnabled() const { + if (!targetSupportsAtomic()) + return false; + if (DoCounterPromotion.getNumOccurrences() > 0) return DoCounterPromotion; @@ -737,8 +740,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 { @@ -1376,3 +1380,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(); +} Index: llvm/test/Instrumentation/InstrProfiling/atomic-updates-disabled.ll =================================================================== --- /dev/null +++ llvm/test/Instrumentation/InstrProfiling/atomic-updates-disabled.ll @@ -0,0 +1,16 @@ +; RUN: opt < %s -S -passes=instrprof -instrprof-atomic-counter-update-all | FileCheck %s +; This test purposely uses a target triple that doesn't support the atomic update used by InstrProf +; It shouldn't end up with an atomic update instruction + +target triple = "mips-unknown-linux-gnu" + +@__profn_foo = private constant [3 x i8] c"foo" + +; CHECK-LABEL: define void @foo +; CHECK-NOT: atomicrmw add ptr @__profc_foo, i64 1 monotonic +define void @foo() { + call void @llvm.instrprof.increment(ptr @__profn_foo, i64 0, i32 1, i32 0) + ret void +} + +declare void @llvm.instrprof.increment(ptr, i64, i32, i32) Index: llvm/test/Instrumentation/InstrProfiling/atomic-updates.ll =================================================================== --- llvm/test/Instrumentation/InstrProfiling/atomic-updates.ll +++ llvm/test/Instrumentation/InstrProfiling/atomic-updates.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -S -passes=instrprof -instrprof-atomic-counter-update-all | FileCheck %s +; This test purposely uses a target triple that does support the atomic update used by InstrProf target triple = "x86_64-apple-macosx10.10.0" Index: llvm/test/Transforms/PGOProfile/counter_promo.ll =================================================================== --- llvm/test/Transforms/PGOProfile/counter_promo.ll +++ llvm/test/Transforms/PGOProfile/counter_promo.ll @@ -1,6 +1,8 @@ ; RUN: opt < %s --passes=pgo-instr-gen,instrprof -do-counter-promotion=true -skip-ret-exit-block=0 -S | FileCheck --check-prefix=PROMO --check-prefix=NONATOMIC_PROMO %s ; RUN: opt < %s --passes=pgo-instr-gen,instrprof -do-counter-promotion=true -atomic-counter-update-promoted -skip-ret-exit-block=0 -S | FileCheck --check-prefix=PROMO --check-prefix=ATOMIC_PROMO %s +target triple = "x86_64-apple-macosx10.10.0" + define void @foo(i32 %n, i32 %N) { ; PROMO-LABEL: @foo ; PROMO: {{.*}} = load {{.*}} @__profc_foo{{.*}} 3) Index: llvm/test/Transforms/PGOProfile/counter_promo_exit_merge.ll =================================================================== --- llvm/test/Transforms/PGOProfile/counter_promo_exit_merge.ll +++ llvm/test/Transforms/PGOProfile/counter_promo_exit_merge.ll @@ -1,5 +1,7 @@ ; RUN: opt < %s --passes=instrprof -do-counter-promotion=true -speculative-counter-promotion-max-exiting=3 -S | FileCheck --check-prefix=PROMO %s +target triple = "x86_64-apple-macosx10.10.0" + $__llvm_profile_raw_version = comdat any @g = common local_unnamed_addr global i32 0, align 4 Index: llvm/test/Transforms/PGOProfile/counter_promo_mexits.ll =================================================================== --- llvm/test/Transforms/PGOProfile/counter_promo_mexits.ll +++ llvm/test/Transforms/PGOProfile/counter_promo_mexits.ll @@ -1,5 +1,7 @@ ; RUN: opt < %s --passes=pgo-instr-gen,instrprof -do-counter-promotion=true -speculative-counter-promotion-max-exiting=3 -S | FileCheck --check-prefix=PROMO %s +target triple = "x86_64-apple-macosx10.10.0" + @g = common local_unnamed_addr global i32 0, align 4 define void @foo(i32 %arg) local_unnamed_addr { Index: llvm/test/Transforms/PGOProfile/counter_promo_nest-inseltpoison.ll =================================================================== --- llvm/test/Transforms/PGOProfile/counter_promo_nest-inseltpoison.ll +++ llvm/test/Transforms/PGOProfile/counter_promo_nest-inseltpoison.ll @@ -1,6 +1,8 @@ ; TEST that counter updates are promoted outside the whole loop nest ; RUN: opt < %s --passes=pgo-instr-gen,instrprof -do-counter-promotion=true -S | FileCheck --check-prefix=PROMO %s +target triple = "x86_64-apple-macosx10.10.0" + @g = common local_unnamed_addr global i32 0, align 4 @c = local_unnamed_addr global i32 10, align 4 Index: llvm/test/Transforms/PGOProfile/counter_promo_nest.ll =================================================================== --- llvm/test/Transforms/PGOProfile/counter_promo_nest.ll +++ llvm/test/Transforms/PGOProfile/counter_promo_nest.ll @@ -1,6 +1,8 @@ ; TEST that counter updates are promoted outside the whole loop nest ; RUN: opt < %s --passes=pgo-instr-gen,instrprof -do-counter-promotion=true -S | FileCheck --check-prefix=PROMO %s +target triple = "x86_64-apple-macosx10.10.0" + @g = common local_unnamed_addr global i32 0, align 4 @c = local_unnamed_addr global i32 10, align 4 Index: llvm/test/Transforms/PGOProfile/not_promote_ret_exit.ll =================================================================== --- llvm/test/Transforms/PGOProfile/not_promote_ret_exit.ll +++ llvm/test/Transforms/PGOProfile/not_promote_ret_exit.ll @@ -1,6 +1,8 @@ ; RUN: opt < %s -passes=instrprof -S -do-counter-promotion=1 -skip-ret-exit-block=1 | FileCheck %s --check-prefixes=CHECK,SKIP ; RUN: opt < %s -passes=instrprof -S -do-counter-promotion=1 -skip-ret-exit-block=0 | FileCheck %s --check-prefixes=CHECK,NOTSKIP +target triple = "x86_64-apple-macosx10.10.0" + $__llvm_profile_raw_version = comdat any @bar = dso_local local_unnamed_addr global i32 0, align 4