summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/AArch64/AArch64TargetMachine.cpp10
-rw-r--r--llvm/test/CodeGen/AArch64/windows-trap.ll17
2 files changed, 27 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index fe2eea65ffe..5168c0c67da 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -263,6 +263,16 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT,
this->Options.NoTrapAfterNoreturn = true;
}
+ if (TT.isOSWindows()) {
+ // Unwinding can get confused if the last instruction in an
+ // exception-handling region (function, funclet, try block, etc.)
+ // is a call.
+ //
+ // FIXME: We could elide the trap if the next instruction would be in
+ // the same region anyway.
+ this->Options.TrapUnreachable = true;
+ }
+
// Enable GlobalISel at or below EnableGlobalISelAt0.
if (getOptLevel() <= EnableGlobalISelAtO)
setGlobalISel(true);
diff --git a/llvm/test/CodeGen/AArch64/windows-trap.ll b/llvm/test/CodeGen/AArch64/windows-trap.ll
new file mode 100644
index 00000000000..5cf0ece48e9
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/windows-trap.ll
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple=aarch64-win32 %s -o - | FileCheck %s
+
+declare void @callee() noreturn
+
+; Make sure the call isn't the last instruction in the function; if it is,
+; unwinding may break.
+;
+; (The instruction after the call doesn't have to be anything in particular,
+; but trapping has the nice side-effect of catching bugs.)
+
+define void @test_unreachable() {
+; CHECK-LABEL: test_unreachable:
+; CHECK: bl callee
+; CHECK-NEXT: brk #0x1
+ call void @callee() noreturn
+ unreachable
+}
OpenPOWER on IntegriCloud