• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mcpu=generic -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X32
3; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s --check-prefixes=X64,X64-LINUX
4; RUN: llc < %s -mcpu=generic -mtriple=x86_64-win32 | FileCheck %s --check-prefixes=X64,X64-WIN32
5
6declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32)
7declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)
8
9; The immediate can be encoded in a smaller way if the
10; instruction is a sub instead of an add.
11define i32 @test1(i32 inreg %a) nounwind {
12; X32-LABEL: test1:
13; X32:       # %bb.0: # %entry
14; X32-NEXT:    subl $-128, %eax
15; X32-NEXT:    retl
16;
17; X64-LINUX-LABEL: test1:
18; X64-LINUX:       # %bb.0: # %entry
19; X64-LINUX-NEXT:    subl $-128, %edi
20; X64-LINUX-NEXT:    movl %edi, %eax
21; X64-LINUX-NEXT:    retq
22;
23; X64-WIN32-LABEL: test1:
24; X64-WIN32:       # %bb.0: # %entry
25; X64-WIN32-NEXT:    subl $-128, %ecx
26; X64-WIN32-NEXT:    movl %ecx, %eax
27; X64-WIN32-NEXT:    retq
28entry:
29  %b = add i32 %a, 128
30  ret i32 %b
31}
32define i64 @test2(i64 inreg %a) nounwind {
33; X32-LABEL: test2:
34; X32:       # %bb.0: # %entry
35; X32-NEXT:    addl $-2147483648, %eax # imm = 0x80000000
36; X32-NEXT:    adcl $0, %edx
37; X32-NEXT:    retl
38;
39; X64-LINUX-LABEL: test2:
40; X64-LINUX:       # %bb.0: # %entry
41; X64-LINUX-NEXT:    subq $-2147483648, %rdi # imm = 0x80000000
42; X64-LINUX-NEXT:    movq %rdi, %rax
43; X64-LINUX-NEXT:    retq
44;
45; X64-WIN32-LABEL: test2:
46; X64-WIN32:       # %bb.0: # %entry
47; X64-WIN32-NEXT:    subq $-2147483648, %rcx # imm = 0x80000000
48; X64-WIN32-NEXT:    movq %rcx, %rax
49; X64-WIN32-NEXT:    retq
50entry:
51  %b = add i64 %a, 2147483648
52  ret i64 %b
53}
54define i64 @test3(i64 inreg %a) nounwind {
55; X32-LABEL: test3:
56; X32:       # %bb.0: # %entry
57; X32-NEXT:    addl $128, %eax
58; X32-NEXT:    adcl $0, %edx
59; X32-NEXT:    retl
60;
61; X64-LINUX-LABEL: test3:
62; X64-LINUX:       # %bb.0: # %entry
63; X64-LINUX-NEXT:    subq $-128, %rdi
64; X64-LINUX-NEXT:    movq %rdi, %rax
65; X64-LINUX-NEXT:    retq
66;
67; X64-WIN32-LABEL: test3:
68; X64-WIN32:       # %bb.0: # %entry
69; X64-WIN32-NEXT:    subq $-128, %rcx
70; X64-WIN32-NEXT:    movq %rcx, %rax
71; X64-WIN32-NEXT:    retq
72entry:
73  %b = add i64 %a, 128
74  ret i64 %b
75}
76
77define i1 @test4(i32 %v1, i32 %v2, i32* %X) nounwind {
78; X32-LABEL: test4:
79; X32:       # %bb.0: # %entry
80; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
81; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
82; X32-NEXT:    jo .LBB3_2
83; X32-NEXT:  # %bb.1: # %normal
84; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
85; X32-NEXT:    movl $0, (%eax)
86; X32-NEXT:  .LBB3_2: # %overflow
87; X32-NEXT:    xorl %eax, %eax
88; X32-NEXT:    retl
89;
90; X64-LINUX-LABEL: test4:
91; X64-LINUX:       # %bb.0: # %entry
92; X64-LINUX-NEXT:    addl %esi, %edi
93; X64-LINUX-NEXT:    jo .LBB3_2
94; X64-LINUX-NEXT:  # %bb.1: # %normal
95; X64-LINUX-NEXT:    movl $0, (%rdx)
96; X64-LINUX-NEXT:  .LBB3_2: # %overflow
97; X64-LINUX-NEXT:    xorl %eax, %eax
98; X64-LINUX-NEXT:    retq
99;
100; X64-WIN32-LABEL: test4:
101; X64-WIN32:       # %bb.0: # %entry
102; X64-WIN32-NEXT:    addl %edx, %ecx
103; X64-WIN32-NEXT:    jo .LBB3_2
104; X64-WIN32-NEXT:  # %bb.1: # %normal
105; X64-WIN32-NEXT:    movl $0, (%r8)
106; X64-WIN32-NEXT:  .LBB3_2: # %overflow
107; X64-WIN32-NEXT:    xorl %eax, %eax
108; X64-WIN32-NEXT:    retq
109entry:
110  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
111  %sum = extractvalue {i32, i1} %t, 0
112  %obit = extractvalue {i32, i1} %t, 1
113  br i1 %obit, label %overflow, label %normal
114
115normal:
116  store i32 0, i32* %X
117  br label %overflow
118
119overflow:
120  ret i1 false
121}
122
123define i1 @test5(i32 %v1, i32 %v2, i32* %X) nounwind {
124; X32-LABEL: test5:
125; X32:       # %bb.0: # %entry
126; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
127; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
128; X32-NEXT:    jb .LBB4_2
129; X32-NEXT:  # %bb.1: # %normal
130; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
131; X32-NEXT:    movl $0, (%eax)
132; X32-NEXT:  .LBB4_2: # %carry
133; X32-NEXT:    xorl %eax, %eax
134; X32-NEXT:    retl
135;
136; X64-LINUX-LABEL: test5:
137; X64-LINUX:       # %bb.0: # %entry
138; X64-LINUX-NEXT:    addl %esi, %edi
139; X64-LINUX-NEXT:    jb .LBB4_2
140; X64-LINUX-NEXT:  # %bb.1: # %normal
141; X64-LINUX-NEXT:    movl $0, (%rdx)
142; X64-LINUX-NEXT:  .LBB4_2: # %carry
143; X64-LINUX-NEXT:    xorl %eax, %eax
144; X64-LINUX-NEXT:    retq
145;
146; X64-WIN32-LABEL: test5:
147; X64-WIN32:       # %bb.0: # %entry
148; X64-WIN32-NEXT:    addl %edx, %ecx
149; X64-WIN32-NEXT:    jb .LBB4_2
150; X64-WIN32-NEXT:  # %bb.1: # %normal
151; X64-WIN32-NEXT:    movl $0, (%r8)
152; X64-WIN32-NEXT:  .LBB4_2: # %carry
153; X64-WIN32-NEXT:    xorl %eax, %eax
154; X64-WIN32-NEXT:    retq
155entry:
156  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
157  %sum = extractvalue {i32, i1} %t, 0
158  %obit = extractvalue {i32, i1} %t, 1
159  br i1 %obit, label %carry, label %normal
160
161normal:
162  store i32 0, i32* %X
163  br label %carry
164
165carry:
166  ret i1 false
167}
168
169define i64 @test6(i64 %A, i32 %B) nounwind {
170; X32-LABEL: test6:
171; X32:       # %bb.0: # %entry
172; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
173; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
174; X32-NEXT:    addl {{[0-9]+}}(%esp), %edx
175; X32-NEXT:    retl
176;
177; X64-LINUX-LABEL: test6:
178; X64-LINUX:       # %bb.0: # %entry
179; X64-LINUX-NEXT:    # kill: def $esi killed $esi def $rsi
180; X64-LINUX-NEXT:    shlq $32, %rsi
181; X64-LINUX-NEXT:    leaq (%rsi,%rdi), %rax
182; X64-LINUX-NEXT:    retq
183;
184; X64-WIN32-LABEL: test6:
185; X64-WIN32:       # %bb.0: # %entry
186; X64-WIN32-NEXT:    # kill: def $edx killed $edx def $rdx
187; X64-WIN32-NEXT:    shlq $32, %rdx
188; X64-WIN32-NEXT:    leaq (%rdx,%rcx), %rax
189; X64-WIN32-NEXT:    retq
190entry:
191  %tmp12 = zext i32 %B to i64
192  %tmp3 = shl i64 %tmp12, 32
193  %tmp5 = add i64 %tmp3, %A
194  ret i64 %tmp5
195}
196
197define {i32, i1} @test7(i32 %v1, i32 %v2) nounwind {
198; X32-LABEL: test7:
199; X32:       # %bb.0: # %entry
200; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
201; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
202; X32-NEXT:    setb %dl
203; X32-NEXT:    retl
204;
205; X64-LINUX-LABEL: test7:
206; X64-LINUX:       # %bb.0: # %entry
207; X64-LINUX-NEXT:    addl %esi, %edi
208; X64-LINUX-NEXT:    setb %dl
209; X64-LINUX-NEXT:    movl %edi, %eax
210; X64-LINUX-NEXT:    retq
211;
212; X64-WIN32-LABEL: test7:
213; X64-WIN32:       # %bb.0: # %entry
214; X64-WIN32-NEXT:    addl %edx, %ecx
215; X64-WIN32-NEXT:    setb %dl
216; X64-WIN32-NEXT:    movl %ecx, %eax
217; X64-WIN32-NEXT:    retq
218entry:
219  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
220  ret {i32, i1} %t
221}
222
223; PR5443
224define {i64, i1} @test8(i64 %left, i64 %right) nounwind {
225; X32-LABEL: test8:
226; X32:       # %bb.0: # %entry
227; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
228; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
229; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
230; X32-NEXT:    adcl {{[0-9]+}}(%esp), %edx
231; X32-NEXT:    setb %cl
232; X32-NEXT:    retl
233;
234; X64-LINUX-LABEL: test8:
235; X64-LINUX:       # %bb.0: # %entry
236; X64-LINUX-NEXT:    addq %rsi, %rdi
237; X64-LINUX-NEXT:    setb %dl
238; X64-LINUX-NEXT:    movq %rdi, %rax
239; X64-LINUX-NEXT:    retq
240;
241; X64-WIN32-LABEL: test8:
242; X64-WIN32:       # %bb.0: # %entry
243; X64-WIN32-NEXT:    addq %rdx, %rcx
244; X64-WIN32-NEXT:    setb %dl
245; X64-WIN32-NEXT:    movq %rcx, %rax
246; X64-WIN32-NEXT:    retq
247entry:
248  %extleft = zext i64 %left to i65
249  %extright = zext i64 %right to i65
250  %sum = add i65 %extleft, %extright
251  %res.0 = trunc i65 %sum to i64
252  %overflow = and i65 %sum, -18446744073709551616
253  %res.1 = icmp ne i65 %overflow, 0
254  %final0 = insertvalue {i64, i1} undef, i64 %res.0, 0
255  %final1 = insertvalue {i64, i1} %final0, i1 %res.1, 1
256  ret {i64, i1} %final1
257}
258
259define i32 @test9(i32 %x, i32 %y) nounwind readnone {
260; X32-LABEL: test9:
261; X32:       # %bb.0: # %entry
262; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
263; X32-NEXT:    xorl %ecx, %ecx
264; X32-NEXT:    cmpl $10, {{[0-9]+}}(%esp)
265; X32-NEXT:    sete %cl
266; X32-NEXT:    subl %ecx, %eax
267; X32-NEXT:    retl
268;
269; X64-LINUX-LABEL: test9:
270; X64-LINUX:       # %bb.0: # %entry
271; X64-LINUX-NEXT:    xorl %eax, %eax
272; X64-LINUX-NEXT:    cmpl $10, %edi
273; X64-LINUX-NEXT:    sete %al
274; X64-LINUX-NEXT:    subl %eax, %esi
275; X64-LINUX-NEXT:    movl %esi, %eax
276; X64-LINUX-NEXT:    retq
277;
278; X64-WIN32-LABEL: test9:
279; X64-WIN32:       # %bb.0: # %entry
280; X64-WIN32-NEXT:    xorl %eax, %eax
281; X64-WIN32-NEXT:    cmpl $10, %ecx
282; X64-WIN32-NEXT:    sete %al
283; X64-WIN32-NEXT:    subl %eax, %edx
284; X64-WIN32-NEXT:    movl %edx, %eax
285; X64-WIN32-NEXT:    retq
286entry:
287  %cmp = icmp eq i32 %x, 10
288  %sub = sext i1 %cmp to i32
289  %cond = add i32 %sub, %y
290  ret i32 %cond
291}
292
293define i1 @test10(i32 %x) nounwind {
294; X32-LABEL: test10:
295; X32:       # %bb.0: # %entry
296; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
297; X32-NEXT:    incl %eax
298; X32-NEXT:    seto %al
299; X32-NEXT:    retl
300;
301; X64-LINUX-LABEL: test10:
302; X64-LINUX:       # %bb.0: # %entry
303; X64-LINUX-NEXT:    incl %edi
304; X64-LINUX-NEXT:    seto %al
305; X64-LINUX-NEXT:    retq
306;
307; X64-WIN32-LABEL: test10:
308; X64-WIN32:       # %bb.0: # %entry
309; X64-WIN32-NEXT:    incl %ecx
310; X64-WIN32-NEXT:    seto %al
311; X64-WIN32-NEXT:    retq
312entry:
313  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
314  %obit = extractvalue {i32, i1} %t, 1
315  ret i1 %obit
316}
317
318define void @test11(i32* inreg %a) nounwind {
319; X32-LABEL: test11:
320; X32:       # %bb.0: # %entry
321; X32-NEXT:    subl $-128, (%eax)
322; X32-NEXT:    retl
323;
324; X64-LINUX-LABEL: test11:
325; X64-LINUX:       # %bb.0: # %entry
326; X64-LINUX-NEXT:    subl $-128, (%rdi)
327; X64-LINUX-NEXT:    retq
328;
329; X64-WIN32-LABEL: test11:
330; X64-WIN32:       # %bb.0: # %entry
331; X64-WIN32-NEXT:    subl $-128, (%rcx)
332; X64-WIN32-NEXT:    retq
333entry:
334  %aa = load i32, i32* %a
335  %b = add i32 %aa, 128
336  store i32 %b, i32* %a
337  ret void
338}
339
340define void @test12(i64* inreg %a) nounwind {
341; X32-LABEL: test12:
342; X32:       # %bb.0: # %entry
343; X32-NEXT:    addl $-2147483648, (%eax) # imm = 0x80000000
344; X32-NEXT:    adcl $0, 4(%eax)
345; X32-NEXT:    retl
346;
347; X64-LINUX-LABEL: test12:
348; X64-LINUX:       # %bb.0: # %entry
349; X64-LINUX-NEXT:    subq $-2147483648, (%rdi) # imm = 0x80000000
350; X64-LINUX-NEXT:    retq
351;
352; X64-WIN32-LABEL: test12:
353; X64-WIN32:       # %bb.0: # %entry
354; X64-WIN32-NEXT:    subq $-2147483648, (%rcx) # imm = 0x80000000
355; X64-WIN32-NEXT:    retq
356entry:
357  %aa = load i64, i64* %a
358  %b = add i64 %aa, 2147483648
359  store i64 %b, i64* %a
360  ret void
361}
362
363define void @test13(i64* inreg %a) nounwind {
364; X32-LABEL: test13:
365; X32:       # %bb.0: # %entry
366; X32-NEXT:    addl $128, (%eax)
367; X32-NEXT:    adcl $0, 4(%eax)
368; X32-NEXT:    retl
369;
370; X64-LINUX-LABEL: test13:
371; X64-LINUX:       # %bb.0: # %entry
372; X64-LINUX-NEXT:    subq $-128, (%rdi)
373; X64-LINUX-NEXT:    retq
374;
375; X64-WIN32-LABEL: test13:
376; X64-WIN32:       # %bb.0: # %entry
377; X64-WIN32-NEXT:    subq $-128, (%rcx)
378; X64-WIN32-NEXT:    retq
379entry:
380  %aa = load i64, i64* %a
381  %b = add i64 %aa, 128
382  store i64 %b, i64* %a
383  ret void
384}
385
386define i32 @inc_not(i32 %a) {
387; X32-LABEL: inc_not:
388; X32:       # %bb.0:
389; X32-NEXT:    xorl %eax, %eax
390; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
391; X32-NEXT:    retl
392;
393; X64-LINUX-LABEL: inc_not:
394; X64-LINUX:       # %bb.0:
395; X64-LINUX-NEXT:    negl %edi
396; X64-LINUX-NEXT:    movl %edi, %eax
397; X64-LINUX-NEXT:    retq
398;
399; X64-WIN32-LABEL: inc_not:
400; X64-WIN32:       # %bb.0:
401; X64-WIN32-NEXT:    negl %ecx
402; X64-WIN32-NEXT:    movl %ecx, %eax
403; X64-WIN32-NEXT:    retq
404  %nota = xor i32 %a, -1
405  %r = add i32 %nota, 1
406  ret i32 %r
407}
408
409define void @uaddo1_not(i32 %a, i32* %p0, i1* %p1) {
410; X32-LABEL: uaddo1_not:
411; X32:       # %bb.0:
412; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
413; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
414; X32-NEXT:    xorl %edx, %edx
415; X32-NEXT:    subl {{[0-9]+}}(%esp), %edx
416; X32-NEXT:    movl %edx, (%ecx)
417; X32-NEXT:    setae (%eax)
418; X32-NEXT:    retl
419;
420; X64-LINUX-LABEL: uaddo1_not:
421; X64-LINUX:       # %bb.0:
422; X64-LINUX-NEXT:    negl %edi
423; X64-LINUX-NEXT:    movl %edi, (%rsi)
424; X64-LINUX-NEXT:    setae (%rdx)
425; X64-LINUX-NEXT:    retq
426;
427; X64-WIN32-LABEL: uaddo1_not:
428; X64-WIN32:       # %bb.0:
429; X64-WIN32-NEXT:    negl %ecx
430; X64-WIN32-NEXT:    movl %ecx, (%rdx)
431; X64-WIN32-NEXT:    setae (%r8)
432; X64-WIN32-NEXT:    retq
433  %nota = xor i32 %a, -1
434  %uaddo = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %nota, i32 1)
435  %r0 = extractvalue {i32, i1} %uaddo, 0
436  %r1 = extractvalue {i32, i1} %uaddo, 1
437  store i32 %r0, i32* %p0
438  store i1 %r1, i1* %p1
439  ret void
440}
441