1; RUN: llc < %s -O0 -march=x86-64 -mcpu=corei7 -verify-machineinstrs | FileCheck %s -check-prefix=WITH-CMOV
2; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 -verify-machineinstrs | FileCheck %s -check-prefix=WITH-CMOV
3; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 -mattr=-cmov -verify-machineinstrs | FileCheck %s --check-prefix NOCMOV
4
5@sc32 = external global i32
6
7define void @atomic_fetch_add32() nounwind {
8; WITH-CMOV-LABEL:   atomic_fetch_add32:
9entry:
10; 32-bit
11  %t1 = atomicrmw add  i32* @sc32, i32 1 acquire
12; WITH-CMOV:       lock
13; WITH-CMOV:       incl
14  %t2 = atomicrmw add  i32* @sc32, i32 3 acquire
15; WITH-CMOV:       lock
16; WITH-CMOV:       addl $3
17  %t3 = atomicrmw add  i32* @sc32, i32 5 acquire
18; WITH-CMOV:       lock
19; WITH-CMOV:       xaddl
20  %t4 = atomicrmw add  i32* @sc32, i32 %t3 acquire
21; WITH-CMOV:       lock
22; WITH-CMOV:       addl
23  ret void
24; WITH-CMOV:       ret
25}
26
27define void @atomic_fetch_sub32() nounwind {
28; WITH-CMOV-LABEL:   atomic_fetch_sub32:
29  %t1 = atomicrmw sub  i32* @sc32, i32 1 acquire
30; WITH-CMOV:       lock
31; WITH-CMOV:       decl
32  %t2 = atomicrmw sub  i32* @sc32, i32 3 acquire
33; WITH-CMOV:       lock
34; WITH-CMOV:       subl $3
35  %t3 = atomicrmw sub  i32* @sc32, i32 5 acquire
36; WITH-CMOV:       lock
37; WITH-CMOV:       xaddl
38  %t4 = atomicrmw sub  i32* @sc32, i32 %t3 acquire
39; WITH-CMOV:       lock
40; WITH-CMOV:       subl
41  ret void
42; WITH-CMOV:       ret
43}
44
45define void @atomic_fetch_and32() nounwind {
46; WITH-CMOV-LABEL:   atomic_fetch_and32:
47  %t1 = atomicrmw and  i32* @sc32, i32 3 acquire
48; WITH-CMOV:       lock
49; WITH-CMOV:       andl $3
50  %t2 = atomicrmw and  i32* @sc32, i32 5 acquire
51; WITH-CMOV:       andl
52; WITH-CMOV:       lock
53; WITH-CMOV:       cmpxchgl
54  %t3 = atomicrmw and  i32* @sc32, i32 %t2 acquire
55; WITH-CMOV:       lock
56; WITH-CMOV:       andl
57  ret void
58; WITH-CMOV:       ret
59}
60
61define void @atomic_fetch_or32() nounwind {
62; WITH-CMOV-LABEL:   atomic_fetch_or32:
63  %t1 = atomicrmw or   i32* @sc32, i32 3 acquire
64; WITH-CMOV:       lock
65; WITH-CMOV:       orl $3
66  %t2 = atomicrmw or   i32* @sc32, i32 5 acquire
67; WITH-CMOV:       orl
68; WITH-CMOV:       lock
69; WITH-CMOV:       cmpxchgl
70  %t3 = atomicrmw or   i32* @sc32, i32 %t2 acquire
71; WITH-CMOV:       lock
72; WITH-CMOV:       orl
73  ret void
74; WITH-CMOV:       ret
75}
76
77define void @atomic_fetch_xor32() nounwind {
78; WITH-CMOV-LABEL:   atomic_fetch_xor32:
79  %t1 = atomicrmw xor  i32* @sc32, i32 3 acquire
80; WITH-CMOV:       lock
81; WITH-CMOV:       xorl $3
82  %t2 = atomicrmw xor  i32* @sc32, i32 5 acquire
83; WITH-CMOV:       xorl
84; WITH-CMOV:       lock
85; WITH-CMOV:       cmpxchgl
86  %t3 = atomicrmw xor  i32* @sc32, i32 %t2 acquire
87; WITH-CMOV:       lock
88; WITH-CMOV:       xorl
89  ret void
90; WITH-CMOV:       ret
91}
92
93define void @atomic_fetch_nand32(i32 %x) nounwind {
94; WITH-CMOV-LABEL:   atomic_fetch_nand32:
95  %t1 = atomicrmw nand i32* @sc32, i32 %x acquire
96; WITH-CMOV:       andl
97; WITH-CMOV:       notl
98; WITH-CMOV:       lock
99; WITH-CMOV:       cmpxchgl
100  ret void
101; WITH-CMOV:       ret
102}
103
104define void @atomic_fetch_max32(i32 %x) nounwind {
105; WITH-CMOV-LABEL: atomic_fetch_max32:
106
107  %t1 = atomicrmw max  i32* @sc32, i32 %x acquire
108; WITH-CMOV:       subl
109; WITH-CMOV:       cmov
110; WITH-CMOV:       lock
111; WITH-CMOV:       cmpxchgl
112
113; NOCMOV:    subl
114; NOCMOV:    jge
115; NOCMOV:    lock
116; NOCMOV:    cmpxchgl
117  ret void
118; WITH-CMOV:       ret
119; NOCMOV:    ret
120}
121
122define void @atomic_fetch_min32(i32 %x) nounwind {
123; WITH-CMOV-LABEL: atomic_fetch_min32:
124; NOCMOV-LABEL: atomic_fetch_min32:
125
126  %t1 = atomicrmw min  i32* @sc32, i32 %x acquire
127; WITH-CMOV:       subl
128; WITH-CMOV:       cmov
129; WITH-CMOV:       lock
130; WITH-CMOV:       cmpxchgl
131
132; NOCMOV:    subl
133; NOCMOV:    jle
134; NOCMOV:    lock
135; NOCMOV:    cmpxchgl
136  ret void
137; WITH-CMOV:       ret
138; NOCMOV:    ret
139}
140
141define void @atomic_fetch_umax32(i32 %x) nounwind {
142; WITH-CMOV-LABEL: atomic_fetch_umax32:
143; NOCMOV-LABEL: atomic_fetch_umax32:
144
145  %t1 = atomicrmw umax i32* @sc32, i32 %x acquire
146; WITH-CMOV:       subl
147; WITH-CMOV:       cmov
148; WITH-CMOV:       lock
149; WITH-CMOV:       cmpxchgl
150
151; NOCMOV:    subl
152; NOCMOV:    ja
153; NOCMOV:    lock
154; NOCMOV:    cmpxchgl
155  ret void
156; WITH-CMOV:       ret
157; NOCMOV:    ret
158}
159
160define void @atomic_fetch_umin32(i32 %x) nounwind {
161; WITH-CMOV-LABEL: atomic_fetch_umin32:
162; NOCMOV-LABEL: atomic_fetch_umin32:
163
164  %t1 = atomicrmw umin i32* @sc32, i32 %x acquire
165; WITH-CMOV:       subl
166; WITH-CMOV:       cmov
167; WITH-CMOV:       lock
168; WITH-CMOV:       cmpxchgl
169
170; NOCMOV:    subl
171; NOCMOV:    jb
172; NOCMOV:    lock
173; NOCMOV:    cmpxchgl
174  ret void
175; WITH-CMOV:       ret
176; NOCMOV:    ret
177}
178
179define void @atomic_fetch_cmpxchg32() nounwind {
180; WITH-CMOV-LABEL: atomic_fetch_cmpxchg32:
181
182  %t1 = cmpxchg i32* @sc32, i32 0, i32 1 acquire acquire
183; WITH-CMOV:       lock
184; WITH-CMOV:       cmpxchgl
185  ret void
186; WITH-CMOV:       ret
187}
188
189define void @atomic_fetch_store32(i32 %x) nounwind {
190; WITH-CMOV-LABEL: atomic_fetch_store32:
191
192  store atomic i32 %x, i32* @sc32 release, align 4
193; WITH-CMOV-NOT:   lock
194; WITH-CMOV:       movl
195  ret void
196; WITH-CMOV:       ret
197}
198
199define void @atomic_fetch_swap32(i32 %x) nounwind {
200; WITH-CMOV-LABEL: atomic_fetch_swap32:
201
202  %t1 = atomicrmw xchg i32* @sc32, i32 %x acquire
203; WITH-CMOV-NOT:   lock
204; WITH-CMOV:       xchgl
205  ret void
206; WITH-CMOV:       ret
207}
208