diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp index 342c4cbbc39d6..31971b179fb4b 100644 --- a/llvm/lib/IR/DiagnosticInfo.cpp +++ b/llvm/lib/IR/DiagnosticInfo.cpp @@ -179,8 +179,12 @@ DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, else if (isa(V)) { raw_string_ostream OS(Val); V->printAsOperand(OS, /*PrintType=*/false); - } else if (auto *I = dyn_cast(V)) + } else if (auto *I = dyn_cast(V)) { Val = I->getOpcodeName(); + } else if (auto *MD = dyn_cast(V)) { + if (auto *S = dyn_cast(MD->getMetadata())) + Val = S->getString(); + } } DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, const Type *T) diff --git a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp index cdc8318f088c2..465fa41b6c663 100644 --- a/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp +++ b/llvm/lib/Transforms/Instrumentation/LowerAllowCheckPass.cpp @@ -10,11 +10,16 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/IR/Constant.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Metadata.h" #include "llvm/Support/RandomNumberGenerator.h" #include #include @@ -35,13 +40,41 @@ static cl::opt STATISTIC(NumChecksTotal, "Number of checks"); STATISTIC(NumChecksRemoved, "Number of removed checks"); +struct RemarkInfo { + ore::NV Kind; + ore::NV F; + ore::NV BB; + explicit RemarkInfo(IntrinsicInst *II) + : Kind("Kind", II->getArgOperand(0)), + F("Function", II->getParent()->getParent()), + BB("Block", II->getParent()->getName()) {} +}; + +static void emitRemark(IntrinsicInst *II, OptimizationRemarkEmitter &ORE, + bool Removed) { + if (Removed) { + ORE.emit([&]() { + RemarkInfo Info(II); + return OptimizationRemark(DEBUG_TYPE, "Removed", II) + << "Removed check: Kind=" << Info.Kind << " F=" << Info.F + << " BB=" << Info.BB; + }); + } else { + ORE.emit([&]() { + RemarkInfo Info(II); + return OptimizationRemarkMissed(DEBUG_TYPE, "Allowed", II) + << "Allowed check: Kind=" << Info.Kind << " F=" << Info.F + << " BB=" << Info.BB; + }); + } +} + static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, - const ProfileSummaryInfo *PSI) { + const ProfileSummaryInfo *PSI, + OptimizationRemarkEmitter &ORE) { SmallVector, 16> ReplaceWithValue; std::unique_ptr Rng; - // TODO: - // https://github.com/llvm/llvm-project/pull/84858#discussion_r1520603139 auto ShouldRemove = [&](bool IsHot) { if (!RandomRate.getNumOccurrences()) return IsHot; @@ -75,6 +108,7 @@ static bool removeUbsanTraps(Function &F, const BlockFrequencyInfo &BFI, }); if (ToRemove) ++NumChecksRemoved; + emitRemark(II, ORE, ToRemove); break; } default: @@ -99,9 +133,11 @@ PreservedAnalyses LowerAllowCheckPass::run(Function &F, ProfileSummaryInfo *PSI = MAMProxy.getCachedResult(*F.getParent()); BlockFrequencyInfo &BFI = AM.getResult(F); + OptimizationRemarkEmitter &ORE = + AM.getResult(F); - return removeUbsanTraps(F, BFI, PSI) ? PreservedAnalyses::none() - : PreservedAnalyses::all(); + return removeUbsanTraps(F, BFI, PSI, ORE) ? PreservedAnalyses::none() + : PreservedAnalyses::all(); } bool LowerAllowCheckPass::IsRequested() { diff --git a/llvm/test/Transforms/lower-builtin-allow-check-remarks.ll b/llvm/test/Transforms/lower-builtin-allow-check-remarks.ll new file mode 100644 index 0000000000000..3422ab1b56d32 --- /dev/null +++ b/llvm/test/Transforms/lower-builtin-allow-check-remarks.ll @@ -0,0 +1,24 @@ +; RUN: opt < %s -passes='require,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 +; RUN: opt < %s -passes='require,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 + +; CHECK: remark: :0:0: Allowed check: Kind=test_check F=test_runtime BB=entry1 +; CHECK: remark: :0:0: Allowed check: Kind=7 F=test_ubsan BB=entry2 + +; REMOVE: remark: :0:0: Removed check: Kind=test_check F=test_runtime BB=entry1 +; REMOVE: remark: :0:0: Removed check: Kind=7 F=test_ubsan BB=entry2 + +target triple = "x86_64-pc-linux-gnu" + +define i1 @test_runtime() local_unnamed_addr { +entry1: + %allow = call i1 @llvm.allow.runtime.check(metadata !"test_check") + ret i1 %allow +} + +declare i1 @llvm.allow.runtime.check(metadata) nounwind + +define i1 @test_ubsan() local_unnamed_addr { +entry2: + %allow = call i1 @llvm.allow.ubsan.check(i8 7) + ret i1 %allow +}