1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -verify-machineinstrs -mtriple x86_64-linux < %s | FileCheck %s
3 ; RUN: llc -verify-machineinstrs -mtriple x86_64-windows < %s | FileCheck %s --check-prefix=WIN64
5 declare i64 @llvm.x86.flags.read.u64()
6 declare void @llvm.x86.flags.write.u64(i64)
8 define i64 @read_flags() {
9 ; CHECK-LABEL: read_flags:
10 ; CHECK: # %bb.0: # %entry
12 ; CHECK-NEXT: popq %rax
15 ; WIN64-LABEL: read_flags:
16 ; WIN64: # %bb.0: # %entry
17 ; WIN64-NEXT: pushq %rbp
18 ; WIN64-NEXT: .seh_pushreg %rbp
19 ; WIN64-NEXT: movq %rsp, %rbp
20 ; WIN64-NEXT: .seh_setframe %rbp, 0
21 ; WIN64-NEXT: .seh_endprologue
23 ; WIN64-NEXT: popq %rax
24 ; WIN64-NEXT: popq %rbp
26 ; WIN64-NEXT: .seh_endproc
28 %flags = call i64 @llvm.x86.flags.read.u64()
32 define void @write_flags(i64 %arg) {
33 ; CHECK-LABEL: write_flags:
34 ; CHECK: # %bb.0: # %entry
35 ; CHECK-NEXT: pushq %rdi
39 ; WIN64-LABEL: write_flags:
40 ; WIN64: # %bb.0: # %entry
41 ; WIN64-NEXT: pushq %rbp
42 ; WIN64-NEXT: .seh_pushreg %rbp
43 ; WIN64-NEXT: movq %rsp, %rbp
44 ; WIN64-NEXT: .seh_setframe %rbp, 0
45 ; WIN64-NEXT: .seh_endprologue
46 ; WIN64-NEXT: pushq %rcx
48 ; WIN64-NEXT: popq %rbp
50 ; WIN64-NEXT: .seh_endproc
52 call void @llvm.x86.flags.write.u64(i64 %arg)
56 define i64 @read_flags_reg_pressure() nounwind {
57 ; CHECK-LABEL: read_flags_reg_pressure:
59 ; CHECK-NEXT: pushq %rbp
60 ; CHECK-NEXT: pushq %r15
61 ; CHECK-NEXT: pushq %r14
62 ; CHECK-NEXT: pushq %r13
63 ; CHECK-NEXT: pushq %r12
64 ; CHECK-NEXT: pushq %rbx
65 ; CHECK-NEXT: subq $16, %rsp
68 ; CHECK-NEXT: movq %rdx, (%rsp) # 8-byte Spill
70 ; CHECK-NEXT: popq %rdx
71 ; CHECK-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
72 ; CHECK-NEXT: movq (%rsp), %rdx # 8-byte Reload
75 ; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
76 ; CHECK-NEXT: addq $16, %rsp
77 ; CHECK-NEXT: popq %rbx
78 ; CHECK-NEXT: popq %r12
79 ; CHECK-NEXT: popq %r13
80 ; CHECK-NEXT: popq %r14
81 ; CHECK-NEXT: popq %r15
82 ; CHECK-NEXT: popq %rbp
85 ; WIN64-LABEL: read_flags_reg_pressure:
87 ; WIN64-NEXT: pushq %rbp
88 ; WIN64-NEXT: pushq %r15
89 ; WIN64-NEXT: pushq %r14
90 ; WIN64-NEXT: pushq %r13
91 ; WIN64-NEXT: pushq %r12
92 ; WIN64-NEXT: pushq %rsi
93 ; WIN64-NEXT: pushq %rdi
94 ; WIN64-NEXT: pushq %rbx
95 ; WIN64-NEXT: subq $16, %rsp
96 ; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
99 ; WIN64-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
101 ; WIN64-NEXT: popq %rdx
102 ; WIN64-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
103 ; WIN64-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
105 ; WIN64-NEXT: #NO_APP
106 ; WIN64-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
107 ; WIN64-NEXT: addq $16, %rsp
108 ; WIN64-NEXT: popq %rbx
109 ; WIN64-NEXT: popq %rdi
110 ; WIN64-NEXT: popq %rsi
111 ; WIN64-NEXT: popq %r12
112 ; WIN64-NEXT: popq %r13
113 ; WIN64-NEXT: popq %r14
114 ; WIN64-NEXT: popq %r15
115 ; WIN64-NEXT: popq %rbp
117 %1 = tail call { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } asm sideeffect "", "={ax},={bx},={cx},={dx},={si},={di},={bp},={r8},={r9},={r10},={r11},={r12},={r13},={r14},={r15},~{dirflag},~{fpsr},~{flags}"()
118 %2 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 0
119 %3 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 1
120 %4 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 2
121 %5 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 3
122 %6 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 4
123 %7 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 5
124 %8 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 6
125 %9 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 7
126 %10 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 8
127 %11 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 9
128 %12 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 10
129 %13 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 11
130 %14 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 12
131 %15 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 13
132 %16 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %1, 14
133 %17 = tail call i64 @llvm.x86.flags.read.u64()
134 tail call void asm sideeffect "", "{ax},{bx},{cx},{dx},{si},{di},{bp},{r8},{r9},{r10},{r11},{r12},{r13},{r14},{r15},~{dirflag},~{fpsr},~{flags}"(i64 %2, i64 %3, i64 %4, i64 %5, i64 %6, i64 %7, i64 %8, i64 %9, i64 %10, i64 %11, i64 %12, i64 %13, i64 %14, i64 %15, i64 %16)
138 define void @write_flags_reg_pressure(i64 noundef %0) nounwind {
139 ; CHECK-LABEL: write_flags_reg_pressure:
141 ; CHECK-NEXT: pushq %rbp
142 ; CHECK-NEXT: pushq %r15
143 ; CHECK-NEXT: pushq %r14
144 ; CHECK-NEXT: pushq %r13
145 ; CHECK-NEXT: pushq %r12
146 ; CHECK-NEXT: pushq %rbx
147 ; CHECK-NEXT: subq $16, %rsp
148 ; CHECK-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
150 ; CHECK-NEXT: #NO_APP
151 ; CHECK-NEXT: movq %rdx, (%rsp) # 8-byte Spill
152 ; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
153 ; CHECK-NEXT: pushq %rdx
155 ; CHECK-NEXT: movq (%rsp), %rdx # 8-byte Reload
157 ; CHECK-NEXT: #NO_APP
158 ; CHECK-NEXT: addq $16, %rsp
159 ; CHECK-NEXT: popq %rbx
160 ; CHECK-NEXT: popq %r12
161 ; CHECK-NEXT: popq %r13
162 ; CHECK-NEXT: popq %r14
163 ; CHECK-NEXT: popq %r15
164 ; CHECK-NEXT: popq %rbp
167 ; WIN64-LABEL: write_flags_reg_pressure:
169 ; WIN64-NEXT: pushq %rbp
170 ; WIN64-NEXT: pushq %r15
171 ; WIN64-NEXT: pushq %r14
172 ; WIN64-NEXT: pushq %r13
173 ; WIN64-NEXT: pushq %r12
174 ; WIN64-NEXT: pushq %rsi
175 ; WIN64-NEXT: pushq %rdi
176 ; WIN64-NEXT: pushq %rbx
177 ; WIN64-NEXT: subq $16, %rsp
178 ; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rbp
179 ; WIN64-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
181 ; WIN64-NEXT: #NO_APP
182 ; WIN64-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
183 ; WIN64-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
184 ; WIN64-NEXT: pushq %rdx
186 ; WIN64-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload
188 ; WIN64-NEXT: #NO_APP
189 ; WIN64-NEXT: addq $16, %rsp
190 ; WIN64-NEXT: popq %rbx
191 ; WIN64-NEXT: popq %rdi
192 ; WIN64-NEXT: popq %rsi
193 ; WIN64-NEXT: popq %r12
194 ; WIN64-NEXT: popq %r13
195 ; WIN64-NEXT: popq %r14
196 ; WIN64-NEXT: popq %r15
197 ; WIN64-NEXT: popq %rbp
199 %2 = tail call { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } asm sideeffect "", "={ax},={bx},={cx},={dx},={si},={di},={bp},={r8},={r9},={r10},={r11},={r12},={r13},={r14},={r15},~{dirflag},~{fpsr},~{flags}"()
200 %3 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 0
201 %4 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 1
202 %5 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 2
203 %6 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 3
204 %7 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 4
205 %8 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 5
206 %9 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 6
207 %10 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 7
208 %11 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 8
209 %12 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 9
210 %13 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 10
211 %14 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 11
212 %15 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 12
213 %16 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 13
214 %17 = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } %2, 14
215 tail call void @llvm.x86.flags.write.u64(i64 %0)
216 tail call void asm sideeffect "", "{ax},{bx},{cx},{dx},{si},{di},{bp},{r8},{r9},{r10},{r11},{r12},{r13},{r14},{r15},~{dirflag},~{fpsr},~{flags}"(i64 %3, i64 %4, i64 %5, i64 %6, i64 %7, i64 %8, i64 %9, i64 %10, i64 %11, i64 %12, i64 %13, i64 %14, i64 %15, i64 %16, i64 %17)