llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Vitaly Buka (vitalybuka) <details> <summary>Changes</summary> Intrinsic introduced with #<!-- -->84850. Using intrinsic improves performance by 3% comparing to removing traps (on "test-suite/MultiSource/Benchmarks" with PGO+ThinLTO). The pass will be renamed with #<!-- -->84852. --- Patch is 20.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/84858.diff 5 Files Affected: - (modified) clang/lib/CodeGen/BackendUtil.cpp (+3-3) - (modified) clang/lib/CodeGen/CGExpr.cpp (+14-1) - (modified) clang/test/CodeGen/remote-traps.c (+20-3) - (modified) llvm/lib/Transforms/Instrumentation/RemoveTrapsPass.cpp (+15-11) - (modified) llvm/test/Transforms/RemoveTraps/remove-traps.ll (+64-25) ``````````diff diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 82b30b8d815629..7e53469a48d42c 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -100,9 +100,9 @@ using namespace llvm; namespace llvm { extern cl::opt<bool> PrintPipelinePasses; -cl::opt<bool> ClRemoveTraps("clang-remove-traps", cl::Optional, - cl::desc("Insert remove-traps pass."), - cl::init(false)); +static cl::opt<bool> ClRemoveTraps("clang-remove-traps", cl::Optional, + cl::desc("Insert remove-traps pass."), + cl::init(false)); // Experiment to move sanitizers earlier. static cl::opt<bool> ClSanitizeOnOptimizerEarlyEP( diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 59a7fe8925001c..3a27622f165995 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -56,7 +56,14 @@ using namespace CodeGen; // Experiment to make sanitizers easier to debug static llvm::cl::opt<bool> ClSanitizeDebugDeoptimization( "ubsan-unique-traps", llvm::cl::Optional, - llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check"), + llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check."), + llvm::cl::init(false)); + +// TODO: Introduce frontend options to enabled per sanitizers, similar to +// `fsanitize-trap`. +static llvm::cl::opt<bool> ClSanitizeExpHot( + "ubsan-exp-hot", llvm::cl::Optional, + llvm::cl::desc("Pass UBSAN checks if `llvm.experimental.hot()` is true."), llvm::cl::init(false)); //===--------------------------------------------------------------------===// @@ -3805,6 +3812,12 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID) { llvm::BasicBlock *Cont = createBasicBlock("cont"); + if (ClSanitizeExpHot) { + Checked = + Builder.CreateOr(Checked, Builder.CreateCall(CGM.getIntrinsic( + llvm::Intrinsic::experimental_hot))); + } + // If we're optimizing, collapse all calls to trap down to just one per // check-type per function to save on code size. if ((int)TrapBBs.size() <= CheckHandlerID) diff --git a/clang/test/CodeGen/remote-traps.c b/clang/test/CodeGen/remote-traps.c index 6751afb96d25f2..934b76fae0d2a5 100644 --- a/clang/test/CodeGen/remote-traps.c +++ b/clang/test/CodeGen/remote-traps.c @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -O1 -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow %s -o - | FileCheck %s -// RUN: %clang_cc1 -O1 -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -mllvm -clang-remove-traps -mllvm -remove-traps-random-rate=1 %s -o - | FileCheck %s --implicit-check-not="call void @llvm.ubsantrap" --check-prefixes=REMOVE +// RUN: %clang_cc1 -O1 %s -o - -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -mllvm -ubsan-exp-hot | FileCheck %s +// RUN: %clang_cc1 -O1 %s -o - -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -mllvm -ubsan-exp-hot -mllvm -clang-remove-traps -mllvm -remove-traps-random-rate=1 %s -o - | FileCheck %s --check-prefixes=REMOVE + +#include <stdbool.h> int test(int x) { return x + 123; @@ -12,4 +14,19 @@ int test(int x) { // CHECK-NEXT: unreachable // REMOVE-LABEL: define {{.*}}i32 @test( -// REMOVE: call { i32, i1 } @llvm.sadd.with.overflow.i32( +// REMOVE: add i32 %x, 123 +// REMOVE-NEXT: ret i32 + + +bool experimental_hot() __asm("llvm.experimental.hot"); + +bool test_asm() { + return experimental_hot(); +} + +// CHECK-LABEL: define {{.*}}i1 @test_asm( +// CHECK: [[R:%.*]] = tail call zeroext i1 @llvm.experimental.hot() +// CHECK: ret i1 [[R]] + +// REMOVE-LABEL: define {{.*}}i1 @test_asm( +// REMOVE: ret i1 true diff --git a/llvm/lib/Transforms/Instrumentation/RemoveTrapsPass.cpp b/llvm/lib/Transforms/Instrumentation/RemoveTrapsPass.cpp index d87f7482a21d25..fa4716f2e7a403 100644 --- a/llvm/lib/Transforms/Instrumentation/RemoveTrapsPass.cpp +++ b/llvm/lib/Transforms/Instrumentation/RemoveTrapsPass.cpp @@ -11,6 +11,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/ProfileSummaryInfo.h" +#include "llvm/IR/Constant.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" @@ -37,7 +38,7 @@ STATISTIC(NumChecksRemoved, "Number of removed checks"); static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, const ProfileSummaryInfo *PSI) { - SmallVector<IntrinsicInst *, 16> Remove; + SmallVector<std::pair<IntrinsicInst *, Value *>, 16> ReplaceWithValue; std::unique_ptr<RandomNumberGenerator> Rng; auto ShouldRemove = [&](bool IsHot) { @@ -56,15 +57,12 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, continue; auto ID = II->getIntrinsicID(); switch (ID) { - case Intrinsic::ubsantrap: { + case Intrinsic::experimental_hot: { ++NumChecksTotal; bool IsHot = false; if (PSI) { - uint64_t Count = 0; - for (const auto *PR : predecessors(&BB)) - Count += BFI.getBlockProfileCount(PR).value_or(0); - + uint64_t Count = BFI.getBlockProfileCount(&BB).value_or(0); IsHot = HotPercentileCutoff.getNumOccurrences() ? (HotPercentileCutoff > 0 && @@ -72,10 +70,14 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, : PSI->isHotCount(Count); } - if (ShouldRemove(IsHot)) { - Remove.push_back(II); + bool ToRemove = ShouldRemove(IsHot); + ReplaceWithValue.push_back({ + II, + ToRemove ? Constant::getAllOnesValue(II->getType()) + : (Constant::getNullValue(II->getType())), + }); + if (ToRemove) ++NumChecksRemoved; - } break; } default: @@ -84,10 +86,12 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, } } - for (IntrinsicInst *I : Remove) + for (auto [I, V] : ReplaceWithValue) { + I->replaceAllUsesWith(V); I->eraseFromParent(); + } - return !Remove.empty(); + return !ReplaceWithValue.empty(); } PreservedAnalyses RemoveTrapsPass::run(Function &F, diff --git a/llvm/test/Transforms/RemoveTraps/remove-traps.ll b/llvm/test/Transforms/RemoveTraps/remove-traps.ll index 71549e7d9b4122..80b86e0f7455aa 100644 --- a/llvm/test/Transforms/RemoveTraps/remove-traps.ll +++ b/llvm/test/Transforms/RemoveTraps/remove-traps.ll @@ -12,7 +12,8 @@ define dso_local noundef i32 @simple(ptr noundef readonly %0) { ; NOPROFILE-LABEL: define dso_local noundef i32 @simple( ; NOPROFILE-SAME: ptr noundef readonly [[TMP0:%.*]]) { ; NOPROFILE-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; NOPROFILE-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; NOPROFILE-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], false +; NOPROFILE-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; NOPROFILE: 3: ; NOPROFILE-NEXT: tail call void @llvm.ubsantrap(i8 22) ; NOPROFILE-NEXT: unreachable @@ -23,8 +24,10 @@ define dso_local noundef i32 @simple(ptr noundef readonly %0) { ; ALL-LABEL: define dso_local noundef i32 @simple( ; ALL-SAME: ptr noundef readonly [[TMP0:%.*]]) { ; ALL-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; ALL-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; ALL-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], true +; ALL-NEXT: br i1 [[TMP6]], 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 @@ -33,7 +36,8 @@ define dso_local noundef i32 @simple(ptr noundef readonly %0) { ; HOT-LABEL: define dso_local noundef i32 @simple( ; HOT-SAME: ptr noundef readonly [[TMP0:%.*]]) { ; HOT-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; HOT-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; HOT-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], false +; HOT-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; HOT: 3: ; HOT-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT-NEXT: unreachable @@ -44,7 +48,8 @@ define dso_local noundef i32 @simple(ptr noundef readonly %0) { ; HOT70-LABEL: define dso_local noundef i32 @simple( ; HOT70-SAME: ptr noundef readonly [[TMP0:%.*]]) { ; HOT70-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; HOT70-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; HOT70-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], false +; HOT70-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; HOT70: 3: ; HOT70-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT70-NEXT: unreachable @@ -52,7 +57,9 @@ define dso_local noundef i32 @simple(ptr noundef readonly %0) { ; HOT70-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 ; HOT70-NEXT: ret i32 [[TMP5]] ; - %2 = icmp eq ptr %0, null + %chk = icmp eq ptr %0, null + %hot = call i1 @llvm.experimental.hot() + %2 = or i1 %chk, %hot br i1 %2, label %3, label %4 3: @@ -69,7 +76,8 @@ define dso_local noundef i32 @hot(ptr noundef readonly %0) !prof !36 { ; NOPROFILE-LABEL: define dso_local noundef i32 @hot( ; NOPROFILE-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF16:![0-9]+]] { ; NOPROFILE-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; NOPROFILE-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; NOPROFILE-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], false +; NOPROFILE-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; NOPROFILE: 3: ; NOPROFILE-NEXT: tail call void @llvm.ubsantrap(i8 22) ; NOPROFILE-NEXT: unreachable @@ -80,8 +88,10 @@ define dso_local noundef i32 @hot(ptr noundef readonly %0) !prof !36 { ; ALL-LABEL: define dso_local noundef i32 @hot( ; ALL-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF16:![0-9]+]] { ; ALL-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; ALL-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; ALL-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], true +; ALL-NEXT: br i1 [[TMP6]], 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 @@ -90,8 +100,10 @@ define dso_local noundef i32 @hot(ptr noundef readonly %0) !prof !36 { ; HOT-LABEL: define dso_local noundef i32 @hot( ; HOT-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF16:![0-9]+]] { ; HOT-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; HOT-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; HOT-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], true +; HOT-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; HOT: 3: +; HOT-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT-NEXT: unreachable ; HOT: 4: ; HOT-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 @@ -100,7 +112,8 @@ define dso_local noundef i32 @hot(ptr noundef readonly %0) !prof !36 { ; HOT70-LABEL: define dso_local noundef i32 @hot( ; HOT70-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF16:![0-9]+]] { ; HOT70-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; HOT70-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; HOT70-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], false +; HOT70-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; HOT70: 3: ; HOT70-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT70-NEXT: unreachable @@ -108,7 +121,9 @@ 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]] ; - %2 = icmp eq ptr %0, null + %chk = icmp eq ptr %0, null + %hot = call i1 @llvm.experimental.hot() + %2 = or i1 %chk, %hot br i1 %2, label %3, label %4 3: @@ -124,7 +139,8 @@ define dso_local noundef i32 @veryHot(ptr noundef readonly %0) !prof !39 { ; NOPROFILE-LABEL: define dso_local noundef i32 @veryHot( ; NOPROFILE-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF17:![0-9]+]] { ; NOPROFILE-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; NOPROFILE-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; NOPROFILE-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], false +; NOPROFILE-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; NOPROFILE: 3: ; NOPROFILE-NEXT: tail call void @llvm.ubsantrap(i8 22) ; NOPROFILE-NEXT: unreachable @@ -135,8 +151,10 @@ define dso_local noundef i32 @veryHot(ptr noundef readonly %0) !prof !39 { ; ALL-LABEL: define dso_local noundef i32 @veryHot( ; ALL-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF17:![0-9]+]] { ; ALL-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; ALL-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; ALL-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], true +; ALL-NEXT: br i1 [[TMP6]], 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 @@ -145,8 +163,10 @@ define dso_local noundef i32 @veryHot(ptr noundef readonly %0) !prof !39 { ; HOT-LABEL: define dso_local noundef i32 @veryHot( ; HOT-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF17:![0-9]+]] { ; HOT-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; HOT-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; HOT-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], true +; HOT-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; HOT: 3: +; HOT-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT-NEXT: unreachable ; HOT: 4: ; HOT-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 @@ -155,14 +175,18 @@ define dso_local noundef i32 @veryHot(ptr noundef readonly %0) !prof !39 { ; HOT70-LABEL: define dso_local noundef i32 @veryHot( ; HOT70-SAME: ptr noundef readonly [[TMP0:%.*]]) !prof [[PROF17:![0-9]+]] { ; HOT70-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null -; HOT70-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] +; HOT70-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], true +; HOT70-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]] ; HOT70: 3: +; HOT70-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT70-NEXT: unreachable ; HOT70: 4: ; HOT70-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4 ; HOT70-NEXT: ret i32 [[TMP5]] ; - %2 = icmp eq ptr %0, null + %chk = icmp eq ptr %0, null + %hot = call i1 @llvm.experimental.hot() + %2 = or i1 %chk, %hot br i1 %2, label %3, label %4 3: @@ -182,7 +206,8 @@ define dso_local noundef i32 @branchColdFnHot(i32 noundef %0, ptr noundef readon ; NOPROFILE-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF18:![0-9]+]] ; NOPROFILE: 4: ; NOPROFILE-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null -; NOPROFILE-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; NOPROFILE-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], false +; NOPROFILE-NEXT: br i1 [[TMP11]], label [[TMP6:%.*]], label [[TMP7:%.*]] ; NOPROFILE: 6: ; NOPROFILE-NEXT: tail call void @llvm.ubsantrap(i8 22) ; NOPROFILE-NEXT: unreachable @@ -199,8 +224,10 @@ define dso_local noundef i32 @branchColdFnHot(i32 noundef %0, ptr noundef readon ; ALL-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF18:![0-9]+]] ; ALL: 4: ; ALL-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null -; ALL-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; ALL-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], true +; ALL-NEXT: br i1 [[TMP11]], 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 @@ -215,7 +242,8 @@ define dso_local noundef i32 @branchColdFnHot(i32 noundef %0, ptr noundef readon ; HOT-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF18:![0-9]+]] ; HOT: 4: ; HOT-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null -; HOT-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; HOT-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], false +; HOT-NEXT: br i1 [[TMP11]], label [[TMP6:%.*]], label [[TMP7:%.*]] ; HOT: 6: ; HOT-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT-NEXT: unreachable @@ -232,7 +260,8 @@ define dso_local noundef i32 @branchColdFnHot(i32 noundef %0, ptr noundef readon ; HOT70-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF18:![0-9]+]] ; HOT70: 4: ; HOT70-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null -; HOT70-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; HOT70-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], false +; HOT70-NEXT: br i1 [[TMP11]], label [[TMP6:%.*]], label [[TMP7:%.*]] ; HOT70: 6: ; HOT70-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT70-NEXT: unreachable @@ -247,7 +276,9 @@ define dso_local noundef i32 @branchColdFnHot(i32 noundef %0, ptr noundef readon br i1 %3, label %9, label %4, !prof !38 4: - %5 = icmp eq ptr %1, null + %chk = icmp eq ptr %1, null + %hot = call i1 @llvm.experimental.hot() + %5 = or i1 %chk, %hot br i1 %5, label %6, label %7 6: @@ -270,7 +301,8 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon ; NOPROFILE-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF19:![0-9]+]] ; NOPROFILE: 4: ; NOPROFILE-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null -; NOPROFILE-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; NOPROFILE-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], false +; NOPROFILE-NEXT: br i1 [[TMP11]], label [[TMP6:%.*]], label [[TMP7:%.*]] ; NOPROFILE: 6: ; NOPROFILE-NEXT: tail call void @llvm.ubsantrap(i8 22) ; NOPROFILE-NEXT: unreachable @@ -287,8 +319,10 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon ; ALL-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF19:![0-9]+]] ; ALL: 4: ; ALL-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null -; ALL-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; ALL-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], true +; ALL-NEXT: br i1 [[TMP11]], 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 @@ -303,8 +337,10 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon ; HOT-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF19:![0-9]+]] ; HOT: 4: ; HOT-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null -; HOT-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; HOT-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], true +; HOT-NEXT: br i1 [[TMP11]], label [[TMP6:%.*]], label [[TMP7:%.*]] ; HOT: 6: +; HOT-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT-NEXT: unreachable ; HOT: 7: ; HOT-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP1]], align 4 @@ -319,7 +355,8 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon ; HOT70-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF19:![0-9]+]] ; HOT70: 4: ; HOT70-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null -; HOT70-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]] +; HOT70-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], false +; HOT70-NEXT: br i1 [[TMP11]], label [[TMP6:%.*]], label [[TMP7:%.*]] ; HOT70: 6: ; HOT70-NEXT: tail call void @llvm.ubsantrap(i8 22) ; HOT70-NEXT: unreachable @@ -334,7 +371,9 @@ define dso_local noundef i32 @branchHotFnCold(i32 nounde... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/84858 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits