Skip to content

Commit d927d18

Browse files
authored
[UBSAN] Emit optimization remarks (#88304)
1 parent acb7ddc commit d927d18

File tree

3 files changed

+70
-6
lines changed

3 files changed

+70
-6
lines changed

llvm/lib/IR/DiagnosticInfo.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,12 @@ DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key,
179179
else if (isa<Constant>(V)) {
180180
raw_string_ostream OS(Val);
181181
V->printAsOperand(OS, /*PrintType=*/false);
182-
} else if (auto *I = dyn_cast<Instruction>(V))
182+
} else if (auto *I = dyn_cast<Instruction>(V)) {
183183
Val = I->getOpcodeName();
184+
} else if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
185+
if (auto *S = dyn_cast<MDString>(MD->getMetadata()))
186+
Val = S->getString();
187+
}
184188
}
185189

186190
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T)

llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@
1010

1111
#include "llvm/ADT/SmallVector.h"
1212
#include "llvm/ADT/Statistic.h"
13+
#include "llvm/ADT/StringRef.h"
14+
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
1315
#include "llvm/Analysis/ProfileSummaryInfo.h"
1416
#include "llvm/IR/Constant.h"
17+
#include "llvm/IR/Constants.h"
18+
#include "llvm/IR/DiagnosticInfo.h"
1519
#include "llvm/IR/Instructions.h"
1620
#include "llvm/IR/IntrinsicInst.h"
1721
#include "llvm/IR/Intrinsics.h"
22+
#include "llvm/IR/Metadata.h"
1823
#include "llvm/Support/RandomNumberGenerator.h"
1924
#include <memory>
2025
#include <random>
@@ -35,13 +40,41 @@ static cl::opt<float>
3540
STATISTIC(NumChecksTotal, "Number of checks");
3641
STATISTIC(NumChecksRemoved, "Number of removed checks");
3742

43+
struct RemarkInfo {
44+
ore::NV Kind;
45+
ore::NV F;
46+
ore::NV BB;
47+
explicit RemarkInfo(IntrinsicInst *II)
48+
: Kind("Kind", II->getArgOperand(0)),
49+
F("Function", II->getParent()->getParent()),
50+
BB("Block", II->getParent()->getName()) {}
51+
};
52+
53+
static void emitRemark(IntrinsicInst *II, OptimizationRemarkEmitter &ORE,
54+
bool Removed) {
55+
if (Removed) {
56+
ORE.emit([&]() {
57+
RemarkInfo Info(II);
58+
return OptimizationRemark(DEBUG_TYPE, "Removed", II)
59+
<< "Removed check: Kind=" << Info.Kind << " F=" << Info.F
60+
<< " BB=" << Info.BB;
61+
});
62+
} else {
63+
ORE.emit([&]() {
64+
RemarkInfo Info(II);
65+
return OptimizationRemarkMissed(DEBUG_TYPE, "Allowed", II)
66+
<< "Allowed check: Kind=" << Info.Kind << " F=" << Info.F
67+
<< " BB=" << Info.BB;
68+
});
69+
}
70+
}
71+
3872
static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI,
39-
const ProfileSummaryInfo *PSI) {
73+
const ProfileSummaryInfo *PSI,
74+
OptimizationRemarkEmitter &ORE) {
4075
SmallVector<std::pair<IntrinsicInst *, bool>, 16> ReplaceWithValue;
4176
std::unique_ptr<RandomNumberGenerator> Rng;
4277

43-
// TODO:
44-
// https://github.com/llvm/llvm-project/pull/84858#discussion_r1520603139
4578
auto ShouldRemove = [&](bool IsHot) {
4679
if (!RandomRate.getNumOccurrences())
4780
return IsHot;
@@ -75,6 +108,7 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI,
75108
});
76109
if (ToRemove)
77110
++NumChecksRemoved;
111+
emitRemark(II, ORE, ToRemove);
78112
break;
79113
}
80114
default:
@@ -99,9 +133,11 @@ PreservedAnalyses LowerAllowCheckPass::run(Function &F,
99133
ProfileSummaryInfo *PSI =
100134
MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
101135
BlockFrequencyInfo &BFI = AM.getResult<BlockFrequencyAnalysis>(F);
136+
OptimizationRemarkEmitter &ORE =
137+
AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
102138

103-
return removeUbsanTraps(F, BFI, PSI) ? PreservedAnalyses::none()
104-
: PreservedAnalyses::all();
139+
return removeUbsanTraps(F, BFI, PSI, ORE) ? PreservedAnalyses::none()
140+
: PreservedAnalyses::all();
105141
}
106142

107143
bool LowerAllowCheckPass::IsRequested() {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: opt < %s -passes='require<profile-summary>,function(lower-allow-check)' -lower-allow-check-random-rate=1 -pass-remarks=lower-allow-check -pass-remarks-missed=lower-allow-check -S 2>&1 | FileCheck %s
2+
; RUN: opt < %s -passes='require<profile-summary>,function(lower-allow-check)' -lower-allow-check-random-rate=0 -pass-remarks=lower-allow-check -pass-remarks-missed=lower-allow-check -S 2>&1 | FileCheck %s --check-prefixes=REMOVE
3+
4+
; CHECK: remark: <unknown>:0:0: Allowed check: Kind=test_check F=test_runtime BB=entry1
5+
; CHECK: remark: <unknown>:0:0: Allowed check: Kind=7 F=test_ubsan BB=entry2
6+
7+
; REMOVE: remark: <unknown>:0:0: Removed check: Kind=test_check F=test_runtime BB=entry1
8+
; REMOVE: remark: <unknown>:0:0: Removed check: Kind=7 F=test_ubsan BB=entry2
9+
10+
target triple = "x86_64-pc-linux-gnu"
11+
12+
define i1 @test_runtime() local_unnamed_addr {
13+
entry1:
14+
%allow = call i1 @llvm.allow.runtime.check(metadata !"test_check")
15+
ret i1 %allow
16+
}
17+
18+
declare i1 @llvm.allow.runtime.check(metadata) nounwind
19+
20+
define i1 @test_ubsan() local_unnamed_addr {
21+
entry2:
22+
%allow = call i1 @llvm.allow.ubsan.check(i8 7)
23+
ret i1 %allow
24+
}

0 commit comments

Comments
 (0)