[clang] [llvm] [clang][ubsan] Switch UBSAN optimization to `llvm.allow.{runtime,ubsan}.check()` (PR #84858)
Vitaly Buka via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 4 17:38:33 PDT 2024
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/84858
>From 014644897f25ed88a1e17192531cf92110758470 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Mon, 11 Mar 2024 16:58:15 -0700
Subject: [PATCH] [clang][ubsan] Switch UBSAN optimization to
`llvm.allow.{runtime,ubsan}.check()`
Intrinsic introduced with #84850. Intrinsics improves performance
by 3% comparing to removing traps (on
"test-suite/MultiSource/Benchmarks" with PGO+ThinLTO).
The pass will be renamed with #84853.
RFC: https://discourse.llvm.org/t/rfc-add-llvm-experimental-hot-intrinsic-or-llvm-hot/77641
Reviewers: aeubanks, nikic, kstoimenov, dvyukov
Reviewed By: kstoimenov
Pull Request: https://github.com/llvm/llvm-project/pull/84858
---
clang/test/CodeGen/remote-traps.c | 37 ------
.../Instrumentation/RemoveTrapsPass.cpp | 27 ++--
.../Transforms/RemoveTraps/remove-traps.ll | 115 ++++++++++++++----
3 files changed, 107 insertions(+), 72 deletions(-)
delete mode 100644 clang/test/CodeGen/remote-traps.c
diff --git a/clang/test/CodeGen/remote-traps.c b/clang/test/CodeGen/remote-traps.c
deleted file mode 100644
index b12c2c6e23b2d1..00000000000000
--- a/clang/test/CodeGen/remote-traps.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
-// 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 -remove-traps-random-rate=1 %s -o - | FileCheck %s --implicit-check-not="call void @llvm.ubsantrap" --check-prefixes=REMOVE
-
-// CHECK-LABEL: define dso_local noundef i32 @test(
-// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-// CHECK-NEXT: entry:
-// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 123), !nosanitize [[META2:![0-9]+]]
-// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
-// CHECK-NEXT: br i1 [[TMP1]], label [[TRAP:%.*]], label [[CONT:%.*]], !nosanitize [[META2]]
-// CHECK: trap:
-// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR3:[0-9]+]], !nosanitize [[META2]]
-// CHECK-NEXT: unreachable, !nosanitize [[META2]]
-// CHECK: cont:
-// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
-// CHECK-NEXT: ret i32 [[TMP2]]
-//
-// REMOVE-LABEL: define dso_local noundef i32 @test(
-// REMOVE-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-// REMOVE-NEXT: entry:
-// REMOVE-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 123), !nosanitize [[META2:![0-9]+]]
-// REMOVE-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]]
-// REMOVE-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true
-// REMOVE-NEXT: tail call void @llvm.assume(i1 [[TMP2]])
-// REMOVE-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]]
-// REMOVE-NEXT: ret i32 [[TMP3]]
-//
-int test(int x) {
- return x + 123;
-}
-
-
-//.
-// CHECK: [[META2]] = !{}
-//.
-// REMOVE: [[META2]] = !{}
-//.
diff --git a/llvm/lib/Transforms/Instrumentation/RemoveTrapsPass.cpp b/llvm/lib/Transforms/Instrumentation/RemoveTrapsPass.cpp
index b281468cb84ee1..6adc29f8572b54 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"
@@ -35,9 +36,11 @@ 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 *, bool>, 16> ReplaceWithValue;
std::unique_ptr<RandomNumberGenerator> Rng;
+ // TODO:
+ // https://github.com/llvm/llvm-project/pull/84858#discussion_r1520603139
auto ShouldRemove = [&](bool IsHot) {
if (!RandomRate.getNumOccurrences())
return IsHot;
@@ -54,21 +57,23 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI,
continue;
auto ID = II->getIntrinsicID();
switch (ID) {
- case Intrinsic::ubsantrap: {
+ case Intrinsic::allow_ubsan_check:
+ case Intrinsic::allow_runtime_check: {
++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 = PSI->isHotCountNthPercentile(HotPercentileCutoff, Count);
}
- if (ShouldRemove(IsHot)) {
- Remove.push_back(II);
+ bool ToRemove = ShouldRemove(IsHot);
+ ReplaceWithValue.push_back({
+ II,
+ ToRemove,
+ });
+ if (ToRemove)
++NumChecksRemoved;
- }
break;
}
default:
@@ -77,10 +82,12 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI,
}
}
- for (IntrinsicInst *I : Remove)
+ for (auto [I, V] : ReplaceWithValue) {
+ I->replaceAllUsesWith(ConstantInt::getBool(I->getType(), !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 4853149f955b09..c8d5fecbf55a64 100644
--- a/llvm/test/Transforms/RemoveTraps/remove-traps.ll
+++ b/llvm/test/Transforms/RemoveTraps/remove-traps.ll
@@ -7,12 +7,15 @@
target triple = "x86_64-pc-linux-gnu"
declare void @llvm.ubsantrap(i8 immarg)
+declare i1 @llvm.allow.ubsan.check(i8 immarg)
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: [[HOT:%.*]] = xor i1 true, true
+; NOPROFILE-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; 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 +26,11 @@ 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: [[HOT:%.*]] = xor i1 false, true
+; ALL-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; 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 +39,9 @@ define dso_local noundef i32 @simple(ptr noundef readonly %0) {
; HOT99-LABEL: define dso_local noundef i32 @simple(
; HOT99-SAME: ptr noundef readonly [[TMP0:%.*]]) {
; HOT99-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null
-; HOT99-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
+; HOT99-NEXT: [[HOT:%.*]] = xor i1 true, true
+; HOT99-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; HOT99-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]]
; HOT99: 3:
; HOT99-NEXT: tail call void @llvm.ubsantrap(i8 22)
; HOT99-NEXT: unreachable
@@ -44,7 +52,9 @@ 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: [[HOT:%.*]] = xor i1 true, true
+; HOT70-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; 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 +62,10 @@ 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
+ %allow = call i1 @llvm.allow.ubsan.check(i8 22)
+ %hot = xor i1 %allow, true
+ %2 = or i1 %chk, %hot
br i1 %2, label %3, label %4
3:
@@ -69,7 +82,9 @@ 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: [[HOT:%.*]] = xor i1 true, true
+; NOPROFILE-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; 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 +95,11 @@ 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: [[HOT:%.*]] = xor i1 false, true
+; ALL-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; 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 +108,11 @@ define dso_local noundef i32 @hot(ptr noundef readonly %0) !prof !36 {
; 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
-; HOT99-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
+; HOT99-NEXT: [[HOT:%.*]] = xor i1 false, true
+; HOT99-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; HOT99-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]]
; HOT99: 3:
+; HOT99-NEXT: tail call void @llvm.ubsantrap(i8 22)
; HOT99-NEXT: unreachable
; HOT99: 4:
; HOT99-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4
@@ -100,7 +121,9 @@ 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: [[HOT:%.*]] = xor i1 true, true
+; HOT70-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; 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 +131,10 @@ 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
+ %allow = call i1 @llvm.allow.ubsan.check(i8 22)
+ %hot = xor i1 %allow, true
+ %2 = or i1 %chk, %hot
br i1 %2, label %3, label %4
3:
@@ -124,7 +150,9 @@ 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: [[HOT:%.*]] = xor i1 true, true
+; NOPROFILE-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; 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 +163,11 @@ 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: [[HOT:%.*]] = xor i1 false, true
+; ALL-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; 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 +176,11 @@ define dso_local noundef i32 @veryHot(ptr noundef readonly %0) !prof !39 {
; 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
-; HOT99-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
+; HOT99-NEXT: [[HOT:%.*]] = xor i1 false, true
+; HOT99-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; HOT99-NEXT: br i1 [[TMP6]], label [[TMP3:%.*]], label [[TMP4:%.*]]
; HOT99: 3:
+; HOT99-NEXT: tail call void @llvm.ubsantrap(i8 22)
; HOT99-NEXT: unreachable
; HOT99: 4:
; HOT99-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP0]], align 4
@@ -155,14 +189,20 @@ 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: [[HOT:%.*]] = xor i1 false, true
+; HOT70-NEXT: [[TMP6:%.*]] = or i1 [[TMP2]], [[HOT]]
+; 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
+ %allow = call i1 @llvm.allow.ubsan.check(i8 22)
+ %hot = xor i1 %allow, true
+ %2 = or i1 %chk, %hot
br i1 %2, label %3, label %4
3:
@@ -182,7 +222,9 @@ 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: [[HOT:%.*]] = xor i1 true, true
+; NOPROFILE-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], [[HOT]]
+; 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 +241,11 @@ 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: [[HOT:%.*]] = xor i1 false, true
+; ALL-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], [[HOT]]
+; 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 +260,9 @@ define dso_local noundef i32 @branchColdFnHot(i32 noundef %0, ptr noundef readon
; HOT99-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF18:![0-9]+]]
; HOT99: 4:
; HOT99-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null
-; HOT99-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]]
+; HOT99-NEXT: [[HOT:%.*]] = xor i1 true, true
+; HOT99-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], [[HOT]]
+; HOT99-NEXT: br i1 [[TMP11]], label [[TMP6:%.*]], label [[TMP7:%.*]]
; HOT99: 6:
; HOT99-NEXT: tail call void @llvm.ubsantrap(i8 22)
; HOT99-NEXT: unreachable
@@ -232,7 +279,9 @@ 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: [[HOT:%.*]] = xor i1 true, true
+; HOT70-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], [[HOT]]
+; 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 +296,10 @@ 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
+ %allow = call i1 @llvm.allow.ubsan.check(i8 22)
+ %hot = xor i1 %allow, true
+ %5 = or i1 %chk, %hot
br i1 %5, label %6, label %7
6:
@@ -270,7 +322,9 @@ 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: [[HOT:%.*]] = xor i1 true, true
+; NOPROFILE-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], [[HOT]]
+; 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 +341,11 @@ 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: [[HOT:%.*]] = xor i1 false, true
+; ALL-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], [[HOT]]
+; 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 +360,11 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon
; HOT99-NEXT: br i1 [[TMP3]], label [[TMP9:%.*]], label [[TMP4:%.*]], !prof [[PROF19:![0-9]+]]
; HOT99: 4:
; HOT99-NEXT: [[TMP5:%.*]] = icmp eq ptr [[TMP1]], null
-; HOT99-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP7:%.*]]
+; HOT99-NEXT: [[HOT:%.*]] = xor i1 false, true
+; HOT99-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], [[HOT]]
+; HOT99-NEXT: br i1 [[TMP11]], label [[TMP6:%.*]], label [[TMP7:%.*]]
; HOT99: 6:
+; HOT99-NEXT: tail call void @llvm.ubsantrap(i8 22)
; HOT99-NEXT: unreachable
; HOT99: 7:
; HOT99-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP1]], align 4
@@ -319,7 +379,9 @@ 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: [[HOT:%.*]] = xor i1 true, true
+; HOT70-NEXT: [[TMP11:%.*]] = or i1 [[TMP5]], [[HOT]]
+; 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 +396,10 @@ define dso_local noundef i32 @branchHotFnCold(i32 noundef %0, ptr noundef readon
br i1 %3, label %9, label %4, !prof !37
4:
- %5 = icmp eq ptr %1, null
+ %chk = icmp eq ptr %1, null
+ %allow = call i1 @llvm.allow.ubsan.check(i8 22)
+ %hot = xor i1 %allow, true
+ %5 = or i1 %chk, %hot
br i1 %5, label %6, label %7
6:
More information about the cfe-commits
mailing list