forked from OSchip/llvm-project
[MC] [Win64EH] Fix the calculation of the end of epilogs
Exclude the terminating end opcode from the epilog - it doesn't correspond to an actual instruction that is included in the epilog itself (within the .seh_startepilogue/.seh_endepilogue range). In most (all?) cases, an epilog is followed by a matching terminating instruction though (a ret or a branch to a tail call), but it's not strictly within the .seh_startepilogue/.seh_endepilogue range. This fixes a number of failed asserts in cases where the codegen has incorrectly reoredered SEH opcodes so they don't match up exactly with their instructions. However this still just avoids failing the assertion; the root cause of generating unexpected epilogs is still present (and fixing that is a less obvious issue). Differential Revision: https://reviews.llvm.org/D131393
This commit is contained in:
parent
f181dff084
commit
0c52ab3968
|
@ -997,7 +997,9 @@ static void ARM64FindSegmentsInFunction(MCStreamer &streamer,
|
|||
int64_t Offset = GetAbsDifference(streamer, Start, info->Begin);
|
||||
assert((Epilogs.size() == 0 || Offset >= Epilogs.back().End) &&
|
||||
"Epilogs should be monotonically ordered");
|
||||
Epilogs.push_back({Start, Offset, Offset + (int64_t)Instrs.size() * 4});
|
||||
// Exclue the end opcode from Instrs.size() when calculating the end of the
|
||||
// epilog.
|
||||
Epilogs.push_back({Start, Offset, Offset + (int64_t)(Instrs.size() - 1) * 4});
|
||||
}
|
||||
|
||||
unsigned E = 0;
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
// This test checks that we emit allow multiple consecutive epilogs without
|
||||
// triggering failed asserts.unwind info correctly for epilogs that:
|
||||
// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s -o %t.o
|
||||
// RUN: llvm-readobj -u %t.o | FileCheck %s
|
||||
|
||||
// CHECK-LABEL:UnwindInformation [
|
||||
// CHECK-NEXT: RuntimeFunction {
|
||||
// CHECK-NEXT: Function: multi_epilog (0x0)
|
||||
// CHECK-NEXT: ExceptionRecord: .xdata (0x0)
|
||||
// CHECK-NEXT: ExceptionData {
|
||||
// CHECK-NEXT: FunctionLength: 20
|
||||
// CHECK-NEXT: Version: 0
|
||||
// CHECK-NEXT: ExceptionData: No
|
||||
// CHECK-NEXT: EpiloguePacked: No
|
||||
// CHECK-NEXT: EpilogueScopes: 2
|
||||
// CHECK-NEXT: ByteCodeLength: 4
|
||||
// CHECK-NEXT: Prologue [
|
||||
// CHECK-NEXT: 0x81 ; stp x29, x30, [sp, #-16]!
|
||||
// CHECK-NEXT: 0xe4 ; end
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: EpilogueScopes [
|
||||
// CHECK-NEXT: EpilogueScope {
|
||||
// CHECK-NEXT: StartOffset: 2
|
||||
// CHECK-NEXT: EpilogueStartIndex: 0
|
||||
// CHECK-NEXT: Opcodes [
|
||||
// CHECK-NEXT: 0x81 ; ldp x29, x30, [sp], #16
|
||||
// CHECK-NEXT: 0xe4 ; end
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: EpilogueScope {
|
||||
// CHECK-NEXT: StartOffset: 3
|
||||
// CHECK-NEXT: EpilogueStartIndex: 0
|
||||
// CHECK-NEXT: Opcodes [
|
||||
// CHECK-NEXT: 0x81 ; ldp x29, x30, [sp], #16
|
||||
// CHECK-NEXT: 0xe4 ; end
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT:]
|
||||
|
||||
.text
|
||||
.global multi_epilog
|
||||
.p2align 2
|
||||
.seh_proc multi_epilog
|
||||
multi_epilog:
|
||||
stp x29, lr, [sp, #-16]!
|
||||
.seh_save_fplr_x 16
|
||||
.seh_endprologue
|
||||
nop
|
||||
.seh_startepilogue
|
||||
ldp x29, lr, [sp], #16
|
||||
.seh_save_fplr_x 16
|
||||
.seh_endepilogue
|
||||
.seh_startepilogue
|
||||
ldp x29, lr, [sp], #16
|
||||
.seh_save_fplr_x 16
|
||||
.seh_endepilogue
|
||||
ret
|
||||
.seh_endfunclet
|
||||
.seh_endproc
|
Loading…
Reference in New Issue