From ed3959a17866fd3ce9742184ae8fa80f5bcd52aa Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 7 Nov 2018 21:31:14 +0000 Subject: [PATCH] [AArch64] [Windows] Trap after noreturn calls. Like the comment says, this isn't the most efficient fix in terms of codesize, but it works. Differential Revision: https://reviews.llvm.org/D54129 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346358 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64TargetMachine.cpp | 10 ++++++++++ test/CodeGen/AArch64/windows-trap.ll | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 test/CodeGen/AArch64/windows-trap.ll diff --git a/lib/Target/AArch64/AArch64TargetMachine.cpp b/lib/Target/AArch64/AArch64TargetMachine.cpp index fe2eea65ffe..5168c0c67da 100644 --- a/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/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/test/CodeGen/AArch64/windows-trap.ll b/test/CodeGen/AArch64/windows-trap.ll new file mode 100644 index 00000000000..5cf0ece48e9 --- /dev/null +++ b/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 +}