[llvm] [HWASan] add optimization remarks for ignoreAccess (PR #94551)
Florian Mayer via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 5 18:22:00 PDT 2024
https://github.com/fmayer created https://github.com/llvm/llvm-project/pull/94551
None
>From e0b15a73e1c739bd27569c4f8fc7d33223d40285 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Wed, 5 Jun 2024 18:21:39 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
---
.../Instrumentation/HWAddressSanitizer.cpp | 58 ++++++++++++++-----
.../stack-safety-analysis.ll | 23 +++++++-
2 files changed, 66 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 2aa21759d56e0..38030a65a3563 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -337,13 +337,17 @@ class HWAddressSanitizer {
unsigned AccessSizeIndex,
Instruction *InsertBefore, DomTreeUpdater &DTU,
LoopInfo *LI);
- bool ignoreMemIntrinsic(MemIntrinsic *MI);
+ bool ignoreMemIntrinsic(OptimizationRemarkEmitter &ORE, MemIntrinsic *MI);
void instrumentMemIntrinsic(MemIntrinsic *MI);
bool instrumentMemAccess(InterestingMemoryOperand &O, DomTreeUpdater &DTU,
LoopInfo *LI);
bool ignoreAccess(Instruction *Inst, Value *Ptr);
+ bool ignoreAccessWithRemark(OptimizationRemarkEmitter &ORE, Instruction *Inst,
+ Value *Ptr);
+
void getInterestingMemoryOperands(
- Instruction *I, const TargetLibraryInfo &TLI,
+ OptimizationRemarkEmitter &ORE, Instruction *I,
+ const TargetLibraryInfo &TLI,
SmallVectorImpl<InterestingMemoryOperand> &Interesting);
void tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag, size_t Size);
@@ -795,8 +799,23 @@ bool HWAddressSanitizer::ignoreAccess(Instruction *Inst, Value *Ptr) {
return false;
}
+bool HWAddressSanitizer::ignoreAccessWithRemark(OptimizationRemarkEmitter &ORE,
+ Instruction *Inst, Value *Ptr) {
+ bool Ignored = ignoreAccess(Inst, Ptr);
+ if (Ignored) {
+ ORE.emit(
+ [&]() { return OptimizationRemark(DEBUG_TYPE, "ignoreAccess", Inst); });
+ } else {
+ ORE.emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "ignoreAccess", Inst);
+ });
+ }
+ return Ignored;
+}
+
void HWAddressSanitizer::getInterestingMemoryOperands(
- Instruction *I, const TargetLibraryInfo &TLI,
+ OptimizationRemarkEmitter &ORE, Instruction *I,
+ const TargetLibraryInfo &TLI,
SmallVectorImpl<InterestingMemoryOperand> &Interesting) {
// Skip memory accesses inserted by another instrumentation.
if (I->hasMetadata(LLVMContext::MD_nosanitize))
@@ -807,22 +826,26 @@ void HWAddressSanitizer::getInterestingMemoryOperands(
return;
if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
- if (!ClInstrumentReads || ignoreAccess(I, LI->getPointerOperand()))
+ if (!ClInstrumentReads ||
+ ignoreAccessWithRemark(ORE, I, LI->getPointerOperand()))
return;
Interesting.emplace_back(I, LI->getPointerOperandIndex(), false,
LI->getType(), LI->getAlign());
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
- if (!ClInstrumentWrites || ignoreAccess(I, SI->getPointerOperand()))
+ if (!ClInstrumentWrites ||
+ ignoreAccessWithRemark(ORE, I, SI->getPointerOperand()))
return;
Interesting.emplace_back(I, SI->getPointerOperandIndex(), true,
SI->getValueOperand()->getType(), SI->getAlign());
} else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
- if (!ClInstrumentAtomics || ignoreAccess(I, RMW->getPointerOperand()))
+ if (!ClInstrumentAtomics ||
+ ignoreAccessWithRemark(ORE, I, RMW->getPointerOperand()))
return;
Interesting.emplace_back(I, RMW->getPointerOperandIndex(), true,
RMW->getValOperand()->getType(), std::nullopt);
} else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
- if (!ClInstrumentAtomics || ignoreAccess(I, XCHG->getPointerOperand()))
+ if (!ClInstrumentAtomics ||
+ ignoreAccessWithRemark(ORE, I, XCHG->getPointerOperand()))
return;
Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true,
XCHG->getCompareOperand()->getType(),
@@ -830,7 +853,7 @@ void HWAddressSanitizer::getInterestingMemoryOperands(
} else if (auto *CI = dyn_cast<CallInst>(I)) {
for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) ||
- ignoreAccess(I, CI->getArgOperand(ArgNo)))
+ ignoreAccessWithRemark(ORE, I, CI->getArgOperand(ArgNo)))
continue;
Type *Ty = CI->getParamByValType(ArgNo);
Interesting.emplace_back(I, ArgNo, false, Ty, Align(1));
@@ -1035,13 +1058,17 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
->setSuccessor(0, TCI.TagMismatchTerm->getParent());
}
-bool HWAddressSanitizer::ignoreMemIntrinsic(MemIntrinsic *MI) {
+bool HWAddressSanitizer::ignoreMemIntrinsic(OptimizationRemarkEmitter &ORE,
+ MemIntrinsic *MI) {
if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) {
- return (!ClInstrumentWrites || ignoreAccess(MTI, MTI->getDest())) &&
- (!ClInstrumentReads || ignoreAccess(MTI, MTI->getSource()));
+ return (!ClInstrumentWrites ||
+ ignoreAccessWithRemark(ORE, MTI, MTI->getDest())) &&
+ (!ClInstrumentReads ||
+ ignoreAccessWithRemark(ORE, MTI, MTI->getSource()));
}
if (isa<MemSetInst>(MI))
- return !ClInstrumentWrites || ignoreAccess(MI, MI->getDest());
+ return !ClInstrumentWrites ||
+ ignoreAccessWithRemark(ORE, MI, MI->getDest());
return false;
}
@@ -1541,6 +1568,9 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
NumTotalFuncs++;
+ OptimizationRemarkEmitter &ORE =
+ FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
+
if (selectiveInstrumentationShouldSkip(F, FAM))
return;
@@ -1562,10 +1592,10 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
if (InstrumentLandingPads && isa<LandingPadInst>(Inst))
LandingPadVec.push_back(&Inst);
- getInterestingMemoryOperands(&Inst, TLI, OperandsToInstrument);
+ getInterestingMemoryOperands(ORE, &Inst, TLI, OperandsToInstrument);
if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&Inst))
- if (!ignoreMemIntrinsic(MI))
+ if (!ignoreMemIntrinsic(ORE, MI))
IntrinToInstrument.push_back(MI);
}
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll b/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll
index dad5f8e2fc56a..8610645a4ca77 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll
@@ -1,4 +1,5 @@
-; RUN: opt -mtriple=aarch64-unknown-linux-gnu -passes=hwasan -hwasan-instrument-with-calls -hwasan-use-stack-safety=1 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=SAFETY,CHECK
+; RUN: opt -pass-remarks-output=%t.pass-remarks -mtriple=aarch64-unknown-linux-gnu -passes=hwasan -hwasan-instrument-with-calls -hwasan-use-stack-safety=1 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=SAFETY,CHECK
+; RUN: cat %t.pass-remarks | FileCheck %s --check-prefixes=SAFETY-REMARKS
; RUN: opt -mtriple=aarch64-unknown-linux-gnu -passes=hwasan -hwasan-instrument-with-calls -hwasan-use-stack-safety=0 -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=NOSAFETY,CHECK
; RUN: opt -mtriple=aarch64-unknown-linux-gnu -passes=hwasan -hwasan-instrument-with-calls -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=SAFETY,CHECK
; RUN: opt -mtriple=aarch64-unknown-linux-gnu -passes=hwasan -hwasan-instrument-stack=0 -hwasan-instrument-with-calls -hwasan-generate-tags-with-calls -S < %s | FileCheck %s --check-prefixes=NOSTACK,CHECK
@@ -20,6 +21,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_simple
%buf.sroa.0 = alloca i8, align 4
call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %buf.sroa.0)
store volatile i8 0, ptr %buf.sroa.0, align 4, !tbaa !8
@@ -37,6 +39,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_cmpxchg
%buf.sroa.0 = alloca i8, align 4
call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %buf.sroa.0)
%0 = cmpxchg ptr %buf.sroa.0, i8 1, i8 2 monotonic monotonic, align 4
@@ -54,6 +57,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_atomicrwm
%buf.sroa.0 = alloca i8, align 4
call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %buf.sroa.0)
%0 = atomicrmw add ptr %buf.sroa.0, i8 1 monotonic, align 4
@@ -71,6 +75,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_use
%buf.sroa.0 = alloca i8, align 4
call void @use(ptr nonnull %buf.sroa.0)
call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %buf.sroa.0)
@@ -89,6 +94,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_in_range
%buf.sroa.0 = alloca [10 x i8], align 4
call void @llvm.lifetime.start.p0(i64 10, ptr nonnull %buf.sroa.0)
store volatile i8 0, ptr %buf.sroa.0, align 4, !tbaa !8
@@ -106,6 +112,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_in_range2
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 9
call void @llvm.lifetime.start.p0(i64 10, ptr nonnull %buf.sroa.0)
@@ -123,6 +130,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_memset
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_memset
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_in_range3
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 9
call void @llvm.memset.p0.i32(ptr %ptr, i8 0, i32 1, i1 true)
@@ -138,6 +146,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_memmove
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_memmove
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_in_range4
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 9
call void @llvm.memmove.p0.p0.i32(ptr %ptr, ptr %ptr, i32 1, i1 true)
@@ -153,6 +162,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_memmove
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_memmove
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_in_range5
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 9
%buf.sroa.1 = alloca [10 x i8], align 4
@@ -171,6 +181,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_out_of_range
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 10
call void @llvm.lifetime.start.p0(i64 10, ptr nonnull %buf.sroa.0)
@@ -188,6 +199,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_out_of_range2
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 10
call void @llvm.lifetime.start.p0(i64 10, ptr nonnull %buf.sroa.0)
@@ -205,6 +217,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_memset
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_memset
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_out_of_range3
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 9
call void @llvm.memset.p0.i32(ptr %ptr, i8 0, i32 2, i1 true)
@@ -220,6 +233,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_memmove
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_memmove
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_out_of_range4
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 9
call void @llvm.memmove.p0.p0.i32(ptr %ptr, ptr %ptr, i32 2, i1 true)
@@ -235,6 +249,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_memmove
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_memmove
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_out_of_range5
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 9
%buf.sroa.1 = alloca [10 x i8], align 4
@@ -256,6 +271,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_out_of_range6
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 10
call void @llvm.lifetime.start.p0(i64 10, ptr nonnull %buf.sroa.0)
@@ -275,6 +291,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_potentially_out_of_range
%buf.sroa.0 = alloca [10 x i8], align 4
%off = call i32 @getoffset()
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 %off
@@ -293,6 +310,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_memmove
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK: call {{.*}}__hwasan_memmove
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_potentially_out_of_range2
%buf.sroa.0 = alloca [10 x i8], align 4
%ptr = getelementptr [10 x i8], ptr %buf.sroa.0, i32 0, i32 9
call void @llvm.memmove.p0.p0.i32(ptr %ptr, ptr %a, i32 1, i1 true)
@@ -309,6 +327,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_unclear
%buf.sroa.0 = alloca i8, align 4
%ptr = call ptr @getptr(ptr %buf.sroa.0)
call void @llvm.lifetime.start.p0(i64 10, ptr nonnull %ptr)
@@ -326,6 +345,7 @@ entry:
; SAFETY: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Missed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_select
%x = call ptr @getptr(ptr %a)
%buf.sroa.0 = alloca i8, align 4
call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %buf.sroa.0)
@@ -346,6 +366,7 @@ entry:
; SAFETY-NOT: call {{.*}}__hwasan_store
; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag
; NOSTACK-NOT: call {{.*}}__hwasan_store
+ ; SAFETY-REMARKS: --- !Passed{{[[:space:]]}}Pass: hwasan{{[[:space:]]}}Name: ignoreAccess{{[[:space:]]}}Function: test_retptr
%buf.sroa.0 = alloca i8, align 4
call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %buf.sroa.0)
%ptr = call ptr @retptr(ptr %buf.sroa.0)
More information about the llvm-commits
mailing list