summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2019-12-19 14:03:22 -0800
committerVedant Kumar <vsk@apple.com>2019-12-19 14:06:24 -0800
commitcaaacb83995057b5226db97e5781b6f5f8d5c2b7 (patch)
tree93df69116ff9e90ae374634507309fc744c666ea /llvm
parent8277c91cf3427347626e276fec20a68c0662e49d (diff)
downloadbcm5719-llvm-caaacb83995057b5226db97e5781b6f5f8d5c2b7.tar.gz
bcm5719-llvm-caaacb83995057b5226db97e5781b6f5f8d5c2b7.zip
HotColdSplitting: Do not outline within noreturn functions
A function marked `noreturn` may contain unreachable terminators: these should not be considered cold, as the function may be a trampoline. rdar://58068594
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/IPO/HotColdSplitting.cpp5
-rw-r--r--llvm/test/Transforms/HotColdSplit/noreturn.ll20
2 files changed, 25 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
index 2bd3df3add7..5e690714bfd 100644
--- a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
+++ b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
@@ -207,6 +207,11 @@ bool HotColdSplitting::shouldOutlineFrom(const Function &F) const {
if (F.hasFnAttribute(Attribute::NoInline))
return false;
+ // A function marked `noreturn` may contain unreachable terminators: these
+ // should not be considered cold, as the function may be a trampoline.
+ if (F.hasFnAttribute(Attribute::NoReturn))
+ return false;
+
if (F.hasFnAttribute(Attribute::SanitizeAddress) ||
F.hasFnAttribute(Attribute::SanitizeHWAddress) ||
F.hasFnAttribute(Attribute::SanitizeThread) ||
diff --git a/llvm/test/Transforms/HotColdSplit/noreturn.ll b/llvm/test/Transforms/HotColdSplit/noreturn.ll
index ca0f58815bf..74f4cb18c7f 100644
--- a/llvm/test/Transforms/HotColdSplit/noreturn.ll
+++ b/llvm/test/Transforms/HotColdSplit/noreturn.ll
@@ -23,6 +23,24 @@ define void @foo(i32, %struct.__jmp_buf_tag*) {
ret void
}
+; Don't outline within a noreturn function.
+
+; CHECK: define {{.*}}@xpc_objc_main(i32 {{.*}}) [[XPC_OBJC_MAIN_ATTRS:#[0-9]+]]
+; CHECK-NOT: xpc_objc_main.cold.1
+define void @xpc_objc_main(i32) noreturn {
+ %2 = icmp eq i32 %0, 0
+ tail call void @_Z10sideeffectv()
+ br i1 %2, label %4, label %3
+
+; <label>:3: ; preds = %2
+ call void @_Z10sideeffectv()
+ unreachable
+
+; <label>:4: ; preds = %2
+ ; Crash with an error message, "not supposed to return".
+ unreachable
+}
+
; Do outline noreturn calls marked cold.
; CHECK-LABEL: define {{.*}}@bar(
@@ -62,6 +80,8 @@ define void @baz(i32, %struct.__jmp_buf_tag*) {
; CHECK-LABEL: define {{.*}}@bar.cold.1(
; CHECK: call {{.*}}@llvm.trap(
+; CHECK: attributes [[XPC_OBJC_MAIN_ATTRS]] = { noreturn }
+
declare void @sink() cold
declare void @llvm.trap() noreturn cold
OpenPOWER on IntegriCloud