Skip to content

Commit 6a822e2

Browse files
committed
[ASan][MSan] Remove EmptyAsm and set the CallInst to nomerge to avoid from merging.
Summary: `nomerge` attribute was added at D78659. So, we can remove the EmptyAsm workaround in ASan the MSan and use this attribute. Reviewers: vitalybuka Reviewed By: vitalybuka Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D82322
1 parent be494ad commit 6a822e2

File tree

10 files changed

+16
-44
lines changed

10 files changed

+16
-44
lines changed

llvm/include/llvm/IR/InstrTypes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,6 +1723,9 @@ class CallBase : public Instruction {
17231723

17241724
/// Determine if the call cannot be tail merged.
17251725
bool cannotMerge() const { return hasFnAttr(Attribute::NoMerge); }
1726+
void setCannotMerge() {
1727+
addAttribute(AttributeList::FunctionIndex, Attribute::NoMerge);
1728+
}
17261729

17271730
/// Determine if the invoke is convergent
17281731
bool isConvergent() const { return hasFnAttr(Attribute::Convergent); }

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,6 @@ struct AddressSanitizer {
693693
FunctionCallee AsanMemoryAccessCallbackSized[2][2];
694694

695695
FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
696-
InlineAsm *EmptyAsm;
697696
Value *LocalDynamicShadow = nullptr;
698697
const GlobalsMetadata &GlobalsMD;
699698
DenseMap<const AllocaInst *, bool> ProcessedAllocas;
@@ -911,16 +910,14 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
911910
using AllocaForValueMapTy = DenseMap<Value *, AllocaInst *>;
912911
AllocaForValueMapTy AllocaForValue;
913912

914-
bool HasNonEmptyInlineAsm = false;
913+
bool HasInlineAsm = false;
915914
bool HasReturnsTwiceCall = false;
916-
std::unique_ptr<CallInst> EmptyInlineAsm;
917915

918916
FunctionStackPoisoner(Function &F, AddressSanitizer &ASan)
919917
: F(F), ASan(ASan), DIB(*F.getParent(), /*AllowUnresolved*/ false),
920918
C(ASan.C), IntptrTy(ASan.IntptrTy),
921919
IntptrPtrTy(PointerType::get(IntptrTy, 0)), Mapping(ASan.Mapping),
922-
StackAlignment(1 << Mapping.Scale),
923-
EmptyInlineAsm(CallInst::Create(ASan.EmptyAsm)) {}
920+
StackAlignment(1 << Mapping.Scale) {}
924921

925922
bool runOnFunction() {
926923
if (!ClStack) return false;
@@ -1082,9 +1079,7 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
10821079

10831080
void visitCallBase(CallBase &CB) {
10841081
if (CallInst *CI = dyn_cast<CallInst>(&CB)) {
1085-
HasNonEmptyInlineAsm |= CI->isInlineAsm() &&
1086-
!CI->isIdenticalTo(EmptyInlineAsm.get()) &&
1087-
&CB != ASan.LocalDynamicShadow;
1082+
HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
10881083
HasReturnsTwiceCall |= CI->canReturnTwice();
10891084
}
10901085
}
@@ -1621,10 +1616,7 @@ Instruction *AddressSanitizer::generateCrashCode(Instruction *InsertBefore,
16211616
{Addr, ExpVal});
16221617
}
16231618

1624-
// We don't do Call->setDoesNotReturn() because the BB already has
1625-
// UnreachableInst at the end.
1626-
// This EmptyAsm is required to avoid callback merge.
1627-
IRB.CreateCall(EmptyAsm, {});
1619+
Call->setCannotMerge();
16281620
return Call;
16291621
}
16301622

@@ -2598,10 +2590,6 @@ void AddressSanitizer::initializeCallbacks(Module &M) {
25982590
M.getOrInsertFunction(kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy);
25992591
AsanPtrSubFunction =
26002592
M.getOrInsertFunction(kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy);
2601-
// We insert an empty inline asm after __asan_report* to avoid callback merge.
2602-
EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
2603-
StringRef(""), StringRef(""),
2604-
/*hasSideEffects=*/true);
26052593
if (Mapping.InGlobal)
26062594
AsanShadowGlobal = M.getOrInsertGlobal("__asan_shadow",
26072595
ArrayType::get(IRB.getInt8Ty(), 0));
@@ -3205,8 +3193,8 @@ void FunctionStackPoisoner::processStaticAllocas() {
32053193
// 2) There is a returns_twice call (typically setjmp), which is
32063194
// optimization-hostile, and doesn't play well with introduced indirect
32073195
// register-relative calculation of local variable addresses.
3208-
DoDynamicAlloca &= !HasNonEmptyInlineAsm && !HasReturnsTwiceCall;
3209-
DoStackMalloc &= !HasNonEmptyInlineAsm && !HasReturnsTwiceCall;
3196+
DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
3197+
DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
32103198

32113199
Value *StaticAlloca =
32123200
DoDynamicAlloca ? nullptr : createAllocaForLayout(IRB, L, false);

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,6 @@ class MemorySanitizer {
595595

596596
/// Branch weights for origin store.
597597
MDNode *OriginStoreWeights;
598-
599-
/// An empty volatile inline asm that prevents callback merge.
600-
InlineAsm *EmptyAsm;
601598
};
602599

603600
void insertModuleCtor(Module &M) {
@@ -854,10 +851,6 @@ void MemorySanitizer::initializeCallbacks(Module &M) {
854851
MemsetFn = M.getOrInsertFunction(
855852
"__msan_memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(),
856853
IntptrTy);
857-
// We insert an empty inline asm after __msan_report* to avoid callback merge.
858-
EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
859-
StringRef(""), StringRef(""),
860-
/*hasSideEffects=*/true);
861854

862855
MsanInstrumentAsmStoreFn =
863856
M.getOrInsertFunction("__msan_instrument_asm_store", IRB.getVoidTy(),
@@ -1211,8 +1204,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
12111204
if (!Origin)
12121205
Origin = (Value *)IRB.getInt32(0);
12131206
assert(Origin->getType()->isIntegerTy());
1214-
IRB.CreateCall(MS.WarningFn, Origin);
1215-
IRB.CreateCall(MS.EmptyAsm, {});
1207+
IRB.CreateCall(MS.WarningFn, Origin)->setCannotMerge();
12161208
// FIXME: Insert UnreachableInst if !MS.Recover?
12171209
// This may invalidate some of the following checks and needs to be done
12181210
// at the very end.

llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,6 @@ class ModuleSanitizerCoverage {
250250
FunctionCallee SanCovTraceGepFunction;
251251
FunctionCallee SanCovTraceSwitchFunction;
252252
GlobalVariable *SanCovLowestStack;
253-
InlineAsm *EmptyAsm;
254253
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
255254
*Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy;
256255
Module *CurModule;
@@ -485,11 +484,6 @@ bool ModuleSanitizerCoverage::instrumentModule(
485484
if (Options.StackDepth && !SanCovLowestStack->isDeclaration())
486485
SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy));
487486

488-
// We insert an empty inline asm after cov callbacks to avoid callback merge.
489-
EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
490-
StringRef(""), StringRef(""),
491-
/*hasSideEffects=*/true);
492-
493487
SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy);
494488
SanCovTracePCGuard =
495489
M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy);
@@ -921,16 +915,15 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
921915
IRBuilder<> IRB(&*IP);
922916
IRB.SetCurrentDebugLocation(EntryLoc);
923917
if (Options.TracePC) {
924-
IRB.CreateCall(SanCovTracePC); // gets the PC using GET_CALLER_PC.
925-
IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
918+
IRB.CreateCall(SanCovTracePC)
919+
->setCannotMerge(); // gets the PC using GET_CALLER_PC.
926920
}
927921
if (Options.TracePCGuard) {
928922
auto GuardPtr = IRB.CreateIntToPtr(
929923
IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
930924
ConstantInt::get(IntptrTy, Idx * 4)),
931925
Int32PtrTy);
932-
IRB.CreateCall(SanCovTracePCGuard, GuardPtr);
933-
IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge.
926+
IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
934927
}
935928
if (Options.Inline8bitCounters) {
936929
auto CounterPtr = IRB.CreateGEP(

llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ declare void @foo(...)
9595
; CHECK: call void @__msan_warning_with_origin_noreturn(i32
9696
; CHECK-ORIGINS-SAME %[[ORIGIN]])
9797
; CHECK-CONT:
98-
; CHECK-NEXT: call void asm sideeffect
9998
; CHECK-NEXT: unreachable
10099
; CHECK: br i1 %tobool
101100
; CHECK: ret void

llvm/test/Instrumentation/SanitizerCoverage/coverage-dbg.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
; and add sanitize_address to @_ZN1A1fEv
1717

1818
; Test that __sanitizer_cov_trace_pc_guard call has !dbg pointing to the opening { of A::f().
19-
; CHECK: call void @__sanitizer_cov_trace_pc_guard(i32*{{.*}}), !dbg [[A:!.*]]
19+
; CHECK: call void @__sanitizer_cov_trace_pc_guard(i32*{{.*}}) #{{.*}}, !dbg [[A:!.*]]
2020
; CHECK: [[A]] = !DILocation(line: 6, scope: !{{.*}})
2121

2222

llvm/test/Instrumentation/SanitizerCoverage/coverage.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ entry:
8585

8686
; CHECK_TRACE_PC-LABEL: define void @foo
8787
; CHECK_TRACE_PC: call void @__sanitizer_cov_trace_pc
88-
; CHECK_TRACE_PC: call void asm sideeffect "", ""()
8988
; CHECK_TRACE_PC: ret void
9089

9190
; CHECK_TRACE_PC-LABEL: define void @CallViaVptr

llvm/test/Instrumentation/SanitizerCoverage/coverage2-dbg.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ target triple = "x86_64-unknown-linux-gnu"
1818
; Check that __sanitizer_cov call has !dgb pointing to the beginning
1919
; of appropriate basic blocks.
2020
; CHECK-LABEL:_Z3fooPi
21-
; CHECK: call void @__sanitizer_cov{{.*}}(i32*{{.*}}), !dbg [[A:!.*]]
22-
; CHECK: call void @__sanitizer_cov{{.*}}(i32*{{.*}}), !dbg [[B:!.*]]
21+
; CHECK: call void @__sanitizer_cov{{.*}}(i32*{{.*}}) #{{.*}}, !dbg [[A:!.*]]
22+
; CHECK: call void @__sanitizer_cov{{.*}}(i32*{{.*}}) #{{.*}}, !dbg [[B:!.*]]
2323
; CHECK: ret void
2424
; CHECK: [[A]] = !DILocation(line: 1, scope: !{{.*}})
2525
; CHECK: [[B]] = !DILocation(line: 3, column: 5, scope: !{{.*}})

llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-comdat.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ entry:
3131

3232
; CHECK_TRACE_PC_GUARD-LABEL: define void @foo
3333
; CHECK_TRACE_PC_GUARD: call void @__sanitizer_cov_trace_pc
34-
; CHECK_TRACE_PC_GUARD: call void asm sideeffect "", ""()
3534
; CHECK_TRACE_PC_GUARD: ret void
3635

3736
; CHECK_TRACE_PC_GUARD-LABEL: define void @CallViaVptr

llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-nocomdat.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ entry:
3131

3232
; CHECK_TRACE_PC_GUARD-LABEL: define void @foo
3333
; CHECK_TRACE_PC_GUARD: call void @__sanitizer_cov_trace_pc
34-
; CHECK_TRACE_PC_GUARD: call void asm sideeffect "", ""()
3534
; CHECK_TRACE_PC_GUARD: ret void
3635

3736
; CHECK_TRACE_PC_GUARD-LABEL: define void @CallViaVptr

0 commit comments

Comments
 (0)