blob: 959522782665902da6fc2d6dac7bf6fd854c604f [file] [log] [blame]
Michael Kuperstein259f1502015-10-07 07:01:31 +00001; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s
2
3declare i32 @__gxx_personality_v0(...)
4declare void @good(i32 %a, i32 %b, i32 %c, i32 %d)
5declare void @large(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f)
6declare void @empty()
7
8; We use an invoke, and expect a .cfi_escape GNU_ARGS_SIZE with size 16
9; before the invocation
10; CHECK-LABEL: test1:
11; CHECK: .cfi_escape 0x2e, 0x10
12; CHECK-NEXT: pushl $4
13; CHECK-NEXT: pushl $3
14; CHECK-NEXT: pushl $2
15; CHECK-NEXT: pushl $1
16; CHECK-NEXT: call
17; CHECK-NEXT: addl $16, %esp
18define void @test1() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
19entry:
20 invoke void @good(i32 1, i32 2, i32 3, i32 4)
21 to label %continue unwind label %cleanup
22continue:
23 ret void
24cleanup:
25 landingpad { i8*, i32 }
26 cleanup
27 ret void
28}
29
30; If the function has no handlers, we don't need to generate GNU_ARGS_SIZE,
31; even if it has an unwind table.
32; CHECK-LABEL: test2:
33; CHECK-NOT: .cfi_escape
34; CHECK: pushl $4
35; CHECK-NEXT: pushl $3
36; CHECK-NEXT: pushl $2
37; CHECK-NEXT: pushl $1
38; CHECK-NEXT: call
39; CHECK-NEXT: addl $16, %esp
40define void @test2() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
41entry:
42 call void @good(i32 1, i32 2, i32 3, i32 4)
43 ret void
44}
45
46; If we did not end up using any pushes, no need for GNU_ARGS_SIZE anywhere
47; CHECK-LABEL: test3:
48; CHECK-NOT: .cfi_escape
49; CHECK-NOT: pushl
50; CHECK: retl
51define void @test3() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
52entry:
53 invoke void @empty()
54 to label %continue unwind label %cleanup
55continue:
56 ret void
57cleanup:
58 landingpad { i8*, i32 }
59 cleanup
60 ret void
61}
62
63; Different sized stacks need different GNU_ARGS_SIZEs
64; CHECK-LABEL: test4:
65; CHECK: .cfi_escape 0x2e, 0x10
66; CHECK-NEXT: pushl $4
67; CHECK-NEXT: pushl $3
68; CHECK-NEXT: pushl $2
69; CHECK-NEXT: pushl $1
70; CHECK-NEXT: call
71; CHECK-NEXT: addl $16, %esp
72; CHECK: .cfi_escape 0x2e, 0x20
73; CHECK-NEXT: subl $8, %esp
74; CHECK-NEXT: pushl $11
75; CHECK-NEXT: pushl $10
76; CHECK-NEXT: pushl $9
77; CHECK-NEXT: pushl $8
78; CHECK-NEXT: pushl $7
79; CHECK-NEXT: pushl $6
80; CHECK-NEXT: calll large
81; CHECK-NEXT: addl $32, %esp
82define void @test4() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
83entry:
84 invoke void @good(i32 1, i32 2, i32 3, i32 4)
85 to label %continue1 unwind label %cleanup
86continue1:
87 invoke void @large(i32 6, i32 7, i32 8, i32 9, i32 10, i32 11)
88 to label %continue2 unwind label %cleanup
89continue2:
90 ret void
91cleanup:
92 landingpad { i8*, i32 }
93 cleanup
94 ret void
95}
96
97; If we did use pushes, we need to reset GNU_ARGS_SIZE before a call
98; without parameters
99; CHECK-LABEL: test5:
100; CHECK: .cfi_escape 0x2e, 0x10
101; CHECK-NEXT: pushl $4
102; CHECK-NEXT: pushl $3
103; CHECK-NEXT: pushl $2
104; CHECK-NEXT: pushl $1
105; CHECK-NEXT: call
106; CHECK-NEXT: addl $16, %esp
107; CHECK: .cfi_escape 0x2e, 0x00
108; CHECK-NEXT: call
109define void @test5() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
110entry:
111 invoke void @good(i32 1, i32 2, i32 3, i32 4)
112 to label %continue1 unwind label %cleanup
113continue1:
114 invoke void @empty()
115 to label %continue2 unwind label %cleanup
116continue2:
117 ret void
118cleanup:
119 landingpad { i8*, i32 }
120 cleanup
121 ret void
122}
123
124; This is actually inefficient - we don't need to repeat the .cfi_escape twice.
125; CHECK-LABEL: test6:
126; CHECK: .cfi_escape 0x2e, 0x10
127; CHECK: call
128; CHECK: .cfi_escape 0x2e, 0x10
129; CHECK: call
130define void @test6() optsize personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
131entry:
132 invoke void @good(i32 1, i32 2, i32 3, i32 4)
133 to label %continue1 unwind label %cleanup
134continue1:
135 invoke void @good(i32 5, i32 6, i32 7, i32 8)
136 to label %continue2 unwind label %cleanup
137continue2:
138 ret void
139cleanup:
140 landingpad { i8*, i32 }
141 cleanup
142 ret void
143}