[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / base-pointer-and-mwaitx.ll
blob73339648827e9fa8be432ee0455bc13633a4c92a
1 ; RUN: split-file %s %t
2 ; RUN: cat %t/main.ll %t/_align32.ll > %t/align32.ll
3 ; RUN: llc -mtriple=x86_64-pc-linux-gnu -mattr=+mwaitx -x86-use-base-pointer=true -stackrealign %t/align32.ll -o - | FileCheck --check-prefix=CHECK --check-prefix=USE_BASE_64 %s
4 ; RUN: llc -mtriple=x86_64-pc-linux-gnux32 -mattr=+mwaitx -x86-use-base-pointer=true -stackrealign %t/align32.ll -o - | FileCheck --check-prefix=CHECK --check-prefix=USE_BASE_32 %s
5 ; RUN: llc -mtriple=x86_64-pc-linux-gnu -mattr=+mwaitx -x86-use-base-pointer=true %t/main.ll -o - | FileCheck --check-prefix=CHECK --check-prefix=NO_BASE_64 %s
6 ; RUN: llc -mtriple=x86_64-pc-linux-gnux32 -mattr=+mwaitx -x86-use-base-pointer=true %t/main.ll -o - | FileCheck --check-prefix=CHECK --check-prefix=NO_BASE_32 %s
8 ;--- main.ll
10 ; This test checks that we save and restore the base pointer (ebx or rbx) in the
11 ; presence of the mwaitx intrinsic which requires to use ebx for one of its
12 ; argument.
13 ; This function uses a dynamically allocated stack to force the use
14 ; of a base pointer.
15 ; After the call to the mwaitx intrinsic we do a volatile store to the
16 ; dynamically allocated memory which will require the use of the base pointer.
17 ; The base pointer should therefore be restored straight after the mwaitx
18 ; instruction.
20 define void @test_baseptr(i64 %x, i64 %y, i32 %E, i32 %H, i32 %C) nounwind {
21 entry:
22   %ptr = alloca ptr, align 8
23   %0 = alloca i8, i64 %x, align 16
24   store ptr %0, ptr %ptr, align 8
25   call void @llvm.x86.mwaitx(i32 %E, i32 %H, i32 %C)
26   %1 = load ptr, ptr %ptr, align 8
27   %arrayidx = getelementptr inbounds i8, ptr %1, i64 %y
28   store volatile i8 42, ptr %arrayidx, align 1
29   ret void
31 ; CHECK-LABEL: test_baseptr:
32 ; USE_BASE_64: movq %rsp, %rbx
33 ; Pass mwaitx first 2 arguments in eax and ecx respectively.
34 ; USE_BASE_64: movl %ecx, %eax
35 ; USE_BASE_64: movl %edx, %ecx
36 ; Save base pointer.
37 ; USE_BASE_64: movq %rbx, [[SAVE_rbx:%r([8-9]|1[0-5]|di|si)]]
38 ; Set mwaitx ebx argument.
39 ; USE_BASE_64: movl %r8d, %ebx
40 ; USE_BASE_64-NEXT: mwaitx
41 ; Restore base pointer.
42 ; USE_BASE_64-NEXT: movq [[SAVE_rbx]], %rbx
44 ; USE_BASE_32: movl %esp, %ebx
45 ; Pass mwaitx first 2 arguments in eax and ecx respectively.
46 ; USE_BASE_32: movl %ecx, %eax
47 ; USE_BASE_32: movl %edx, %ecx
48 ; Save base pointer.
49 ; USE_BASE_32: movq %rbx, [[SAVE_rbx:%r(di|si)]]
50 ; Set mwaitx ebx argument.
51 ; USE_BASE_32: movl %r8d, %ebx
52 ; USE_BASE_32-NEXT: mwaitx
53 ; Restore base pointer.
54 ; USE_BASE_32-NEXT: movq [[SAVE_rbx]], %rbx
56 ; Pass mwaitx 3 arguments in eax, ecx, ebx
57 ; NO_BASE_64: movl %r8d, %ebx
58 ; NO_BASE_64: movl %ecx, %eax
59 ; NO_BASE_64: movl %edx, %ecx
60 ; No need to save base pointer.
61 ; NO_BASE_64-NOT: movq %rbx
62 ; NO_BASE_64: mwaitx
63 ; No need to restore base pointer.
64 ; NO_BASE_64-NOT: movq {{.*}}, %rbx
65 ; NO_BASE_64-NEXT: {{.+$}}
67 ; Pass mwaitx 3 arguments in eax, ecx, ebx
68 ; NO_BASE_32: movl %r8d, %ebx
69 ; NO_BASE_32: movl %ecx, %eax
70 ; NO_BASE_32: movl %edx, %ecx
71 ; No need to save base pointer.
72 ; NO_BASE_32-NOT: movl %ebx
73 ; NO_BASE_32: mwaitx
74 ; No need to restore base pointer.
75 ; NO_BASE_32-NOT: movl {{.*}}, %ebx
76 ; NO_BASE_32-NEXT: {{.+$}}
78 ; Test of the case where an opaque sp adjustement is introduced by a separate
79 ; basic block which, combined with stack realignment, requires a base pointer.
80 @g = global i32 0, align 8
82 define void @test_opaque_sp_adjustment(i32 %E, i32 %H, i32 %C, i64 %x) {
83 entry:
84   %ptr = alloca ptr, align 8
85   call void @llvm.x86.mwaitx(i32 %E, i32 %H, i32 %C)
86   %g = load i32, ptr @g, align 4
87   %tobool = icmp ne i32 %g, 0
88   br i1 %tobool, label %if.then, label %if.end
90 if.then:
91   call void asm sideeffect "", "~{rsp},~{esp},~{dirflag},~{fpsr},~{flags}"()
92   br label %if.end
94 if.end:
95   %ptr2 = load ptr, ptr %ptr, align 8
96   %arrayidx = getelementptr inbounds i8, ptr %ptr2, i64 %x
97   store volatile i8 42, ptr %arrayidx, align 1
98   ret void
100 ; CHECK-LABEL: test_opaque_sp_adjustment:
101 ; USE_BASE_64: movq %rsp, %rbx
102 ; Pass mwaitx first 2 arguments in eax and ecx respectively.
103 ; USE_BASE_64: movl %esi, %eax
104 ; USE_BASE_64: movl %edi, %ecx
105 ; Save base pointer.
106 ; USE_BASE_64: movq %rbx, [[SAVE_rbx:%r([8-9]|1[0-5]|di|si)]]
107 ; Set mwaitx ebx argument.
108 ; USE_BASE_64: movl %edx, %ebx
109 ; USE_BASE_64-NEXT: mwaitx
110 ; Restore base pointer.
111 ; USE_BASE_64-NEXT: movq [[SAVE_rbx]], %rbx
113 ; USE_BASE_32: movl %esp, %ebx
114 ; Pass mwaitx first 2 arguments in eax and ecx respectively.
115 ; USE_BASE_32: movl %esi, %eax
116 ; USE_BASE_32: movl %edi, %ecx
117 ; Save base pointer.
118 ; USE_BASE_32: movq %rbx, [[SAVE_rbx:%r(di|si)]]
119 ; Set mwaitx ebx argument.
120 ; USE_BASE_32: movl %edx, %ebx
121 ; USE_BASE_32-NEXT: mwaitx
122 ; Restore base pointer.
123 ; USE_BASE_32-NEXT: movq [[SAVE_rbx]], %rbx
125 ; Pass mwaitx 3 arguments in eax, ecx, ebx
126 ; NO_BASE_64: movl %edx, %ebx
127 ; NO_BASE_64: movl %esi, %eax
128 ; NO_BASE_64: movl %edi, %ecx
129 ; No need to save base pointer.
130 ; NO_BASE_64-NOT: movq %rbx
131 ; NO_BASE_64: mwaitx
132 ; NO_BASE_64-NOT: movq {{.*}}, %rbx
133 ; NO_BASE_64-NEXT: {{.+$}}
135 ; Pass mwaitx 3 arguments in eax, ecx, ebx
136 ; NO_BASE_32: movl %edx, %ebx
137 ; NO_BASE_32: movl %esi, %eax
138 ; NO_BASE_32: movl %edi, %ecx
139 ; No need to save base pointer.
140 ; NO_BASE_32-NOT: movl %ebx
141 ; NO_BASE_32: mwaitx
142 ; No need to restore base pointer.
143 ; NO_BASE_32-NOT: movl {{.*}}, %ebx
144 ; NO_BASE_32-NEXT: {{.+$}}
146 ; Test of the case where a variable size object is introduced by a separate
147 ; basic block which, combined with stack realignment, requires a base pointer.
148 define void @test_variable_size_object(i32 %E, i32 %H, i32 %C, i64 %x) {
149 entry:
150   %ptr = alloca ptr, align 8
151   call void @llvm.x86.mwaitx(i32 %E, i32 %H, i32 %C)
152   %g = load i32, ptr @g, align 4
153   %tobool = icmp ne i32 %g, 0
154   br i1 %tobool, label %if.then, label %if.end
156 if.then:
157   %i5 = alloca i8, i64 %x, align 16
158   store ptr %i5, ptr %ptr, align 8
159   br label %if.end
161 if.end:
162   %ptr2 = load ptr, ptr %ptr, align 8
163   %arrayidx = getelementptr inbounds i8, ptr %ptr2, i64 %x
164   store volatile i8 42, ptr %arrayidx, align 1
165   ret void
168 ; CHECK-LABEL: test_variable_size_object:
169 ; USE_BASE_64: movq %rsp, %rbx
170 ; Pass mwaitx first 2 arguments in eax and ecx respectively.
171 ; USE_BASE_64: movl %esi, %eax
172 ; USE_BASE_64: movl %edi, %ecx
173 ; Save base pointer.
174 ; USE_BASE_64: movq %rbx, [[SAVE_rbx:%r([8-9]|1[0-5]|di|si)]]
175 ; Set mwaitx ebx argument.
176 ; USE_BASE_64: movl %edx, %ebx
177 ; USE_BASE_64-NEXT: mwaitx
178 ; Restore base pointer.
179 ; USE_BASE_64-NEXT: movq [[SAVE_rbx]], %rbx
181 ; USE_BASE_32: movl %esp, %ebx
182 ; Pass mwaitx first 2 arguments in eax and ecx respectively.
183 ; USE_BASE_32: movl %esi, %eax
184 ; USE_BASE_32: movl %edi, %ecx
185 ; Save base pointer.
186 ; USE_BASE_32: movq %rbx, [[SAVE_rbx:%r(di|si)]]
187 ; Set mwaitx ebx argument.
188 ; USE_BASE_32: movl %edx, %ebx
189 ; USE_BASE_32-NEXT: mwaitx
190 ; Restore base pointer.
191 ; USE_BASE_32-NEXT: movq [[SAVE_rbx]], %rbx
193 ; Pass mwaitx 3 arguments in eax, ecx, ebx
194 ; NO_BASE_64: movl %edx, %ebx
195 ; NO_BASE_64: movl %esi, %eax
196 ; NO_BASE_64: movl %edi, %ecx
197 ; No need to save base pointer.
198 ; NO_BASE_64-NOT: movq %rbx
199 ; NO_BASE_64: mwaitx
200 ; NO_BASE_64-NOT: movq {{.*}}, %rbx
201 ; NO_BASE_64-NEXT: {{.+$}}
203 ; Pass mwaitx 3 arguments in eax, ecx, ebx
204 ; NO_BASE_32: movl %edx, %ebx
205 ; NO_BASE_32: movl %esi, %eax
206 ; NO_BASE_32: movl %edi, %ecx
207 ; No need to save base pointer.
208 ; NO_BASE_32-NOT: movl %ebx
209 ; NO_BASE_32: mwaitx
210 ; No need to restore base pointer.
211 ; NO_BASE_32-NOT: movl {{.*}}, %ebx
212 ; NO_BASE_32-NEXT: {{.+$}}
214 declare void @llvm.x86.mwaitx(i32, i32, i32) nounwind
215 ;--- _align32.ll
216 !llvm.module.flags = !{!0}
217 !0 = !{i32 2, !"override-stack-alignment", i32 32}