mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
Consider this function:
void foo() { __builtin_unreachable(); } It will output the following on Darwin X86: _func1: Leh_func_begin0: pushq %rbp Ltmp0: movq %rsp, %rbp Ltmp1: Leh_func_end0: This prolog adds a new Call Frame Information (CFI) row to the FDE with an address that is not within the address range of the code it describes -- part is equal to the end of the function -- and therefore results in an invalid EH frame. If we emit a nop in this situation, then the CFI row is now within the address range. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108568 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
78e6e00922
commit
dc86704114
@ -599,12 +599,15 @@ void AsmPrinter::EmitFunctionBody() {
|
||||
|
||||
// Print out code for the function.
|
||||
bool HasAnyRealCode = false;
|
||||
const MachineInstr *LastMI = 0;
|
||||
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
|
||||
I != E; ++I) {
|
||||
// Print a label for the basic block.
|
||||
EmitBasicBlockStart(I);
|
||||
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
|
||||
II != IE; ++II) {
|
||||
LastMI = II;
|
||||
|
||||
// Print the assembly for the instruction.
|
||||
if (!II->isLabel() && !II->isImplicitDef() && !II->isKill() &&
|
||||
!II->isDebugValue()) {
|
||||
@ -652,11 +655,18 @@ void AsmPrinter::EmitFunctionBody() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If the last instruction was a prolog label, then we have a situation where
|
||||
// we emitted a prolog but no function body. This results in the ending prolog
|
||||
// label equaling the end of function label and an invalid "row" in the
|
||||
// FDE. We need to emit a noop in this situation so that the FDE's rows are
|
||||
// valid.
|
||||
bool RequiresNoop = LastMI && LastMI->getOpcode()==TargetOpcode::PROLOG_LABEL;
|
||||
|
||||
// If the function is empty and the object file uses .subsections_via_symbols,
|
||||
// then we need to emit *something* to the function body to prevent the
|
||||
// labels from collapsing together. Just emit a noop.
|
||||
if (MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode) {
|
||||
if ((MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode) || RequiresNoop) {
|
||||
MCInst Noop;
|
||||
TM.getInstrInfo()->getNoopForMachoTarget(Noop);
|
||||
if (Noop.getOpcode()) {
|
||||
|
@ -1,8 +0,0 @@
|
||||
; RUN: llc < %s -march=ppc32 | grep nop
|
||||
target triple = "powerpc-apple-darwin8"
|
||||
|
||||
|
||||
define void @bork() noreturn nounwind {
|
||||
entry:
|
||||
unreachable
|
||||
}
|
12
test/CodeGen/PowerPC/empty-functions.ll
Normal file
12
test/CodeGen/PowerPC/empty-functions.ll
Normal file
@ -0,0 +1,12 @@
|
||||
; RUN: llc < %s -mtriple=powerpc-apple-darwin | FileCheck -check-prefix=CHECK-NO-FP %s
|
||||
; RUN: llc < %s -mtriple=powerpc-apple-darwin -disable-fp-elim | FileCheck -check-prefix=CHECK-FP %s
|
||||
|
||||
define void @func() {
|
||||
entry:
|
||||
unreachable
|
||||
}
|
||||
; CHECK-NO-FP: _func:
|
||||
; CHECK-NO-FP: nop
|
||||
|
||||
; CHECK-FP: _func:
|
||||
; CHECK-FP: nop
|
@ -1,8 +0,0 @@
|
||||
; RUN: llc < %s -march=x86 | grep nop
|
||||
target triple = "i686-apple-darwin8"
|
||||
|
||||
|
||||
define void @bork() noreturn nounwind {
|
||||
entry:
|
||||
unreachable
|
||||
}
|
15
test/CodeGen/X86/empty-functions.ll
Normal file
15
test/CodeGen/X86/empty-functions.ll
Normal file
@ -0,0 +1,15 @@
|
||||
; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck -check-prefix=CHECK-NO-FP %s
|
||||
; RUN: llc < %s -mtriple=x86_64-apple-darwin -disable-fp-elim | FileCheck -check-prefix=CHECK-FP %s
|
||||
|
||||
define void @func() {
|
||||
entry:
|
||||
unreachable
|
||||
}
|
||||
; CHECK-NO-FP: _func:
|
||||
; CHECK-NO-FP-NOT: movq %rsp, %rbp
|
||||
; CHECK-NO-FP: nop
|
||||
|
||||
; CHECK-FP: _func:
|
||||
; CHECK-FP: movq %rsp, %rbp
|
||||
; CHECK-FP-NEXT: Ltmp1:
|
||||
; CHECK-FP: nop
|
Loading…
Reference in New Issue
Block a user