diff --git a/llvm/lib/CodeGen/LLVMTargetMachine.cpp b/llvm/lib/CodeGen/LLVMTargetMachine.cpp index 7ec8390033fba..87a17b88db124 100644 --- a/llvm/lib/CodeGen/LLVMTargetMachine.cpp +++ b/llvm/lib/CodeGen/LLVMTargetMachine.cpp @@ -37,6 +37,11 @@ static cl::opt EnableTrapUnreachable("trap-unreachable", cl::Hidden, cl::desc("Enable generating trap for unreachable")); +static cl::opt EnableNoTrapAfterNoreturn( + "no-trap-after-noreturn", cl::Hidden, + cl::desc("Do not emit a trap instruction for 'unreachable' IR instructions " + "after noreturn calls, even if --trap-unreachable is set.")); + void LLVMTargetMachine::initAsmInfo() { MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str())); assert(MRI && "Unable to create reg info"); @@ -95,6 +100,8 @@ LLVMTargetMachine::LLVMTargetMachine(const Target &T, if (EnableTrapUnreachable) this->Options.TrapUnreachable = true; + if (EnableNoTrapAfterNoreturn) + this->Options.NoTrapAfterNoreturn = true; } TargetTransformInfo diff --git a/llvm/test/CodeGen/ARM/trap-unreachable.ll b/llvm/test/CodeGen/ARM/trap-unreachable.ll index 605d5a234291a..84dbb04c462b4 100644 --- a/llvm/test/CodeGen/ARM/trap-unreachable.ll +++ b/llvm/test/CodeGen/ARM/trap-unreachable.ll @@ -1,8 +1,36 @@ -; RUN: llc -mtriple=thumbv7 -trap-unreachable < %s | FileCheck %s -; CHECK: .inst.n 0xdefe +; RUN: llc -mtriple=thumbv7 -trap-unreachable < %s | FileCheck %s --check-prefixes CHECK,TRAP_UNREACHABLE +; RUN: llc -mtriple=thumbv7 -trap-unreachable -no-trap-after-noreturn < %s | FileCheck %s --check-prefixes CHECK,NTANR -define void @test() #0 { +define void @test_trap_unreachable() #0 { +; CHECK-LABEL: test_trap_unreachable: +; CHECK: @ %bb.0: +; CHECK-NEXT: .inst.n 0xdefe unreachable } attributes #0 = { nounwind } + +declare void @no_return() noreturn +declare void @could_return() + +define void @test_ntanr_noreturn() { +; CHECK-LABEL: test_ntanr_noreturn: +; CHECK: @ %bb.0: +; CHECK-NEXT: push {r7, lr} +; CHECK-NEXT: bl no_return +; TRAP_UNREACHABLE-NEXT: .inst.n 0xdefe +; NTANR-NOT: .inst.n 0xdefe +; + call void @no_return() + unreachable +} + +define void @test_ntanr_could_return() { +; CHECK-LABEL: test_ntanr_could_return: +; CHECK: @ %bb.0: +; CHECK-NEXT: push {r7, lr} +; CHECK-NEXT: bl could_return +; CHECK-NEXT: .inst.n 0xdefe + call void @could_return() + unreachable +}