diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1723,6 +1723,9 @@ /// Determine if the call cannot be tail merged. bool cannotMerge() const { return hasFnAttr(Attribute::NoMerge); } + void setCannotMerge() { + addAttribute(AttributeList::FunctionIndex, Attribute::NoMerge); + } /// Determine if the invoke is convergent bool isConvergent() const { return hasFnAttr(Attribute::Convergent); } diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -693,7 +693,6 @@ FunctionCallee AsanMemoryAccessCallbackSized[2][2]; FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset; - InlineAsm *EmptyAsm; Value *LocalDynamicShadow = nullptr; const GlobalsMetadata &GlobalsMD; DenseMap ProcessedAllocas; @@ -913,14 +912,12 @@ bool HasNonEmptyInlineAsm = false; bool HasReturnsTwiceCall = false; - std::unique_ptr EmptyInlineAsm; FunctionStackPoisoner(Function &F, AddressSanitizer &ASan) : F(F), ASan(ASan), DIB(*F.getParent(), /*AllowUnresolved*/ false), C(ASan.C), IntptrTy(ASan.IntptrTy), IntptrPtrTy(PointerType::get(IntptrTy, 0)), Mapping(ASan.Mapping), - StackAlignment(1 << Mapping.Scale), - EmptyInlineAsm(CallInst::Create(ASan.EmptyAsm)) {} + StackAlignment(1 << Mapping.Scale) {} bool runOnFunction() { if (!ClStack) return false; @@ -1082,9 +1079,8 @@ void visitCallBase(CallBase &CB) { if (CallInst *CI = dyn_cast(&CB)) { - HasNonEmptyInlineAsm |= CI->isInlineAsm() && - !CI->isIdenticalTo(EmptyInlineAsm.get()) && - &CB != ASan.LocalDynamicShadow; + HasNonEmptyInlineAsm |= + CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow; HasReturnsTwiceCall |= CI->canReturnTwice(); } } @@ -1621,10 +1617,7 @@ {Addr, ExpVal}); } - // We don't do Call->setDoesNotReturn() because the BB already has - // UnreachableInst at the end. - // This EmptyAsm is required to avoid callback merge. - IRB.CreateCall(EmptyAsm, {}); + Call->setCannotMerge(); return Call; } @@ -2598,10 +2591,6 @@ M.getOrInsertFunction(kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy); AsanPtrSubFunction = M.getOrInsertFunction(kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy); - // We insert an empty inline asm after __asan_report* to avoid callback merge. - EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), - StringRef(""), StringRef(""), - /*hasSideEffects=*/true); if (Mapping.InGlobal) AsanShadowGlobal = M.getOrInsertGlobal("__asan_shadow", ArrayType::get(IRB.getInt8Ty(), 0)); diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -595,9 +595,6 @@ /// Branch weights for origin store. MDNode *OriginStoreWeights; - - /// An empty volatile inline asm that prevents callback merge. - InlineAsm *EmptyAsm; }; void insertModuleCtor(Module &M) { @@ -854,10 +851,6 @@ MemsetFn = M.getOrInsertFunction( "__msan_memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy); - // We insert an empty inline asm after __msan_report* to avoid callback merge. - EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), - StringRef(""), StringRef(""), - /*hasSideEffects=*/true); MsanInstrumentAsmStoreFn = M.getOrInsertFunction("__msan_instrument_asm_store", IRB.getVoidTy(), @@ -1211,8 +1204,7 @@ if (!Origin) Origin = (Value *)IRB.getInt32(0); assert(Origin->getType()->isIntegerTy()); - IRB.CreateCall(MS.WarningFn, Origin); - IRB.CreateCall(MS.EmptyAsm, {}); + IRB.CreateCall(MS.WarningFn, Origin)->setCannotMerge(); // FIXME: Insert UnreachableInst if !MS.Recover? // This may invalidate some of the following checks and needs to be done // at the very end. diff --git a/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll b/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll --- a/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/msan_basic.ll @@ -95,7 +95,6 @@ ; CHECK: call void @__msan_warning_with_origin_noreturn(i32 ; CHECK-ORIGINS-SAME %[[ORIGIN]]) ; CHECK-CONT: -; CHECK-NEXT: call void asm sideeffect ; CHECK-NEXT: unreachable ; CHECK: br i1 %tobool ; CHECK: ret void