diff options
4 files changed, 282 insertions, 28 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index a0e63bf1..812874f 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -1528,11 +1528,7 @@ static void emitRemark(const Function &F, OptimizationRemarkEmitter &ORE, bool HWAddressSanitizer::selectiveInstrumentationShouldSkip( Function &F, FunctionAnalysisManager &FAM) const { - bool Skip = [&]() { - if (ClRandomSkipRate.getNumOccurrences()) { - std::bernoulli_distribution D(ClRandomSkipRate); - return !D(*Rng); - } + auto SkipHot = [&]() { if (!ClHotPercentileCutoff.getNumOccurrences()) return false; auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F); @@ -1544,7 +1540,16 @@ bool HWAddressSanitizer::selectiveInstrumentationShouldSkip( } return PSI->isFunctionHotInCallGraphNthPercentile( ClHotPercentileCutoff, &F, FAM.getResult<BlockFrequencyAnalysis>(F)); - }(); + }; + + auto SkipRandom = [&]() { + if (!ClRandomSkipRate.getNumOccurrences()) + return false; + std::bernoulli_distribution D(ClRandomSkipRate); + return !D(*Rng); + }; + + bool Skip = SkipRandom() || SkipHot(); emitRemark(F, FAM.getResult<OptimizationRemarkEmitterAnalysis>(F), Skip); return Skip; } diff --git a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp index 0115809..19cf7dc 100644 --- a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp +++ b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp @@ -76,13 +76,25 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, SmallVector<std::pair<IntrinsicInst *, bool>, 16> ReplaceWithValue; std::unique_ptr<RandomNumberGenerator> Rng; - auto ShouldRemove = [&](bool IsHot) { - if (!RandomRate.getNumOccurrences()) - return IsHot; + auto GetRng = [&]() -> RandomNumberGenerator & { if (!Rng) Rng = F.getParent()->createRNG(F.getName()); - std::bernoulli_distribution D(RandomRate); - return !D(*Rng); + return *Rng; + }; + + auto ShouldRemoveHot = [&](const BasicBlock &BB) { + return HotPercentileCutoff.getNumOccurrences() && PSI && + PSI->isHotCountNthPercentile( + HotPercentileCutoff, BFI.getBlockProfileCount(&BB).value_or(0)); + }; + + auto ShouldRemoveRandom = [&]() { + return RandomRate.getNumOccurrences() && + !std::bernoulli_distribution(RandomRate)(GetRng()); + }; + + auto ShouldRemove = [&](const BasicBlock &BB) { + return ShouldRemoveRandom() || ShouldRemoveHot(BB); }; for (BasicBlock &BB : F) { @@ -96,13 +108,7 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, case Intrinsic::allow_runtime_check: { ++NumChecksTotal; - bool IsHot = false; - if (PSI) { - uint64_t Count = BFI.getBlockProfileCount(&BB).value_or(0); - IsHot = PSI->isHotCountNthPercentile(HotPercentileCutoff, Count); - } - - bool ToRemove = ShouldRemove(IsHot); + bool ToRemove = ShouldRemove(BB); ReplaceWithValue.push_back({ II, ToRemove, diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/pgo-opt-out.ll b/llvm/test/Instrumentation/HWAddressSanitizer/pgo-opt-out.ll index d5cb27d..0ef9423 100644 --- a/llvm/test/Instrumentation/HWAddressSanitizer/pgo-opt-out.ll +++ b/llvm/test/Instrumentation/HWAddressSanitizer/pgo-opt-out.ll @@ -1,15 +1,9 @@ -; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-percentile-cutoff-hot=700000 2>&1 | FileCheck %s --check-prefix=HOT70 -; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-percentile-cutoff-hot=990000 2>&1 | FileCheck %s --check-prefix=HOT99 +; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-percentile-cutoff-hot=700000 2>&1 | FileCheck %s --check-prefix=ALL +; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-percentile-cutoff-hot=990000 2>&1 | FileCheck %s --check-prefix=NONE ; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-random-rate=1.0 2>&1 | FileCheck %s --check-prefix=ALL ; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-random-rate=0.0 2>&1 | FileCheck %s --check-prefix=NONE - -; HOT70: remark: <unknown>:0:0: Sanitized: F=sanitized -; HOT70: @sanitized -; HOT70-NEXT: @__hwasan_tls - -; HOT99: remark: <unknown>:0:0: Skipped: F=sanitized -; HOT99: @sanitized -; HOT99-NEXT: %x = alloca i8, i64 4 +; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-random-rate=1.0 -hwasan-percentile-cutoff-hot=990000 2>&1 | FileCheck %s --check-prefix=NONE +; RUN: opt < %s -passes='require<profile-summary>,hwasan' -pass-remarks=hwasan -pass-remarks-missed=hwasan -S -hwasan-random-rate=0.0 -hwasan-percentile-cutoff-hot=700000 2>&1 | FileCheck %s --check-prefix=NONE ; ALL: remark: <unknown>:0:0: Sanitized: F=sanitize ; ALL: @sanitized diff --git a/llvm/test/Transforms/lower-builtin-allow-check.ll b/llvm/test/Transforms/lower-builtin-allow-check.ll index 05d940a..bcd9722 100644 --- a/llvm/test/Transforms/lower-builtin-allow-check.ll +++ b/llvm/test/Transforms/lower-builtin-allow-check.ll @@ -1,8 +1,11 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 ; RUN: opt < %s -passes='function(lower-allow-check)' -S | FileCheck %s --check-prefixes=NOPROFILE ; RUN: opt < %s -passes='function(lower-allow-check)' -lower-allow-check-random-rate=0 -S | FileCheck %s --check-prefixes=NONE +; RUN: opt < %s -passes='function(lower-allow-check)' -lower-allow-check-random-rate=1 -S | FileCheck %s --check-prefixes=ALL ; RUN: opt < %s -passes='require<profile-summary>,function(lower-allow-check)' -lower-allow-check-percentile-cutoff-hot=990000 -S | FileCheck %s --check-prefixes=HOT99 ; RUN: opt < %s -passes='require<profile-summary>,function(lower-allow-check)' -lower-allow-check-percentile-cutoff-hot=700000 -S | FileCheck %s --check-prefixes=HOT70 +; RUN: opt < %s -passes='require<profile-summary>,function(lower-allow-check)' -lower-allow-check-random-rate=0 -lower-allow-check-percentile-cutoff-hot=990000 -S | FileCheck %s --check-prefixes=NONE99 +; RUN: opt < %s -passes='require<profile-summary>,function(lower-allow-check)' -lower-allow-check-random-rate=1 -lower-allow-check-percentile-cutoff-hot=700000 -S | FileCheck %s --check-prefixes=ALL70 target triple = "x86_64-pc-linux-gnu" @@ -36,6 +39,19 @@ define dso_local noundef i32 @simple(ptr noundef readonly %0) { ; NONE-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 ; NONE-NEXT: ret i32 [[TMP5]] ; +; ALL-LABEL: define dso_local noundef i32 @simple( +; ALL-SAME: ptr noundef readonly [[TMP0:%.*]]) { +; ALL-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null +; ALL-NEXT: [[HOT:%.*]] = xor i1 true, true +; ALL-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; ALL: 3: +; ALL-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL-NEXT: unreachable +; ALL: 4: +; ALL-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 +; ALL-NEXT: ret i32 [[TMP5]] +; ; HOT99-LABEL: define dso_local noundef i32 @simple( ; HOT99-SAME: ptr noundef readonly [[TMP0:%.*]]) { ; HOT99-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null @@ -62,6 +78,32 @@ define dso_local noundef i32 @simple(ptr noundef readonly %0) { ; HOT70-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 ; HOT70-NEXT: ret i32 [[TMP5]] ; +; NONE99-LABEL: define dso_local noundef i32 @simple( +; NONE99-SAME: ptr noundef readonly [[TMP0:%.*]]) { +; NONE99-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null +; NONE99-NEXT: [[HOT:%.*]] = xor i1 false, true +; NONE99-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]] +; NONE99-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; NONE99: 3: +; NONE99-NEXT: tail call void @llvm.ubsantrap(i8 22) +; NONE99-NEXT: unreachable +; NONE99: 4: +; NONE99-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 +; NONE99-NEXT: ret i32 [[TMP5]] +; +; ALL70-LABEL: define dso_local noundef i32 @simple( +; ALL70-SAME: ptr noundef readonly [[TMP0:%.*]]) { +; ALL70-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null +; ALL70-NEXT: [[HOT:%.*]] = xor i1 true, true +; ALL70-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL70-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; ALL70: 3: +; ALL70-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL70-NEXT: unreachable +; ALL70: 4: +; ALL70-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 +; ALL70-NEXT: ret i32 [[TMP5]] +; %chk = icmp eq ptr %0, null %allow = call i1 @llvm.allow.ubsan.check(i8 22) %hot = xor i1 %allow, true @@ -105,6 +147,19 @@ define dso_local noundef i32 @hot(ptr noundef readonly %0) !prof !36 { ; NONE-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 ; NONE-NEXT: ret i32 [[TMP5]] ; +; ALL-LABEL: define dso_local noundef i32 @hot( +; ALL-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF16:![0-9]+]] { +; ALL-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null +; ALL-NEXT: [[HOT:%.*]] = xor i1 true, true +; ALL-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; ALL: 3: +; ALL-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL-NEXT: unreachable +; ALL: 4: +; ALL-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 +; ALL-NEXT: ret i32 [[TMP5]] +; ; HOT99-LABEL: define dso_local noundef i32 @hot( ; HOT99-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF16:![0-9]+]] { ; HOT99-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null @@ -131,6 +186,32 @@ define dso_local noundef i32 @hot(ptr noundef readonly %0) !prof !36 { ; HOT70-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 ; HOT70-NEXT: ret i32 [[TMP5]] ; +; NONE99-LABEL: define dso_local noundef i32 @hot( +; NONE99-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF16:![0-9]+]] { +; NONE99-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null +; NONE99-NEXT: [[HOT:%.*]] = xor i1 false, true +; NONE99-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]] +; NONE99-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; NONE99: 3: +; NONE99-NEXT: tail call void @llvm.ubsantrap(i8 22) +; NONE99-NEXT: unreachable +; NONE99: 4: +; NONE99-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 +; NONE99-NEXT: ret i32 [[TMP5]] +; +; ALL70-LABEL: define dso_local noundef i32 @hot( +; ALL70-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF16:![0-9]+]] { +; ALL70-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null +; ALL70-NEXT: [[HOT:%.*]] = xor i1 true, true +; ALL70-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL70-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; ALL70: 3: +; ALL70-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL70-NEXT: unreachable +; ALL70: 4: +; ALL70-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 +; ALL70-NEXT: ret i32 [[TMP5]] +; %chk = icmp eq ptr %0, null %allow = call i1 @llvm.allow.ubsan.check(i8 22) %hot = xor i1 %allow, true @@ -173,6 +254,19 @@ define dso_local noundef i32 @veryHot(ptr noundef readonly %0) !prof !39 { ; NONE-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 ; NONE-NEXT: ret i32 [[TMP5]] ; +; ALL-LABEL: define dso_local noundef i32 @veryHot( +; ALL-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF17:![0-9]+]] { +; ALL-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null +; ALL-NEXT: [[HOT:%.*]] = xor i1 true, true +; ALL-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; ALL: 3: +; ALL-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL-NEXT: unreachable +; ALL: 4: +; ALL-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 +; ALL-NEXT: ret i32 [[TMP5]] +; ; HOT99-LABEL: define dso_local noundef i32 @veryHot( ; HOT99-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF17:![0-9]+]] { ; HOT99-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null @@ -199,6 +293,32 @@ define dso_local noundef i32 @veryHot(ptr noundef readonly %0) !prof !39 { ; HOT70-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 ; HOT70-NEXT: ret i32 [[TMP5]] ; +; NONE99-LABEL: define dso_local noundef i32 @veryHot( +; NONE99-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF17:![0-9]+]] { +; NONE99-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null +; NONE99-NEXT: [[HOT:%.*]] = xor i1 false, true +; NONE99-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]] +; NONE99-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; NONE99: 3: +; NONE99-NEXT: tail call void @llvm.ubsantrap(i8 22) +; NONE99-NEXT: unreachable +; NONE99: 4: +; NONE99-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 +; NONE99-NEXT: ret i32 [[TMP5]] +; +; ALL70-LABEL: define dso_local noundef i32 @veryHot( +; ALL70-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF17:![0-9]+]] { +; ALL70-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP0]], null +; ALL70-NEXT: [[HOT:%.*]] = xor i1 false, true +; ALL70-NEXT: [[TMP2:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL70-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; ALL70: 3: +; ALL70-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL70-NEXT: unreachable +; ALL70: 4: +; ALL70-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 +; ALL70-NEXT: ret i32 [[TMP5]] +; %chk = icmp eq ptr %0, null %allow = call i1 @llvm.allow.ubsan.check(i8 22) %hot = xor i1 %allow, true @@ -254,6 +374,25 @@ define dso_local noundef i32 @branchColdFnHot(i32 noundef %0, ptr noundef readon ; NONE-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] ; NONE-NEXT: ret i32 [[TMP10]] ; +; ALL-LABEL: define dso_local noundef i32 @branchColdFnHot( +; ALL-SAME: i32 noundef [[TMP0:%.*]], ptr noundef readonly [[TMP1:%.*]]) !prof [[PROF17]] { +; ALL-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; ALL-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF18:![0-9]+]] +; ALL: 4: +; ALL-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP1]], null +; ALL-NEXT: [[HOT:%.*]] = xor i1 true, true +; ALL-NEXT: [[TMP5:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; ALL: 6: +; ALL-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL-NEXT: unreachable +; ALL: 7: +; ALL-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP1]], align 4 +; ALL-NEXT: br label [[TMP9]] +; ALL: 9: +; ALL-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] +; ALL-NEXT: ret i32 [[TMP10]] +; ; HOT99-LABEL: define dso_local noundef i32 @branchColdFnHot( ; HOT99-SAME: i32 noundef [[TMP0:%.*]], ptr noundef readonly [[TMP1:%.*]]) !prof [[PROF17]] { ; HOT99-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 @@ -292,6 +431,44 @@ define dso_local noundef i32 @branchColdFnHot(i32 noundef %0, ptr noundef readon ; HOT70-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] ; HOT70-NEXT: ret i32 [[TMP10]] ; +; NONE99-LABEL: define dso_local noundef i32 @branchColdFnHot( +; NONE99-SAME: i32 noundef [[TMP0:%.*]], ptr noundef readonly [[TMP1:%.*]]) !prof [[PROF17]] { +; NONE99-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; NONE99-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF18:![0-9]+]] +; NONE99: 4: +; NONE99-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP1]], null +; NONE99-NEXT: [[HOT:%.*]] = xor i1 false, true +; NONE99-NEXT: [[TMP5:%.*]] = or i1 [[CHK]], [[HOT]] +; NONE99-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; NONE99: 6: +; NONE99-NEXT: tail call void @llvm.ubsantrap(i8 22) +; NONE99-NEXT: unreachable +; NONE99: 7: +; NONE99-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP1]], align 4 +; NONE99-NEXT: br label [[TMP9]] +; NONE99: 9: +; NONE99-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] +; NONE99-NEXT: ret i32 [[TMP10]] +; +; ALL70-LABEL: define dso_local noundef i32 @branchColdFnHot( +; ALL70-SAME: i32 noundef [[TMP0:%.*]], ptr noundef readonly [[TMP1:%.*]]) !prof [[PROF17]] { +; ALL70-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; ALL70-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF18:![0-9]+]] +; ALL70: 4: +; ALL70-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP1]], null +; ALL70-NEXT: [[HOT:%.*]] = xor i1 true, true +; ALL70-NEXT: [[TMP5:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL70-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; ALL70: 6: +; ALL70-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL70-NEXT: unreachable +; ALL70: 7: +; ALL70-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP1]], align 4 +; ALL70-NEXT: br label [[TMP9]] +; ALL70: 9: +; ALL70-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] +; ALL70-NEXT: ret i32 [[TMP10]] +; %3 = icmp eq i32 %0, 0 br i1 %3, label %9, label %4, !prof !38 @@ -354,6 +531,25 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon ; NONE-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] ; NONE-NEXT: ret i32 [[TMP10]] ; +; ALL-LABEL: define dso_local noundef i32 @branchHotFnCold( +; ALL-SAME: i32 noundef [[TMP0:%.*]], ptr noundef readonly [[TMP1:%.*]]) !prof [[PROF16]] { +; ALL-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; ALL-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF19:![0-9]+]] +; ALL: 4: +; ALL-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP1]], null +; ALL-NEXT: [[HOT:%.*]] = xor i1 true, true +; ALL-NEXT: [[TMP5:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; ALL: 6: +; ALL-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL-NEXT: unreachable +; ALL: 7: +; ALL-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP1]], align 4 +; ALL-NEXT: br label [[TMP9]] +; ALL: 9: +; ALL-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] +; ALL-NEXT: ret i32 [[TMP10]] +; ; HOT99-LABEL: define dso_local noundef i32 @branchHotFnCold( ; HOT99-SAME: i32 noundef [[TMP0:%.*]], ptr noundef readonly [[TMP1:%.*]]) !prof [[PROF16]] { ; HOT99-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 @@ -392,6 +588,44 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon ; HOT70-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] ; HOT70-NEXT: ret i32 [[TMP10]] ; +; NONE99-LABEL: define dso_local noundef i32 @branchHotFnCold( +; NONE99-SAME: i32 noundef [[TMP0:%.*]], ptr noundef readonly [[TMP1:%.*]]) !prof [[PROF16]] { +; NONE99-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; NONE99-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF19:![0-9]+]] +; NONE99: 4: +; NONE99-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP1]], null +; NONE99-NEXT: [[HOT:%.*]] = xor i1 false, true +; NONE99-NEXT: [[TMP5:%.*]] = or i1 [[CHK]], [[HOT]] +; NONE99-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; NONE99: 6: +; NONE99-NEXT: tail call void @llvm.ubsantrap(i8 22) +; NONE99-NEXT: unreachable +; NONE99: 7: +; NONE99-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP1]], align 4 +; NONE99-NEXT: br label [[TMP9]] +; NONE99: 9: +; NONE99-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] +; NONE99-NEXT: ret i32 [[TMP10]] +; +; ALL70-LABEL: define dso_local noundef i32 @branchHotFnCold( +; ALL70-SAME: i32 noundef [[TMP0:%.*]], ptr noundef readonly [[TMP1:%.*]]) !prof [[PROF16]] { +; ALL70-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 +; ALL70-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF19:![0-9]+]] +; ALL70: 4: +; ALL70-NEXT: [[CHK:%.*]] = icmp eq ptr [[TMP1]], null +; ALL70-NEXT: [[HOT:%.*]] = xor i1 true, true +; ALL70-NEXT: [[TMP5:%.*]] = or i1 [[CHK]], [[HOT]] +; ALL70-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; ALL70: 6: +; ALL70-NEXT: tail call void @llvm.ubsantrap(i8 22) +; ALL70-NEXT: unreachable +; ALL70: 7: +; ALL70-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP1]], align 4 +; ALL70-NEXT: br label [[TMP9]] +; ALL70: 9: +; ALL70-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP8]], [[TMP7]] ], [ 0, [[TMP2:%.*]] ] +; ALL70-NEXT: ret i32 [[TMP10]] +; %3 = icmp eq i32 %0, 0 br i1 %3, label %9, label %4, !prof !37 @@ -450,6 +684,11 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon ; NONE: [[PROF18]] = !{!"branch_weights", i32 1000, i32 1} ; NONE: [[PROF19]] = !{!"branch_weights", i32 1, i32 1000} ;. +; ALL: [[PROF16]] = !{!"function_entry_count", i64 1000} +; ALL: [[PROF17]] = !{!"function_entry_count", i64 7000} +; ALL: [[PROF18]] = !{!"branch_weights", i32 1000, i32 1} +; ALL: [[PROF19]] = !{!"branch_weights", i32 1, i32 1000} +;. ; HOT99: [[PROF16]] = !{!"function_entry_count", i64 1000} ; HOT99: [[PROF17]] = !{!"function_entry_count", i64 7000} ; HOT99: [[PROF18]] = !{!"branch_weights", i32 1000, i32 1} @@ -460,3 +699,13 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon ; HOT70: [[PROF18]] = !{!"branch_weights", i32 1000, i32 1} ; HOT70: [[PROF19]] = !{!"branch_weights", i32 1, i32 1000} ;. +; NONE99: [[PROF16]] = !{!"function_entry_count", i64 1000} +; NONE99: [[PROF17]] = !{!"function_entry_count", i64 7000} +; NONE99: [[PROF18]] = !{!"branch_weights", i32 1000, i32 1} +; NONE99: [[PROF19]] = !{!"branch_weights", i32 1, i32 1000} +;. +; ALL70: [[PROF16]] = !{!"function_entry_count", i64 1000} +; ALL70: [[PROF17]] = !{!"function_entry_count", i64 7000} +; ALL70: [[PROF18]] = !{!"branch_weights", i32 1000, i32 1} +; ALL70: [[PROF19]] = !{!"branch_weights", i32 1, i32 1000} +;. |