1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-- -verify-machineinstrs | FileCheck %s
3; RUN: llc < %s -mtriple=x86_64-- -mattr=slow-incdec -verify-machineinstrs | FileCheck %s --check-prefix SLOW_INC
4
5; rdar://7103704
6
7define void @sub1(i32* nocapture %p, i32 %v) nounwind ssp {
8; CHECK-LABEL: sub1:
9; CHECK:       # %bb.0: # %entry
10; CHECK-NEXT:    lock subl %esi, (%rdi)
11; CHECK-NEXT:    retq
12;
13; SLOW_INC-LABEL: sub1:
14; SLOW_INC:       # %bb.0: # %entry
15; SLOW_INC-NEXT:    lock subl %esi, (%rdi)
16; SLOW_INC-NEXT:    retq
17entry:
18  %0 = atomicrmw sub i32* %p, i32 %v monotonic
19  ret void
20}
21
22define void @inc4(i64* nocapture %p) nounwind ssp {
23; CHECK-LABEL: inc4:
24; CHECK:       # %bb.0: # %entry
25; CHECK-NEXT:    lock incq (%rdi)
26; CHECK-NEXT:    retq
27;
28; SLOW_INC-LABEL: inc4:
29; SLOW_INC:       # %bb.0: # %entry
30; SLOW_INC-NEXT:    lock addq $1, (%rdi)
31; SLOW_INC-NEXT:    retq
32entry:
33  %0 = atomicrmw add i64* %p, i64 1 monotonic
34  ret void
35}
36
37define void @add8(i64* nocapture %p) nounwind ssp {
38; CHECK-LABEL: add8:
39; CHECK:       # %bb.0: # %entry
40; CHECK-NEXT:    lock addq $2, (%rdi)
41; CHECK-NEXT:    retq
42;
43; SLOW_INC-LABEL: add8:
44; SLOW_INC:       # %bb.0: # %entry
45; SLOW_INC-NEXT:    lock addq $2, (%rdi)
46; SLOW_INC-NEXT:    retq
47entry:
48  %0 = atomicrmw add i64* %p, i64 2 monotonic
49  ret void
50}
51
52define void @add4(i64* nocapture %p, i32 %v) nounwind ssp {
53; CHECK-LABEL: add4:
54; CHECK:       # %bb.0: # %entry
55; CHECK-NEXT:    movslq %esi, %rax
56; CHECK-NEXT:    lock addq %rax, (%rdi)
57; CHECK-NEXT:    retq
58;
59; SLOW_INC-LABEL: add4:
60; SLOW_INC:       # %bb.0: # %entry
61; SLOW_INC-NEXT:    movslq %esi, %rax
62; SLOW_INC-NEXT:    lock addq %rax, (%rdi)
63; SLOW_INC-NEXT:    retq
64entry:
65  %0 = sext i32 %v to i64		; <i64> [#uses=1]
66  %1 = atomicrmw add i64* %p, i64 %0 monotonic
67  ret void
68}
69
70define void @inc3(i8* nocapture %p) nounwind ssp {
71; CHECK-LABEL: inc3:
72; CHECK:       # %bb.0: # %entry
73; CHECK-NEXT:    lock incb (%rdi)
74; CHECK-NEXT:    retq
75;
76; SLOW_INC-LABEL: inc3:
77; SLOW_INC:       # %bb.0: # %entry
78; SLOW_INC-NEXT:    lock addb $1, (%rdi)
79; SLOW_INC-NEXT:    retq
80entry:
81  %0 = atomicrmw add i8* %p, i8 1 monotonic
82  ret void
83}
84
85define void @add7(i8* nocapture %p) nounwind ssp {
86; CHECK-LABEL: add7:
87; CHECK:       # %bb.0: # %entry
88; CHECK-NEXT:    lock addb $2, (%rdi)
89; CHECK-NEXT:    retq
90;
91; SLOW_INC-LABEL: add7:
92; SLOW_INC:       # %bb.0: # %entry
93; SLOW_INC-NEXT:    lock addb $2, (%rdi)
94; SLOW_INC-NEXT:    retq
95entry:
96  %0 = atomicrmw add i8* %p, i8 2 monotonic
97  ret void
98}
99
100define void @add3(i8* nocapture %p, i32 %v) nounwind ssp {
101; CHECK-LABEL: add3:
102; CHECK:       # %bb.0: # %entry
103; CHECK-NEXT:    lock addb %sil, (%rdi)
104; CHECK-NEXT:    retq
105;
106; SLOW_INC-LABEL: add3:
107; SLOW_INC:       # %bb.0: # %entry
108; SLOW_INC-NEXT:    lock addb %sil, (%rdi)
109; SLOW_INC-NEXT:    retq
110entry:
111  %0 = trunc i32 %v to i8		; <i8> [#uses=1]
112  %1 = atomicrmw add i8* %p, i8 %0 monotonic
113  ret void
114}
115
116define void @inc2(i16* nocapture %p) nounwind ssp {
117; CHECK-LABEL: inc2:
118; CHECK:       # %bb.0: # %entry
119; CHECK-NEXT:    lock incw (%rdi)
120; CHECK-NEXT:    retq
121;
122; SLOW_INC-LABEL: inc2:
123; SLOW_INC:       # %bb.0: # %entry
124; SLOW_INC-NEXT:    lock addw $1, (%rdi)
125; SLOW_INC-NEXT:    retq
126entry:
127  %0 = atomicrmw add i16* %p, i16 1 monotonic
128  ret void
129}
130
131define void @add6(i16* nocapture %p) nounwind ssp {
132; CHECK-LABEL: add6:
133; CHECK:       # %bb.0: # %entry
134; CHECK-NEXT:    lock addw $2, (%rdi)
135; CHECK-NEXT:    retq
136;
137; SLOW_INC-LABEL: add6:
138; SLOW_INC:       # %bb.0: # %entry
139; SLOW_INC-NEXT:    lock addw $2, (%rdi)
140; SLOW_INC-NEXT:    retq
141entry:
142  %0 = atomicrmw add i16* %p, i16 2 monotonic
143  ret void
144}
145
146define void @add2(i16* nocapture %p, i32 %v) nounwind ssp {
147; CHECK-LABEL: add2:
148; CHECK:       # %bb.0: # %entry
149; CHECK-NEXT:    lock addw %si, (%rdi)
150; CHECK-NEXT:    retq
151;
152; SLOW_INC-LABEL: add2:
153; SLOW_INC:       # %bb.0: # %entry
154; SLOW_INC-NEXT:    lock addw %si, (%rdi)
155; SLOW_INC-NEXT:    retq
156entry:
157	%0 = trunc i32 %v to i16		; <i16> [#uses=1]
158  %1 = atomicrmw add i16* %p, i16 %0 monotonic
159  ret void
160}
161
162define void @inc1(i32* nocapture %p) nounwind ssp {
163; CHECK-LABEL: inc1:
164; CHECK:       # %bb.0: # %entry
165; CHECK-NEXT:    lock incl (%rdi)
166; CHECK-NEXT:    retq
167;
168; SLOW_INC-LABEL: inc1:
169; SLOW_INC:       # %bb.0: # %entry
170; SLOW_INC-NEXT:    lock addl $1, (%rdi)
171; SLOW_INC-NEXT:    retq
172entry:
173  %0 = atomicrmw add i32* %p, i32 1 monotonic
174  ret void
175}
176
177define void @add5(i32* nocapture %p) nounwind ssp {
178; CHECK-LABEL: add5:
179; CHECK:       # %bb.0: # %entry
180; CHECK-NEXT:    lock addl $2, (%rdi)
181; CHECK-NEXT:    retq
182;
183; SLOW_INC-LABEL: add5:
184; SLOW_INC:       # %bb.0: # %entry
185; SLOW_INC-NEXT:    lock addl $2, (%rdi)
186; SLOW_INC-NEXT:    retq
187entry:
188  %0 = atomicrmw add i32* %p, i32 2 monotonic
189  ret void
190}
191
192define void @add1(i32* nocapture %p, i32 %v) nounwind ssp {
193; CHECK-LABEL: add1:
194; CHECK:       # %bb.0: # %entry
195; CHECK-NEXT:    lock addl %esi, (%rdi)
196; CHECK-NEXT:    retq
197;
198; SLOW_INC-LABEL: add1:
199; SLOW_INC:       # %bb.0: # %entry
200; SLOW_INC-NEXT:    lock addl %esi, (%rdi)
201; SLOW_INC-NEXT:    retq
202entry:
203  %0 = atomicrmw add i32* %p, i32 %v monotonic
204  ret void
205}
206
207define void @dec4(i64* nocapture %p) nounwind ssp {
208; CHECK-LABEL: dec4:
209; CHECK:       # %bb.0: # %entry
210; CHECK-NEXT:    lock decq (%rdi)
211; CHECK-NEXT:    retq
212;
213; SLOW_INC-LABEL: dec4:
214; SLOW_INC:       # %bb.0: # %entry
215; SLOW_INC-NEXT:    lock subq $1, (%rdi)
216; SLOW_INC-NEXT:    retq
217entry:
218  %0 = atomicrmw sub i64* %p, i64 1 monotonic
219  ret void
220}
221
222define void @sub8(i64* nocapture %p) nounwind ssp {
223; CHECK-LABEL: sub8:
224; CHECK:       # %bb.0: # %entry
225; CHECK-NEXT:    lock subq $2, (%rdi)
226; CHECK-NEXT:    retq
227;
228; SLOW_INC-LABEL: sub8:
229; SLOW_INC:       # %bb.0: # %entry
230; SLOW_INC-NEXT:    lock subq $2, (%rdi)
231; SLOW_INC-NEXT:    retq
232entry:
233  %0 = atomicrmw sub i64* %p, i64 2 monotonic
234  ret void
235}
236
237define void @sub4(i64* nocapture %p, i32 %v) nounwind ssp {
238; CHECK-LABEL: sub4:
239; CHECK:       # %bb.0: # %entry
240; CHECK-NEXT:    movslq %esi, %rax
241; CHECK-NEXT:    lock subq %rax, (%rdi)
242; CHECK-NEXT:    retq
243;
244; SLOW_INC-LABEL: sub4:
245; SLOW_INC:       # %bb.0: # %entry
246; SLOW_INC-NEXT:    movslq %esi, %rax
247; SLOW_INC-NEXT:    lock subq %rax, (%rdi)
248; SLOW_INC-NEXT:    retq
249entry:
250	%0 = sext i32 %v to i64		; <i64> [#uses=1]
251  %1 = atomicrmw sub i64* %p, i64 %0 monotonic
252  ret void
253}
254
255define void @dec3(i8* nocapture %p) nounwind ssp {
256; CHECK-LABEL: dec3:
257; CHECK:       # %bb.0: # %entry
258; CHECK-NEXT:    lock decb (%rdi)
259; CHECK-NEXT:    retq
260;
261; SLOW_INC-LABEL: dec3:
262; SLOW_INC:       # %bb.0: # %entry
263; SLOW_INC-NEXT:    lock subb $1, (%rdi)
264; SLOW_INC-NEXT:    retq
265entry:
266  %0 = atomicrmw sub i8* %p, i8 1 monotonic
267  ret void
268}
269
270define void @sub7(i8* nocapture %p) nounwind ssp {
271; CHECK-LABEL: sub7:
272; CHECK:       # %bb.0: # %entry
273; CHECK-NEXT:    lock subb $2, (%rdi)
274; CHECK-NEXT:    retq
275;
276; SLOW_INC-LABEL: sub7:
277; SLOW_INC:       # %bb.0: # %entry
278; SLOW_INC-NEXT:    lock subb $2, (%rdi)
279; SLOW_INC-NEXT:    retq
280entry:
281  %0 = atomicrmw sub i8* %p, i8 2 monotonic
282  ret void
283}
284
285define void @sub3(i8* nocapture %p, i32 %v) nounwind ssp {
286; CHECK-LABEL: sub3:
287; CHECK:       # %bb.0: # %entry
288; CHECK-NEXT:    lock subb %sil, (%rdi)
289; CHECK-NEXT:    retq
290;
291; SLOW_INC-LABEL: sub3:
292; SLOW_INC:       # %bb.0: # %entry
293; SLOW_INC-NEXT:    lock subb %sil, (%rdi)
294; SLOW_INC-NEXT:    retq
295entry:
296	%0 = trunc i32 %v to i8		; <i8> [#uses=1]
297  %1 = atomicrmw sub i8* %p, i8 %0 monotonic
298  ret void
299}
300
301define void @dec2(i16* nocapture %p) nounwind ssp {
302; CHECK-LABEL: dec2:
303; CHECK:       # %bb.0: # %entry
304; CHECK-NEXT:    lock decw (%rdi)
305; CHECK-NEXT:    retq
306;
307; SLOW_INC-LABEL: dec2:
308; SLOW_INC:       # %bb.0: # %entry
309; SLOW_INC-NEXT:    lock subw $1, (%rdi)
310; SLOW_INC-NEXT:    retq
311entry:
312  %0 = atomicrmw sub i16* %p, i16 1 monotonic
313  ret void
314}
315
316define void @sub6(i16* nocapture %p) nounwind ssp {
317; CHECK-LABEL: sub6:
318; CHECK:       # %bb.0: # %entry
319; CHECK-NEXT:    lock subw $2, (%rdi)
320; CHECK-NEXT:    retq
321;
322; SLOW_INC-LABEL: sub6:
323; SLOW_INC:       # %bb.0: # %entry
324; SLOW_INC-NEXT:    lock subw $2, (%rdi)
325; SLOW_INC-NEXT:    retq
326entry:
327  %0 = atomicrmw sub i16* %p, i16 2 monotonic
328  ret void
329}
330
331define void @sub2(i16* nocapture %p, i32 %v) nounwind ssp {
332; CHECK-LABEL: sub2:
333; CHECK:       # %bb.0: # %entry
334; CHECK-NEXT:    lock subw %si, (%rdi)
335; CHECK-NEXT:    retq
336;
337; SLOW_INC-LABEL: sub2:
338; SLOW_INC:       # %bb.0: # %entry
339; SLOW_INC-NEXT:    lock subw %si, (%rdi)
340; SLOW_INC-NEXT:    retq
341entry:
342	%0 = trunc i32 %v to i16		; <i16> [#uses=1]
343  %1 = atomicrmw sub i16* %p, i16 %0 monotonic
344  ret void
345}
346
347define void @dec1(i32* nocapture %p) nounwind ssp {
348; CHECK-LABEL: dec1:
349; CHECK:       # %bb.0: # %entry
350; CHECK-NEXT:    lock decl (%rdi)
351; CHECK-NEXT:    retq
352;
353; SLOW_INC-LABEL: dec1:
354; SLOW_INC:       # %bb.0: # %entry
355; SLOW_INC-NEXT:    lock subl $1, (%rdi)
356; SLOW_INC-NEXT:    retq
357entry:
358  %0 = atomicrmw sub i32* %p, i32 1 monotonic
359  ret void
360}
361
362define void @sub5(i32* nocapture %p) nounwind ssp {
363; CHECK-LABEL: sub5:
364; CHECK:       # %bb.0: # %entry
365; CHECK-NEXT:    lock subl $2, (%rdi)
366; CHECK-NEXT:    retq
367;
368; SLOW_INC-LABEL: sub5:
369; SLOW_INC:       # %bb.0: # %entry
370; SLOW_INC-NEXT:    lock subl $2, (%rdi)
371; SLOW_INC-NEXT:    retq
372entry:
373  %0 = atomicrmw sub i32* %p, i32 2 monotonic
374  ret void
375}
376