Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit da1c9a3

Browse files
committed
SelectionDAGBuilder, mach-o: Skip trap after noreturn call (for Mach-O)
Add NoTrapAfterNoreturn target option which skips emission of traps behind noreturn calls even if TrapUnreachable is enabled. Enable the feature on Mach-O to save code size; Comments suggest it is not possible to enable it for the other users of TrapUnreachable. rdar://41530228 DifferentialRevision: https://reviews.llvm.org/D48674 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335877 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 6479596 commit da1c9a3

File tree

6 files changed

+62
-7
lines changed

6 files changed

+62
-7
lines changed

include/llvm/Target/TargetOptions.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ namespace llvm {
107107
EnableFastISel(false), UseInitArray(false),
108108
DisableIntegratedAS(false), RelaxELFRelocations(false),
109109
FunctionSections(false), DataSections(false),
110-
UniqueSectionNames(true), TrapUnreachable(false), EmulatedTLS(false),
110+
UniqueSectionNames(true), TrapUnreachable(false),
111+
NoTrapAfterNoreturn(false),
112+
EmulatedTLS(false),
111113
EnableIPRA(false), EmitStackSizeSection(false) {}
112114

113115
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
@@ -209,6 +211,10 @@ namespace llvm {
209211
/// Emit target-specific trap instruction for 'unreachable' IR instructions.
210212
unsigned TrapUnreachable : 1;
211213

214+
/// Do not emit a trap instruction for 'unreachable' IR instructions behind
215+
/// noreturn calls, even if TrapUnreachable is true.
216+
unsigned NoTrapAfterNoreturn : 1;
217+
212218
/// EmulatedTLS - This flag enables emulated TLS model, using emutls
213219
/// function in the runtime library..
214220
unsigned EmulatedTLS : 1;

lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2584,9 +2584,23 @@ void SelectionDAGBuilder::visitIndirectBr(const IndirectBrInst &I) {
25842584
}
25852585

25862586
void SelectionDAGBuilder::visitUnreachable(const UnreachableInst &I) {
2587-
if (DAG.getTarget().Options.TrapUnreachable)
2588-
DAG.setRoot(
2589-
DAG.getNode(ISD::TRAP, getCurSDLoc(), MVT::Other, DAG.getRoot()));
2587+
if (!DAG.getTarget().Options.TrapUnreachable)
2588+
return;
2589+
2590+
// We may be able to ignore unreachable behind a noreturn call.
2591+
if (DAG.getTarget().Options.NoTrapAfterNoreturn) {
2592+
const BasicBlock &BB = *I.getParent();
2593+
if (&I != &BB.front()) {
2594+
BasicBlock::const_iterator PredI =
2595+
std::prev(BasicBlock::const_iterator(&I));
2596+
if (const CallInst *Call = dyn_cast<CallInst>(&*PredI)) {
2597+
if (Call->doesNotReturn())
2598+
return;
2599+
}
2600+
}
2601+
}
2602+
2603+
DAG.setRoot(DAG.getNode(ISD::TRAP, getCurSDLoc(), MVT::Other, DAG.getRoot()));
25902604
}
25912605

25922606
void SelectionDAGBuilder::visitFSub(const User &I) {

lib/Target/AArch64/AArch64TargetMachine.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,10 @@ AArch64TargetMachine::AArch64TargetMachine(const Target &T, const Triple &TT,
244244
TLOF(createTLOF(getTargetTriple())), isLittle(LittleEndian) {
245245
initAsmInfo();
246246

247-
if (TT.isOSBinFormatMachO())
247+
if (TT.isOSBinFormatMachO()) {
248248
this->Options.TrapUnreachable = true;
249+
this->Options.NoTrapAfterNoreturn = true;
250+
}
249251
}
250252

251253
AArch64TargetMachine::~AArch64TargetMachine() = default;

lib/Target/ARM/ARMTargetMachine.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,10 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,
238238
this->Options.EABIVersion = EABI::EABI5;
239239
}
240240

241-
if (TT.isOSBinFormatMachO())
241+
if (TT.isOSBinFormatMachO()) {
242242
this->Options.TrapUnreachable = true;
243+
this->Options.NoTrapAfterNoreturn = true;
244+
}
243245

244246
initAsmInfo();
245247
}

lib/Target/X86/X86TargetMachine.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,10 @@ X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT,
221221
// to ever want to mix 32 and 64-bit windows code in a single module
222222
// this should be fine.
223223
if ((TT.isOSWindows() && TT.getArch() == Triple::x86_64) || TT.isPS4() ||
224-
TT.isOSBinFormatMachO())
224+
TT.isOSBinFormatMachO()) {
225225
this->Options.TrapUnreachable = true;
226+
this->Options.NoTrapAfterNoreturn = TT.isOSBinFormatMachO();
227+
}
226228

227229
initAsmInfo();
228230
}

test/CodeGen/X86/unreachable-trap.ll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: llc -o - %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefixes=CHECK,TRAP_AFTER_NORETURN
2+
; RUN: llc -o - %s -mtriple=x86_64-apple-darwin | FileCheck %s --check-prefixes=CHECK,NO_TRAP_AFTER_NORETURN
3+
4+
; CHECK-LABEL: call_exit:
5+
; CHECK: callq {{_?}}exit
6+
; TRAP_AFTER_NORETURN: ud2
7+
; NO_TRAP_AFTER_NORETURN-NOT: ud2
8+
define i32 @call_exit() noreturn nounwind {
9+
tail call void @exit(i32 0)
10+
unreachable
11+
}
12+
13+
; CHECK-LABEL: trap:
14+
; CHECK: ud2
15+
; TRAP_AFTER_NORETURN: ud2
16+
; NO_TRAP_AFTER_NORETURN-NOT: ud2
17+
define i32 @trap() noreturn nounwind {
18+
tail call void @llvm.trap()
19+
unreachable
20+
}
21+
22+
; CHECK-LABEL: unreachable:
23+
; CHECK: ud2
24+
define i32 @unreachable() noreturn nounwind {
25+
unreachable
26+
}
27+
28+
declare void @llvm.trap() nounwind noreturn
29+
declare void @exit(i32 %rc) nounwind noreturn

0 commit comments

Comments
 (0)