1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mattr=+cmov -mtriple=i386-pc-linux -verify-machineinstrs < %s | FileCheck %s -check-prefix=LINUX
3; RUN: llc -mattr=+cmov -mtriple=i386-macosx -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s -check-prefix=PIC
4
5@sc64 = external dso_local global i64
6
7define i64 @atomic_max_i64() nounwind {
8; LINUX-LABEL: atomic_max_i64:
9; LINUX:       # %bb.0: # %entry
10; LINUX-NEXT:    pushl %ebx
11; LINUX-NEXT:    pushl %esi
12; LINUX-NEXT:    movl sc64+4, %edx
13; LINUX-NEXT:    movl sc64, %eax
14; LINUX-NEXT:    movl $5, %esi
15; LINUX-NEXT:    .p2align 4, 0x90
16; LINUX-NEXT:  .LBB0_1: # %atomicrmw.start
17; LINUX-NEXT:    # =>This Inner Loop Header: Depth=1
18; LINUX-NEXT:    cmpl %eax, %esi
19; LINUX-NEXT:    movl $0, %ecx
20; LINUX-NEXT:    sbbl %edx, %ecx
21; LINUX-NEXT:    movl $0, %ecx
22; LINUX-NEXT:    cmovll %edx, %ecx
23; LINUX-NEXT:    movl $5, %ebx
24; LINUX-NEXT:    cmovll %eax, %ebx
25; LINUX-NEXT:    lock cmpxchg8b sc64
26; LINUX-NEXT:    jne .LBB0_1
27; LINUX-NEXT:  # %bb.2: # %atomicrmw.end
28; LINUX-NEXT:    popl %esi
29; LINUX-NEXT:    popl %ebx
30; LINUX-NEXT:    retl
31;
32; PIC-LABEL: atomic_max_i64:
33; PIC:       ## %bb.0: ## %entry
34; PIC-NEXT:    pushl %ebx
35; PIC-NEXT:    pushl %edi
36; PIC-NEXT:    pushl %esi
37; PIC-NEXT:    calll L0$pb
38; PIC-NEXT:  L0$pb:
39; PIC-NEXT:    popl %eax
40; PIC-NEXT:    movl L_sc64$non_lazy_ptr-L0$pb(%eax), %esi
41; PIC-NEXT:    movl (%esi), %eax
42; PIC-NEXT:    movl 4(%esi), %edx
43; PIC-NEXT:    movl $5, %edi
44; PIC-NEXT:    .p2align 4, 0x90
45; PIC-NEXT:  LBB0_1: ## %atomicrmw.start
46; PIC-NEXT:    ## =>This Inner Loop Header: Depth=1
47; PIC-NEXT:    cmpl %eax, %edi
48; PIC-NEXT:    movl $0, %ecx
49; PIC-NEXT:    sbbl %edx, %ecx
50; PIC-NEXT:    movl $0, %ecx
51; PIC-NEXT:    cmovll %edx, %ecx
52; PIC-NEXT:    movl $5, %ebx
53; PIC-NEXT:    cmovll %eax, %ebx
54; PIC-NEXT:    lock cmpxchg8b (%esi)
55; PIC-NEXT:    jne LBB0_1
56; PIC-NEXT:  ## %bb.2: ## %atomicrmw.end
57; PIC-NEXT:    popl %esi
58; PIC-NEXT:    popl %edi
59; PIC-NEXT:    popl %ebx
60; PIC-NEXT:    retl
61; PIC-NEXT:    ## -- End function
62entry:
63  %max = atomicrmw max i64* @sc64, i64 5 acquire
64  ret i64 %max
65}
66
67define i64 @atomic_min_i64() nounwind {
68; LINUX-LABEL: atomic_min_i64:
69; LINUX:       # %bb.0: # %entry
70; LINUX-NEXT:    pushl %ebx
71; LINUX-NEXT:    movl sc64+4, %edx
72; LINUX-NEXT:    movl sc64, %eax
73; LINUX-NEXT:    .p2align 4, 0x90
74; LINUX-NEXT:  .LBB1_1: # %atomicrmw.start
75; LINUX-NEXT:    # =>This Inner Loop Header: Depth=1
76; LINUX-NEXT:    cmpl $7, %eax
77; LINUX-NEXT:    movl %edx, %ecx
78; LINUX-NEXT:    sbbl $0, %ecx
79; LINUX-NEXT:    movl $0, %ecx
80; LINUX-NEXT:    cmovll %edx, %ecx
81; LINUX-NEXT:    movl $6, %ebx
82; LINUX-NEXT:    cmovll %eax, %ebx
83; LINUX-NEXT:    lock cmpxchg8b sc64
84; LINUX-NEXT:    jne .LBB1_1
85; LINUX-NEXT:  # %bb.2: # %atomicrmw.end
86; LINUX-NEXT:    popl %ebx
87; LINUX-NEXT:    retl
88;
89; PIC-LABEL: atomic_min_i64:
90; PIC:       ## %bb.0: ## %entry
91; PIC-NEXT:    pushl %ebx
92; PIC-NEXT:    pushl %esi
93; PIC-NEXT:    calll L1$pb
94; PIC-NEXT:  L1$pb:
95; PIC-NEXT:    popl %eax
96; PIC-NEXT:    movl L_sc64$non_lazy_ptr-L1$pb(%eax), %esi
97; PIC-NEXT:    movl (%esi), %eax
98; PIC-NEXT:    movl 4(%esi), %edx
99; PIC-NEXT:    .p2align 4, 0x90
100; PIC-NEXT:  LBB1_1: ## %atomicrmw.start
101; PIC-NEXT:    ## =>This Inner Loop Header: Depth=1
102; PIC-NEXT:    cmpl $7, %eax
103; PIC-NEXT:    movl %edx, %ecx
104; PIC-NEXT:    sbbl $0, %ecx
105; PIC-NEXT:    movl $0, %ecx
106; PIC-NEXT:    cmovll %edx, %ecx
107; PIC-NEXT:    movl $6, %ebx
108; PIC-NEXT:    cmovll %eax, %ebx
109; PIC-NEXT:    lock cmpxchg8b (%esi)
110; PIC-NEXT:    jne LBB1_1
111; PIC-NEXT:  ## %bb.2: ## %atomicrmw.end
112; PIC-NEXT:    popl %esi
113; PIC-NEXT:    popl %ebx
114; PIC-NEXT:    retl
115; PIC-NEXT:    ## -- End function
116entry:
117  %min = atomicrmw min i64* @sc64, i64 6 acquire
118  ret i64 %min
119}
120
121define i64 @atomic_umax_i64() nounwind {
122; LINUX-LABEL: atomic_umax_i64:
123; LINUX:       # %bb.0: # %entry
124; LINUX-NEXT:    pushl %ebx
125; LINUX-NEXT:    pushl %esi
126; LINUX-NEXT:    movl sc64+4, %edx
127; LINUX-NEXT:    movl sc64, %eax
128; LINUX-NEXT:    movl $7, %esi
129; LINUX-NEXT:    .p2align 4, 0x90
130; LINUX-NEXT:  .LBB2_1: # %atomicrmw.start
131; LINUX-NEXT:    # =>This Inner Loop Header: Depth=1
132; LINUX-NEXT:    cmpl %eax, %esi
133; LINUX-NEXT:    movl $0, %ecx
134; LINUX-NEXT:    sbbl %edx, %ecx
135; LINUX-NEXT:    movl $0, %ecx
136; LINUX-NEXT:    cmovbl %edx, %ecx
137; LINUX-NEXT:    movl $7, %ebx
138; LINUX-NEXT:    cmovbl %eax, %ebx
139; LINUX-NEXT:    lock cmpxchg8b sc64
140; LINUX-NEXT:    jne .LBB2_1
141; LINUX-NEXT:  # %bb.2: # %atomicrmw.end
142; LINUX-NEXT:    popl %esi
143; LINUX-NEXT:    popl %ebx
144; LINUX-NEXT:    retl
145;
146; PIC-LABEL: atomic_umax_i64:
147; PIC:       ## %bb.0: ## %entry
148; PIC-NEXT:    pushl %ebx
149; PIC-NEXT:    pushl %edi
150; PIC-NEXT:    pushl %esi
151; PIC-NEXT:    calll L2$pb
152; PIC-NEXT:  L2$pb:
153; PIC-NEXT:    popl %eax
154; PIC-NEXT:    movl L_sc64$non_lazy_ptr-L2$pb(%eax), %esi
155; PIC-NEXT:    movl (%esi), %eax
156; PIC-NEXT:    movl 4(%esi), %edx
157; PIC-NEXT:    movl $7, %edi
158; PIC-NEXT:    .p2align 4, 0x90
159; PIC-NEXT:  LBB2_1: ## %atomicrmw.start
160; PIC-NEXT:    ## =>This Inner Loop Header: Depth=1
161; PIC-NEXT:    cmpl %eax, %edi
162; PIC-NEXT:    movl $0, %ecx
163; PIC-NEXT:    sbbl %edx, %ecx
164; PIC-NEXT:    movl $0, %ecx
165; PIC-NEXT:    cmovbl %edx, %ecx
166; PIC-NEXT:    movl $7, %ebx
167; PIC-NEXT:    cmovbl %eax, %ebx
168; PIC-NEXT:    lock cmpxchg8b (%esi)
169; PIC-NEXT:    jne LBB2_1
170; PIC-NEXT:  ## %bb.2: ## %atomicrmw.end
171; PIC-NEXT:    popl %esi
172; PIC-NEXT:    popl %edi
173; PIC-NEXT:    popl %ebx
174; PIC-NEXT:    retl
175; PIC-NEXT:    ## -- End function
176entry:
177  %umax = atomicrmw umax i64* @sc64, i64 7 acquire
178  ret i64 %umax
179}
180
181define i64 @atomic_umin_i64() nounwind {
182; LINUX-LABEL: atomic_umin_i64:
183; LINUX:       # %bb.0: # %entry
184; LINUX-NEXT:    pushl %ebx
185; LINUX-NEXT:    movl sc64+4, %edx
186; LINUX-NEXT:    movl sc64, %eax
187; LINUX-NEXT:    .p2align 4, 0x90
188; LINUX-NEXT:  .LBB3_1: # %atomicrmw.start
189; LINUX-NEXT:    # =>This Inner Loop Header: Depth=1
190; LINUX-NEXT:    cmpl $9, %eax
191; LINUX-NEXT:    movl %edx, %ecx
192; LINUX-NEXT:    sbbl $0, %ecx
193; LINUX-NEXT:    movl $0, %ecx
194; LINUX-NEXT:    cmovbl %edx, %ecx
195; LINUX-NEXT:    movl $8, %ebx
196; LINUX-NEXT:    cmovbl %eax, %ebx
197; LINUX-NEXT:    lock cmpxchg8b sc64
198; LINUX-NEXT:    jne .LBB3_1
199; LINUX-NEXT:  # %bb.2: # %atomicrmw.end
200; LINUX-NEXT:    popl %ebx
201; LINUX-NEXT:    retl
202;
203; PIC-LABEL: atomic_umin_i64:
204; PIC:       ## %bb.0: ## %entry
205; PIC-NEXT:    pushl %ebx
206; PIC-NEXT:    pushl %esi
207; PIC-NEXT:    calll L3$pb
208; PIC-NEXT:  L3$pb:
209; PIC-NEXT:    popl %eax
210; PIC-NEXT:    movl L_sc64$non_lazy_ptr-L3$pb(%eax), %esi
211; PIC-NEXT:    movl (%esi), %eax
212; PIC-NEXT:    movl 4(%esi), %edx
213; PIC-NEXT:    .p2align 4, 0x90
214; PIC-NEXT:  LBB3_1: ## %atomicrmw.start
215; PIC-NEXT:    ## =>This Inner Loop Header: Depth=1
216; PIC-NEXT:    cmpl $9, %eax
217; PIC-NEXT:    movl %edx, %ecx
218; PIC-NEXT:    sbbl $0, %ecx
219; PIC-NEXT:    movl $0, %ecx
220; PIC-NEXT:    cmovbl %edx, %ecx
221; PIC-NEXT:    movl $8, %ebx
222; PIC-NEXT:    cmovbl %eax, %ebx
223; PIC-NEXT:    lock cmpxchg8b (%esi)
224; PIC-NEXT:    jne LBB3_1
225; PIC-NEXT:  ## %bb.2: ## %atomicrmw.end
226; PIC-NEXT:    popl %esi
227; PIC-NEXT:    popl %ebx
228; PIC-NEXT:    retl
229; PIC-NEXT:    ## -- End function
230entry:
231  %umin = atomicrmw umin i64* @sc64, i64 8 acquire
232  ret i64 %umin
233}
234
235@id = internal global i64 0, align 8
236
237define void @tf_bug(i8* %ptr) nounwind {
238; LINUX-LABEL: tf_bug:
239; LINUX:       # %bb.0: # %entry
240; LINUX-NEXT:    pushl %ebx
241; LINUX-NEXT:    pushl %esi
242; LINUX-NEXT:    movl {{[0-9]+}}(%esp), %esi
243; LINUX-NEXT:    movl id+4, %edx
244; LINUX-NEXT:    movl id, %eax
245; LINUX-NEXT:    .p2align 4, 0x90
246; LINUX-NEXT:  .LBB4_1: # %atomicrmw.start
247; LINUX-NEXT:    # =>This Inner Loop Header: Depth=1
248; LINUX-NEXT:    movl %eax, %ebx
249; LINUX-NEXT:    addl $1, %ebx
250; LINUX-NEXT:    movl %edx, %ecx
251; LINUX-NEXT:    adcl $0, %ecx
252; LINUX-NEXT:    lock cmpxchg8b id
253; LINUX-NEXT:    jne .LBB4_1
254; LINUX-NEXT:  # %bb.2: # %atomicrmw.end
255; LINUX-NEXT:    addl $1, %eax
256; LINUX-NEXT:    adcl $0, %edx
257; LINUX-NEXT:    movl %eax, (%esi)
258; LINUX-NEXT:    movl %edx, 4(%esi)
259; LINUX-NEXT:    popl %esi
260; LINUX-NEXT:    popl %ebx
261; LINUX-NEXT:    retl
262;
263; PIC-LABEL: tf_bug:
264; PIC:       ## %bb.0: ## %entry
265; PIC-NEXT:    pushl %ebx
266; PIC-NEXT:    pushl %edi
267; PIC-NEXT:    pushl %esi
268; PIC-NEXT:    calll L4$pb
269; PIC-NEXT:  L4$pb:
270; PIC-NEXT:    popl %edi
271; PIC-NEXT:    movl {{[0-9]+}}(%esp), %esi
272; PIC-NEXT:    movl (_id-L4$pb)+4(%edi), %edx
273; PIC-NEXT:    movl _id-L4$pb(%edi), %eax
274; PIC-NEXT:    .p2align 4, 0x90
275; PIC-NEXT:  LBB4_1: ## %atomicrmw.start
276; PIC-NEXT:    ## =>This Inner Loop Header: Depth=1
277; PIC-NEXT:    movl %eax, %ebx
278; PIC-NEXT:    addl $1, %ebx
279; PIC-NEXT:    movl %edx, %ecx
280; PIC-NEXT:    adcl $0, %ecx
281; PIC-NEXT:    lock cmpxchg8b _id-L4$pb(%edi)
282; PIC-NEXT:    jne LBB4_1
283; PIC-NEXT:  ## %bb.2: ## %atomicrmw.end
284; PIC-NEXT:    addl $1, %eax
285; PIC-NEXT:    adcl $0, %edx
286; PIC-NEXT:    movl %eax, (%esi)
287; PIC-NEXT:    movl %edx, 4(%esi)
288; PIC-NEXT:    popl %esi
289; PIC-NEXT:    popl %edi
290; PIC-NEXT:    popl %ebx
291; PIC-NEXT:    retl
292; PIC-NEXT:    ## -- End function
293; PIC-NEXT:  .zerofill __DATA,__bss,_id,8,3 ## @id
294entry:
295  %tmp1 = atomicrmw add i64* @id, i64 1 seq_cst
296  %tmp2 = add i64 %tmp1, 1
297  %tmp3 = bitcast i8* %ptr to i64*
298  store i64 %tmp2, i64* %tmp3, align 4
299  ret void
300}
301