Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[X86] Emit .cfi_escape GNU_ARGS_SIZE when adjusting the stack before …
…calls When outgoing function arguments are passed using push instructions, and EH is enabled, we may need to indicate to the stack unwinder that the stack pointer was adjusted before the call. This should fix the exception handling issues in PR24792. Differential Revision: http://reviews.llvm.org/D13132 llvm-svn: 249522
- Loading branch information
Michael Kuperstein
committed
Oct 7, 2015
1 parent
1a6fd1c
commit 259f150
Showing
9 changed files
with
257 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
; RUN: llc < %s -mtriple=i686-pc-linux -filetype=obj | llvm-readobj -s -sr -sd | FileCheck %s | ||
|
||
; CHECK: Index: 8 | ||
; CHECK-NEXT: Name: .eh_frame (41) | ||
; CHECK-NEXT: Type: SHT_PROGBITS (0x1) | ||
; CHECK-NEXT: Flags [ (0x2) | ||
; CHECK-NEXT: SHF_ALLOC (0x2) | ||
; CHECK-NEXT: ] | ||
; CHECK-NEXT: Address: 0x0 | ||
; CHECK-NEXT: Offset: 0x64 | ||
; CHECK-NEXT: Size: 60 | ||
; CHECK-NEXT: Link: 0 | ||
; CHECK-NEXT: Info: 0 | ||
; CHECK-NEXT: AddressAlignment: 4 | ||
; CHECK-NEXT: EntrySize: 0 | ||
; CHECK-NEXT: Relocations [ | ||
; CHECK-NEXT: ] | ||
; CHECK-NEXT: SectionData ( | ||
; CHECK-NEXT: 0000: 1C000000 00000000 017A504C 5200017C |.........zPLR..|| | ||
; CHECK-NEXT: 0010: 08070000 00000000 1B0C0404 88010000 |................| | ||
; CHECK-NEXT: 0020: 18000000 24000000 00000000 19000000 |....$...........| | ||
; CHECK-NEXT: 0030: 04000000 00430E10 2E100000 |.....C......| | ||
; CHECK-NEXT: ) | ||
|
||
declare i32 @__gxx_personality_v0(...) | ||
declare void @good(i32 %a, i32 %b, i32 %c, i32 %d) | ||
|
||
define void @test() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | ||
entry: | ||
invoke void @good(i32 1, i32 2, i32 3, i32 4) | ||
to label %continue unwind label %cleanup | ||
continue: | ||
ret void | ||
cleanup: | ||
landingpad { i8*, i32 } | ||
cleanup | ||
ret void | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s | ||
|
||
declare i32 @__gxx_personality_v0(...) | ||
declare void @good(i32 %a, i32 %b, i32 %c, i32 %d) | ||
declare void @large(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) | ||
declare void @empty() | ||
|
||
; We use an invoke, and expect a .cfi_escape GNU_ARGS_SIZE with size 16 | ||
; before the invocation | ||
; CHECK-LABEL: test1: | ||
; CHECK: .cfi_escape 0x2e, 0x10 | ||
; CHECK-NEXT: pushl $4 | ||
; CHECK-NEXT: pushl $3 | ||
; CHECK-NEXT: pushl $2 | ||
; CHECK-NEXT: pushl $1 | ||
; CHECK-NEXT: call | ||
; CHECK-NEXT: addl $16, %esp | ||
define void @test1() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | ||
entry: | ||
invoke void @good(i32 1, i32 2, i32 3, i32 4) | ||
to label %continue unwind label %cleanup | ||
continue: | ||
ret void | ||
cleanup: | ||
landingpad { i8*, i32 } | ||
cleanup | ||
ret void | ||
} | ||
|
||
; If the function has no handlers, we don't need to generate GNU_ARGS_SIZE, | ||
; even if it has an unwind table. | ||
; CHECK-LABEL: test2: | ||
; CHECK-NOT: .cfi_escape | ||
; CHECK: pushl $4 | ||
; CHECK-NEXT: pushl $3 | ||
; CHECK-NEXT: pushl $2 | ||
; CHECK-NEXT: pushl $1 | ||
; CHECK-NEXT: call | ||
; CHECK-NEXT: addl $16, %esp | ||
define void @test2() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | ||
entry: | ||
call void @good(i32 1, i32 2, i32 3, i32 4) | ||
ret void | ||
} | ||
|
||
; If we did not end up using any pushes, no need for GNU_ARGS_SIZE anywhere | ||
; CHECK-LABEL: test3: | ||
; CHECK-NOT: .cfi_escape | ||
; CHECK-NOT: pushl | ||
; CHECK: retl | ||
define void @test3() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | ||
entry: | ||
invoke void @empty() | ||
to label %continue unwind label %cleanup | ||
continue: | ||
ret void | ||
cleanup: | ||
landingpad { i8*, i32 } | ||
cleanup | ||
ret void | ||
} | ||
|
||
; Different sized stacks need different GNU_ARGS_SIZEs | ||
; CHECK-LABEL: test4: | ||
; CHECK: .cfi_escape 0x2e, 0x10 | ||
; CHECK-NEXT: pushl $4 | ||
; CHECK-NEXT: pushl $3 | ||
; CHECK-NEXT: pushl $2 | ||
; CHECK-NEXT: pushl $1 | ||
; CHECK-NEXT: call | ||
; CHECK-NEXT: addl $16, %esp | ||
; CHECK: .cfi_escape 0x2e, 0x20 | ||
; CHECK-NEXT: subl $8, %esp | ||
; CHECK-NEXT: pushl $11 | ||
; CHECK-NEXT: pushl $10 | ||
; CHECK-NEXT: pushl $9 | ||
; CHECK-NEXT: pushl $8 | ||
; CHECK-NEXT: pushl $7 | ||
; CHECK-NEXT: pushl $6 | ||
; CHECK-NEXT: calll large | ||
; CHECK-NEXT: addl $32, %esp | ||
define void @test4() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | ||
entry: | ||
invoke void @good(i32 1, i32 2, i32 3, i32 4) | ||
to label %continue1 unwind label %cleanup | ||
continue1: | ||
invoke void @large(i32 6, i32 7, i32 8, i32 9, i32 10, i32 11) | ||
to label %continue2 unwind label %cleanup | ||
continue2: | ||
ret void | ||
cleanup: | ||
landingpad { i8*, i32 } | ||
cleanup | ||
ret void | ||
} | ||
|
||
; If we did use pushes, we need to reset GNU_ARGS_SIZE before a call | ||
; without parameters | ||
; CHECK-LABEL: test5: | ||
; CHECK: .cfi_escape 0x2e, 0x10 | ||
; CHECK-NEXT: pushl $4 | ||
; CHECK-NEXT: pushl $3 | ||
; CHECK-NEXT: pushl $2 | ||
; CHECK-NEXT: pushl $1 | ||
; CHECK-NEXT: call | ||
; CHECK-NEXT: addl $16, %esp | ||
; CHECK: .cfi_escape 0x2e, 0x00 | ||
; CHECK-NEXT: call | ||
define void @test5() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | ||
entry: | ||
invoke void @good(i32 1, i32 2, i32 3, i32 4) | ||
to label %continue1 unwind label %cleanup | ||
continue1: | ||
invoke void @empty() | ||
to label %continue2 unwind label %cleanup | ||
continue2: | ||
ret void | ||
cleanup: | ||
landingpad { i8*, i32 } | ||
cleanup | ||
ret void | ||
} | ||
|
||
; This is actually inefficient - we don't need to repeat the .cfi_escape twice. | ||
; CHECK-LABEL: test6: | ||
; CHECK: .cfi_escape 0x2e, 0x10 | ||
; CHECK: call | ||
; CHECK: .cfi_escape 0x2e, 0x10 | ||
; CHECK: call | ||
define void @test6() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | ||
entry: | ||
invoke void @good(i32 1, i32 2, i32 3, i32 4) | ||
to label %continue1 unwind label %cleanup | ||
continue1: | ||
invoke void @good(i32 5, i32 6, i32 7, i32 8) | ||
to label %continue2 unwind label %cleanup | ||
continue2: | ||
ret void | ||
cleanup: | ||
landingpad { i8*, i32 } | ||
cleanup | ||
ret void | ||
} |