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 @@ -209,6 +209,18 @@ Value *Addr = cast(Store)->getPointerOperand(); Type *Ty = LiveInValue->getType(); IRBuilder<> Builder(InsertPos); + if (auto *AddrInst = dyn_cast_or_null(Addr)) { + // If isRuntimeCounterRelocationEnabled() is true then the address of + // the store instruction is computed with two instructions in + // InstrProfiling::getCounterAddress(). We need to copy those + // instructions to this block to compute Addr correctly. + // %BiasAdd = add i64 ptrtoint <__profc_>, <__llvm_profile_counter_bias> + // %Addr = inttoptr i64 %BiasAdd to i64* + auto *OrigBiasInst = dyn_cast(AddrInst->getOperand(0)); + assert(OrigBiasInst->getOpcode() == Instruction::BinaryOps::Add); + Value *BiasInst = Builder.Insert(OrigBiasInst->clone()); + Addr = Builder.CreateIntToPtr(BiasInst, Ty->getPointerTo()); + } if (AtomicCounterUpdatePromoted) // automic update currently can only be promoted across the current // loop, not the whole loop nest. diff --git a/llvm/test/Transforms/PGOProfile/counter_promo_with_bias.ll b/llvm/test/Transforms/PGOProfile/counter_promo_with_bias.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/PGOProfile/counter_promo_with_bias.ll @@ -0,0 +1,33 @@ +; RUN: opt < %s -instrprof -runtime-counter-relocation -do-counter-promotion=true -S | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" + +@__profn_foo = private constant [3 x i8] c"foo" + +define void @foo(i1 %c) { +entry: +; CHECK: %[[BIAS:[0-9]+]] = load i64, i64* @__llvm_profile_counter_bias + br label %while.cond + +while.cond: ; preds = %land.rhs, %while.cond.preheader +; CHECK: %[[COUNT:[a-z0-9.]+]] = phi i64 [ %[[LAND_COUNT:[0-9]+]], %land.rhs ], [ 0, %entry ] + br i1 %c, label %while.cond.cleanup_crit_edge, label %land.rhs + +while.cond.cleanup_crit_edge: ; preds = %while.cond +; CHECK: %[[COUNTER_PTR:[0-9]+]] = add i64 ptrtoint ([1 x i64]* @__profc_foo to i64), %[[BIAS]] +; CHECK: %[[COUNTER_ADDR:[0-9]+]] = inttoptr i64 %[[COUNTER_PTR]] to i64* +; CHECK: %[[COUNTER_PROMO:[a-z0-9.]+]] = load i64, i64* %[[COUNTER_ADDR]] +; CHECK: %[[VALUE:[0-9]+]] = add i64 %[[COUNTER_PROMO]], %[[COUNT]] +; CHECK: store i64 %[[VALUE]], i64* %[[COUNTER_ADDR]] + br label %cleanup + +land.rhs: ; preds = %while.cond + call void @llvm.instrprof.increment(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @__profn_foo, i32 0, i32 0), i64 0, i32 1, i32 0) +; CHECK: %[[LAND_COUNT]] = add i64 %[[COUNT]], 1 + br label %while.cond + +cleanup: ; preds = %while.cond.cleanup_crit_edge + ret void +} + +declare void @llvm.instrprof.increment(i8 *, i64, i32, i32)