diff options
| -rw-r--r-- | llvm/lib/Transforms/IPO/HotColdSplitting.cpp | 11 | ||||
| -rw-r--r-- | llvm/test/Transforms/HotColdSplit/X86/do-not-split.ll | 72 | 
2 files changed, 81 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp index b8def7ad3ea..a237eb7b4fc 100644 --- a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp +++ b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp @@ -111,10 +111,11 @@ bool unlikelyExecuted(BasicBlock &BB) {    if (BB.isEHPad() || isa<ResumeInst>(BB.getTerminator()))      return true; -  // The block is cold if it calls/invokes a cold function. +  // The block is cold if it calls/invokes a cold function. However, do not +  // mark sanitizer traps as cold.    for (Instruction &I : BB)      if (auto CS = CallSite(&I)) -      if (CS.hasFnAttr(Attribute::Cold)) +      if (CS.hasFnAttr(Attribute::Cold) && !CS->getMetadata("nosanitize"))          return true;    // The block is cold if it has an unreachable terminator, unless it's @@ -235,6 +236,12 @@ bool HotColdSplitting::shouldOutlineFrom(const Function &F) const {    if (F.hasFnAttribute(Attribute::NoInline))      return false; +  if (F.hasFnAttribute(Attribute::SanitizeAddress) || +      F.hasFnAttribute(Attribute::SanitizeHWAddress) || +      F.hasFnAttribute(Attribute::SanitizeThread) || +      F.hasFnAttribute(Attribute::SanitizeMemory)) +    return false; +    return true;  } diff --git a/llvm/test/Transforms/HotColdSplit/X86/do-not-split.ll b/llvm/test/Transforms/HotColdSplit/X86/do-not-split.ll index 448e63ab1de..076174d0a05 100644 --- a/llvm/test/Transforms/HotColdSplit/X86/do-not-split.ll +++ b/llvm/test/Transforms/HotColdSplit/X86/do-not-split.ll @@ -110,6 +110,78 @@ if.end:                                           ; preds = %entry    ret void  } +; CHECK-LABEL: @sanitize_address +; CHECK-NOT: sanitize_address.cold.1 +define void @sanitize_address() sanitize_address { +entry: +  br i1 undef, label %if.then, label %if.end + +if.then:                                          ; preds = %entry +  call void @sink() +  ret void + +if.end:                                           ; preds = %entry +  ret void +} + +; CHECK-LABEL: @sanitize_hwaddress +; CHECK-NOT: sanitize_hwaddress.cold.1 +define void @sanitize_hwaddress() sanitize_hwaddress { +entry: +  br i1 undef, label %if.then, label %if.end + +if.then:                                          ; preds = %entry +  call void @sink() +  ret void + +if.end:                                           ; preds = %entry +  ret void +} + +; CHECK-LABEL: @sanitize_thread +; CHECK-NOT: sanitize_thread.cold.1 +define void @sanitize_thread() sanitize_thread { +entry: +  br i1 undef, label %if.then, label %if.end + +if.then:                                          ; preds = %entry +  call void @sink() +  ret void + +if.end:                                           ; preds = %entry +  ret void +} + +; CHECK-LABEL: @sanitize_memory +; CHECK-NOT: sanitize_memory.cold.1 +define void @sanitize_memory() sanitize_memory { +entry: +  br i1 undef, label %if.then, label %if.end + +if.then:                                          ; preds = %entry +  call void @sink() +  ret void + +if.end:                                           ; preds = %entry +  ret void +} + +declare void @llvm.trap() cold noreturn + +; CHECK-LABEL: @nosanitize_call +; CHECK-NOT: nosanitize_call.cold.1 +define void @nosanitize_call() sanitize_memory { +entry: +  br i1 undef, label %if.then, label %if.end + +if.then:                                          ; preds = %entry +  call void @llvm.trap(), !nosanitize !2 +  unreachable + +if.end:                                           ; preds = %entry +  ret void +} +  declare void @llvm.dbg.value(metadata, metadata, metadata)  declare void @sink() cold  | 

