xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/x86-shrink-wrap-unwind.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker;
3*9880d681SAndroid Build Coastguard Worker; Note: This test cannot be merged with the shrink-wrapping tests
4*9880d681SAndroid Build Coastguard Worker; because the booleans set on the command line take precedence on
5*9880d681SAndroid Build Coastguard Worker; the target logic that disable shrink-wrapping.
6*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
7*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-apple-macosx"
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker; This test checks that we do not use shrink-wrapping when
11*9880d681SAndroid Build Coastguard Worker; the function does not have any frame pointer and may unwind.
12*9880d681SAndroid Build Coastguard Worker; This is a workaround for a limitation in the emission of
13*9880d681SAndroid Build Coastguard Worker; the CFI directives, that are not correct in such case.
14*9880d681SAndroid Build Coastguard Worker; PR25614
15*9880d681SAndroid Build Coastguard Worker;
16*9880d681SAndroid Build Coastguard Worker; No shrink-wrapping should occur here, until the CFI information are fixed.
17*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: framelessUnwind:
18*9880d681SAndroid Build Coastguard Worker;
19*9880d681SAndroid Build Coastguard Worker; Prologue code.
20*9880d681SAndroid Build Coastguard Worker; (What we push does not matter. It should be some random sratch register.)
21*9880d681SAndroid Build Coastguard Worker; CHECK: pushq
22*9880d681SAndroid Build Coastguard Worker;
23*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit.
24*9880d681SAndroid Build Coastguard Worker; After the prologue is set.
25*9880d681SAndroid Build Coastguard Worker; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]]
26*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmpl %esi, [[ARG0CPY]]
27*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]]
28*9880d681SAndroid Build Coastguard Worker;
29*9880d681SAndroid Build Coastguard Worker; Store %a in the alloca.
30*9880d681SAndroid Build Coastguard Worker; CHECK: movl [[ARG0CPY]], 4(%rsp)
31*9880d681SAndroid Build Coastguard Worker; Set the alloca address in the second argument.
32*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leaq 4(%rsp), %rsi
33*9880d681SAndroid Build Coastguard Worker; Set the first argument to zero.
34*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl %edi, %edi
35*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq _doSomething
36*9880d681SAndroid Build Coastguard Worker;
37*9880d681SAndroid Build Coastguard Worker; CHECK: [[EXIT_LABEL]]:
38*9880d681SAndroid Build Coastguard Worker;
39*9880d681SAndroid Build Coastguard Worker; Without shrink-wrapping, epilogue is in the exit block.
40*9880d681SAndroid Build Coastguard Worker; Epilogue code. (What we pop does not matter.)
41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: popq
42*9880d681SAndroid Build Coastguard Worker;
43*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq
44*9880d681SAndroid Build Coastguard Workerdefine i32 @framelessUnwind(i32 %a, i32 %b) #0 {
45*9880d681SAndroid Build Coastguard Worker  %tmp = alloca i32, align 4
46*9880d681SAndroid Build Coastguard Worker  %tmp2 = icmp slt i32 %a, %b
47*9880d681SAndroid Build Coastguard Worker  br i1 %tmp2, label %true, label %false
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Workertrue:
50*9880d681SAndroid Build Coastguard Worker  store i32 %a, i32* %tmp, align 4
51*9880d681SAndroid Build Coastguard Worker  %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
52*9880d681SAndroid Build Coastguard Worker  br label %false
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Workerfalse:
55*9880d681SAndroid Build Coastguard Worker  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
56*9880d681SAndroid Build Coastguard Worker  ret i32 %tmp.0
57*9880d681SAndroid Build Coastguard Worker}
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Workerdeclare i32 @doSomething(i32, i32*)
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Workerattributes #0 = { "no-frame-pointer-elim"="false" }
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker; Shrink-wrapping should occur here. We have a frame pointer.
64*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: frameUnwind:
65*9880d681SAndroid Build Coastguard Worker;
66*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit.
67*9880d681SAndroid Build Coastguard Worker; No prologue needed.
68*9880d681SAndroid Build Coastguard Worker;
69*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit.
70*9880d681SAndroid Build Coastguard Worker; After the prologue is set.
71*9880d681SAndroid Build Coastguard Worker; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]]
72*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmpl %esi, [[ARG0CPY]]
73*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]]
74*9880d681SAndroid Build Coastguard Worker;
75*9880d681SAndroid Build Coastguard Worker; Prologue code.
76*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rbp
77*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rsp, %rbp
78*9880d681SAndroid Build Coastguard Worker;
79*9880d681SAndroid Build Coastguard Worker; Store %a in the alloca.
80*9880d681SAndroid Build Coastguard Worker; CHECK: movl [[ARG0CPY]], -4(%rbp)
81*9880d681SAndroid Build Coastguard Worker; Set the alloca address in the second argument.
82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leaq -4(%rbp), %rsi
83*9880d681SAndroid Build Coastguard Worker; Set the first argument to zero.
84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl %edi, %edi
85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq _doSomething
86*9880d681SAndroid Build Coastguard Worker;
87*9880d681SAndroid Build Coastguard Worker; Epilogue code. (What we pop does not matter.)
88*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rbp
89*9880d681SAndroid Build Coastguard Worker;
90*9880d681SAndroid Build Coastguard Worker; CHECK: [[EXIT_LABEL]]:
91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq
92*9880d681SAndroid Build Coastguard Workerdefine i32 @frameUnwind(i32 %a, i32 %b) #1 {
93*9880d681SAndroid Build Coastguard Worker  %tmp = alloca i32, align 4
94*9880d681SAndroid Build Coastguard Worker  %tmp2 = icmp slt i32 %a, %b
95*9880d681SAndroid Build Coastguard Worker  br i1 %tmp2, label %true, label %false
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Workertrue:
98*9880d681SAndroid Build Coastguard Worker  store i32 %a, i32* %tmp, align 4
99*9880d681SAndroid Build Coastguard Worker  %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
100*9880d681SAndroid Build Coastguard Worker  br label %false
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Workerfalse:
103*9880d681SAndroid Build Coastguard Worker  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
104*9880d681SAndroid Build Coastguard Worker  ret i32 %tmp.0
105*9880d681SAndroid Build Coastguard Worker}
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Workerattributes #1 = { "no-frame-pointer-elim"="true" }
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker; Shrink-wrapping should occur here. We do not have to unwind.
110*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: framelessnoUnwind:
111*9880d681SAndroid Build Coastguard Worker;
112*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit.
113*9880d681SAndroid Build Coastguard Worker; No prologue needed.
114*9880d681SAndroid Build Coastguard Worker;
115*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit.
116*9880d681SAndroid Build Coastguard Worker; After the prologue is set.
117*9880d681SAndroid Build Coastguard Worker; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]]
118*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmpl %esi, [[ARG0CPY]]
119*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]]
120*9880d681SAndroid Build Coastguard Worker;
121*9880d681SAndroid Build Coastguard Worker; Prologue code.
122*9880d681SAndroid Build Coastguard Worker; (What we push does not matter. It should be some random sratch register.)
123*9880d681SAndroid Build Coastguard Worker; CHECK: pushq
124*9880d681SAndroid Build Coastguard Worker;
125*9880d681SAndroid Build Coastguard Worker; Store %a in the alloca.
126*9880d681SAndroid Build Coastguard Worker; CHECK: movl [[ARG0CPY]], 4(%rsp)
127*9880d681SAndroid Build Coastguard Worker; Set the alloca address in the second argument.
128*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leaq 4(%rsp), %rsi
129*9880d681SAndroid Build Coastguard Worker; Set the first argument to zero.
130*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl %edi, %edi
131*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq _doSomething
132*9880d681SAndroid Build Coastguard Worker;
133*9880d681SAndroid Build Coastguard Worker; Epilogue code.
134*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: addq
135*9880d681SAndroid Build Coastguard Worker;
136*9880d681SAndroid Build Coastguard Worker; CHECK: [[EXIT_LABEL]]:
137*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq
138*9880d681SAndroid Build Coastguard Workerdefine i32 @framelessnoUnwind(i32 %a, i32 %b) #2 {
139*9880d681SAndroid Build Coastguard Worker  %tmp = alloca i32, align 4
140*9880d681SAndroid Build Coastguard Worker  %tmp2 = icmp slt i32 %a, %b
141*9880d681SAndroid Build Coastguard Worker  br i1 %tmp2, label %true, label %false
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Workertrue:
144*9880d681SAndroid Build Coastguard Worker  store i32 %a, i32* %tmp, align 4
145*9880d681SAndroid Build Coastguard Worker  %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
146*9880d681SAndroid Build Coastguard Worker  br label %false
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Workerfalse:
149*9880d681SAndroid Build Coastguard Worker  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
150*9880d681SAndroid Build Coastguard Worker  ret i32 %tmp.0
151*9880d681SAndroid Build Coastguard Worker}
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Workerattributes #2 = { "no-frame-pointer-elim"="false" nounwind }
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker; Check that we generate correct code for segmented stack.
157*9880d681SAndroid Build Coastguard Worker; We used to emit the code at the entry point of the function
158*9880d681SAndroid Build Coastguard Worker; instead of just before the prologue.
159*9880d681SAndroid Build Coastguard Worker; For now, shrink-wrapping is disabled on segmented stack functions: PR26107.
160*9880d681SAndroid Build Coastguard Worker;
161*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: segmentedStack:
162*9880d681SAndroid Build Coastguard Worker; CHECK: cmpq
163*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ja [[ENTRY_LABEL:LBB[0-9_]+]]
164*9880d681SAndroid Build Coastguard Worker;
165*9880d681SAndroid Build Coastguard Worker; CHECK: callq ___morestack
166*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq
167*9880d681SAndroid Build Coastguard Worker;
168*9880d681SAndroid Build Coastguard Worker; CHECK: [[ENTRY_LABEL]]:
169*9880d681SAndroid Build Coastguard Worker; Prologue
170*9880d681SAndroid Build Coastguard Worker; CHECK: push
171*9880d681SAndroid Build Coastguard Worker;
172*9880d681SAndroid Build Coastguard Worker; In PR26107, we use to drop these two basic blocks, because
173*9880d681SAndroid Build Coastguard Worker; the segmentedStack entry block was jumping directly to
174*9880d681SAndroid Build Coastguard Worker; the place where the prologue is actually needed, which is
175*9880d681SAndroid Build Coastguard Worker; the call to memcmp.
176*9880d681SAndroid Build Coastguard Worker; Then, those two basic blocks did not have any predecessors
177*9880d681SAndroid Build Coastguard Worker; anymore and were removed.
178*9880d681SAndroid Build Coastguard Worker;
179*9880d681SAndroid Build Coastguard Worker; Check if vk1 is null
180*9880d681SAndroid Build Coastguard Worker; CHECK: testq %rdi, %rdi
181*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: je [[STRINGS_EQUAL:LBB[0-9_]+]]
182*9880d681SAndroid Build Coastguard Worker;
183*9880d681SAndroid Build Coastguard Worker; Check if vk2 is null
184*9880d681SAndroid Build Coastguard Worker; CHECK: testq %rsi, %rsi
185*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  je [[STRINGS_EQUAL]]
186*9880d681SAndroid Build Coastguard Worker;
187*9880d681SAndroid Build Coastguard Worker; CHECK: [[STRINGS_EQUAL]]
188*9880d681SAndroid Build Coastguard Worker; CHECK: popq
189*9880d681SAndroid Build Coastguard Workerdefine zeroext i1 @segmentedStack(i8* readonly %vk1, i8* readonly %vk2, i64 %key_size) #5 {
190*9880d681SAndroid Build Coastguard Workerentry:
191*9880d681SAndroid Build Coastguard Worker  %cmp.i = icmp eq i8* %vk1, null
192*9880d681SAndroid Build Coastguard Worker  %cmp1.i = icmp eq i8* %vk2, null
193*9880d681SAndroid Build Coastguard Worker  %brmerge.i = or i1 %cmp.i, %cmp1.i
194*9880d681SAndroid Build Coastguard Worker  %cmp1.mux.i = and i1 %cmp.i, %cmp1.i
195*9880d681SAndroid Build Coastguard Worker  br i1 %brmerge.i, label %__go_ptr_strings_equal.exit, label %if.end4.i
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Workerif.end4.i:                                        ; preds = %entry
198*9880d681SAndroid Build Coastguard Worker  %tmp = getelementptr inbounds i8, i8* %vk1, i64 8
199*9880d681SAndroid Build Coastguard Worker  %tmp1 = bitcast i8* %tmp to i64*
200*9880d681SAndroid Build Coastguard Worker  %tmp2 = load i64, i64* %tmp1, align 8
201*9880d681SAndroid Build Coastguard Worker  %tmp3 = getelementptr inbounds i8, i8* %vk2, i64 8
202*9880d681SAndroid Build Coastguard Worker  %tmp4 = bitcast i8* %tmp3 to i64*
203*9880d681SAndroid Build Coastguard Worker  %tmp5 = load i64, i64* %tmp4, align 8
204*9880d681SAndroid Build Coastguard Worker  %cmp.i.i = icmp eq i64 %tmp2, %tmp5
205*9880d681SAndroid Build Coastguard Worker  br i1 %cmp.i.i, label %land.rhs.i.i, label %__go_ptr_strings_equal.exit
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Workerland.rhs.i.i:                                     ; preds = %if.end4.i
208*9880d681SAndroid Build Coastguard Worker  %tmp6 = bitcast i8* %vk2 to i8**
209*9880d681SAndroid Build Coastguard Worker  %tmp7 = load i8*, i8** %tmp6, align 8
210*9880d681SAndroid Build Coastguard Worker  %tmp8 = bitcast i8* %vk1 to i8**
211*9880d681SAndroid Build Coastguard Worker  %tmp9 = load i8*, i8** %tmp8, align 8
212*9880d681SAndroid Build Coastguard Worker  %call.i.i = tail call i32 @memcmp(i8* %tmp9, i8* %tmp7, i64 %tmp2) #5
213*9880d681SAndroid Build Coastguard Worker  %cmp4.i.i = icmp eq i32 %call.i.i, 0
214*9880d681SAndroid Build Coastguard Worker  br label %__go_ptr_strings_equal.exit
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker__go_ptr_strings_equal.exit:                      ; preds = %land.rhs.i.i, %if.end4.i, %entry
217*9880d681SAndroid Build Coastguard Worker  %retval.0.i = phi i1 [ %cmp1.mux.i, %entry ], [ false, %if.end4.i ], [ %cmp4.i.i, %land.rhs.i.i ]
218*9880d681SAndroid Build Coastguard Worker  ret i1 %retval.0.i
219*9880d681SAndroid Build Coastguard Worker}
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind readonly
222*9880d681SAndroid Build Coastguard Workerdeclare i32 @memcmp(i8* nocapture, i8* nocapture, i64) #5
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Workerattributes #5 = { nounwind readonly ssp uwtable "split-stack" }
225