[Reland][Runtimes] Merge 'compile_commands.json' files from runtimes build (#116303)
[llvm-project.git] / llvm / test / CodeGen / X86 / add.ll
blob079294ef09bdbbd0eabb9fd8e1360a67d082e2e0
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86
3 ; RUN: llc < %s -mtriple=x86_64-linux -verify-machineinstrs | FileCheck %s --check-prefix=X64-LINUX
4 ; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s --check-prefix=X64-WIN32
6 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32)
7 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)
9 ; The immediate can be encoded in a smaller way if the
10 ; instruction is a sub instead of an add.
11 define i32 @test1(i32 inreg %a) nounwind {
12 ; X86-LABEL: test1:
13 ; X86:       # %bb.0: # %entry
14 ; X86-NEXT:    subl $-128, %eax
15 ; X86-NEXT:    retl
17 ; X64-LINUX-LABEL: test1:
18 ; X64-LINUX:       # %bb.0: # %entry
19 ; X64-LINUX-NEXT:    # kill: def $edi killed $edi def $rdi
20 ; X64-LINUX-NEXT:    leal 128(%rdi), %eax
21 ; X64-LINUX-NEXT:    retq
23 ; X64-WIN32-LABEL: test1:
24 ; X64-WIN32:       # %bb.0: # %entry
25 ; X64-WIN32-NEXT:    # kill: def $ecx killed $ecx def $rcx
26 ; X64-WIN32-NEXT:    leal 128(%rcx), %eax
27 ; X64-WIN32-NEXT:    retq
28 entry:
29   %b = add i32 %a, 128
30   ret i32 %b
33 define i32 @test1b(ptr %p) nounwind {
34 ; X86-LABEL: test1b:
35 ; X86:       # %bb.0: # %entry
36 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
37 ; X86-NEXT:    movl (%eax), %eax
38 ; X86-NEXT:    subl $-128, %eax
39 ; X86-NEXT:    retl
41 ; X64-LINUX-LABEL: test1b:
42 ; X64-LINUX:       # %bb.0: # %entry
43 ; X64-LINUX-NEXT:    movl (%rdi), %eax
44 ; X64-LINUX-NEXT:    subl $-128, %eax
45 ; X64-LINUX-NEXT:    retq
47 ; X64-WIN32-LABEL: test1b:
48 ; X64-WIN32:       # %bb.0: # %entry
49 ; X64-WIN32-NEXT:    movl (%rcx), %eax
50 ; X64-WIN32-NEXT:    subl $-128, %eax
51 ; X64-WIN32-NEXT:    retq
52 entry:
53   %a = load i32, ptr %p
54   %b = add i32 %a, 128
55   ret i32 %b
58 define i64 @test2(i64 inreg %a) nounwind {
59 ; X86-LABEL: test2:
60 ; X86:       # %bb.0: # %entry
61 ; X86-NEXT:    addl $-2147483648, %eax # imm = 0x80000000
62 ; X86-NEXT:    adcl $0, %edx
63 ; X86-NEXT:    retl
65 ; X64-LINUX-LABEL: test2:
66 ; X64-LINUX:       # %bb.0: # %entry
67 ; X64-LINUX-NEXT:    movq %rdi, %rax
68 ; X64-LINUX-NEXT:    subq $-2147483648, %rax # imm = 0x80000000
69 ; X64-LINUX-NEXT:    retq
71 ; X64-WIN32-LABEL: test2:
72 ; X64-WIN32:       # %bb.0: # %entry
73 ; X64-WIN32-NEXT:    movq %rcx, %rax
74 ; X64-WIN32-NEXT:    subq $-2147483648, %rax # imm = 0x80000000
75 ; X64-WIN32-NEXT:    retq
76 entry:
77   %b = add i64 %a, 2147483648
78   ret i64 %b
80 define i64 @test3(i64 inreg %a) nounwind {
81 ; X86-LABEL: test3:
82 ; X86:       # %bb.0: # %entry
83 ; X86-NEXT:    addl $128, %eax
84 ; X86-NEXT:    adcl $0, %edx
85 ; X86-NEXT:    retl
87 ; X64-LINUX-LABEL: test3:
88 ; X64-LINUX:       # %bb.0: # %entry
89 ; X64-LINUX-NEXT:    leaq 128(%rdi), %rax
90 ; X64-LINUX-NEXT:    retq
92 ; X64-WIN32-LABEL: test3:
93 ; X64-WIN32:       # %bb.0: # %entry
94 ; X64-WIN32-NEXT:    leaq 128(%rcx), %rax
95 ; X64-WIN32-NEXT:    retq
96 entry:
97   %b = add i64 %a, 128
98   ret i64 %b
101 define i64 @test3b(ptr %p) nounwind {
102 ; X86-LABEL: test3b:
103 ; X86:       # %bb.0: # %entry
104 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
105 ; X86-NEXT:    movl 4(%ecx), %edx
106 ; X86-NEXT:    movl $128, %eax
107 ; X86-NEXT:    addl (%ecx), %eax
108 ; X86-NEXT:    adcl $0, %edx
109 ; X86-NEXT:    retl
111 ; X64-LINUX-LABEL: test3b:
112 ; X64-LINUX:       # %bb.0: # %entry
113 ; X64-LINUX-NEXT:    movq (%rdi), %rax
114 ; X64-LINUX-NEXT:    subq $-128, %rax
115 ; X64-LINUX-NEXT:    retq
117 ; X64-WIN32-LABEL: test3b:
118 ; X64-WIN32:       # %bb.0: # %entry
119 ; X64-WIN32-NEXT:    movq (%rcx), %rax
120 ; X64-WIN32-NEXT:    subq $-128, %rax
121 ; X64-WIN32-NEXT:    retq
122 entry:
123   %a = load i64, ptr %p
124   %b = add i64 %a, 128
125   ret i64 %b
128 define i1 @test4(i32 %v1, i32 %v2, ptr %X) nounwind {
129 ; X86-LABEL: test4:
130 ; X86:       # %bb.0: # %entry
131 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
132 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
133 ; X86-NEXT:    jo .LBB5_2
134 ; X86-NEXT:  # %bb.1: # %normal
135 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
136 ; X86-NEXT:    movl $0, (%eax)
137 ; X86-NEXT:  .LBB5_2: # %overflow
138 ; X86-NEXT:    xorl %eax, %eax
139 ; X86-NEXT:    retl
141 ; X64-LINUX-LABEL: test4:
142 ; X64-LINUX:       # %bb.0: # %entry
143 ; X64-LINUX-NEXT:    addl %esi, %edi
144 ; X64-LINUX-NEXT:    jo .LBB5_2
145 ; X64-LINUX-NEXT:  # %bb.1: # %normal
146 ; X64-LINUX-NEXT:    movl $0, (%rdx)
147 ; X64-LINUX-NEXT:  .LBB5_2: # %overflow
148 ; X64-LINUX-NEXT:    xorl %eax, %eax
149 ; X64-LINUX-NEXT:    retq
151 ; X64-WIN32-LABEL: test4:
152 ; X64-WIN32:       # %bb.0: # %entry
153 ; X64-WIN32-NEXT:    addl %edx, %ecx
154 ; X64-WIN32-NEXT:    jo .LBB5_2
155 ; X64-WIN32-NEXT:  # %bb.1: # %normal
156 ; X64-WIN32-NEXT:    movl $0, (%r8)
157 ; X64-WIN32-NEXT:  .LBB5_2: # %overflow
158 ; X64-WIN32-NEXT:    xorl %eax, %eax
159 ; X64-WIN32-NEXT:    retq
160 entry:
161   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
162   %sum = extractvalue {i32, i1} %t, 0
163   %obit = extractvalue {i32, i1} %t, 1
164   br i1 %obit, label %overflow, label %normal
166 normal:
167   store i32 0, ptr %X
168   br label %overflow
170 overflow:
171   ret i1 false
174 define i1 @test5(i32 %v1, i32 %v2, ptr %X) nounwind {
175 ; X86-LABEL: test5:
176 ; X86:       # %bb.0: # %entry
177 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
178 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
179 ; X86-NEXT:    jb .LBB6_2
180 ; X86-NEXT:  # %bb.1: # %normal
181 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
182 ; X86-NEXT:    movl $0, (%eax)
183 ; X86-NEXT:  .LBB6_2: # %carry
184 ; X86-NEXT:    xorl %eax, %eax
185 ; X86-NEXT:    retl
187 ; X64-LINUX-LABEL: test5:
188 ; X64-LINUX:       # %bb.0: # %entry
189 ; X64-LINUX-NEXT:    addl %esi, %edi
190 ; X64-LINUX-NEXT:    jb .LBB6_2
191 ; X64-LINUX-NEXT:  # %bb.1: # %normal
192 ; X64-LINUX-NEXT:    movl $0, (%rdx)
193 ; X64-LINUX-NEXT:  .LBB6_2: # %carry
194 ; X64-LINUX-NEXT:    xorl %eax, %eax
195 ; X64-LINUX-NEXT:    retq
197 ; X64-WIN32-LABEL: test5:
198 ; X64-WIN32:       # %bb.0: # %entry
199 ; X64-WIN32-NEXT:    addl %edx, %ecx
200 ; X64-WIN32-NEXT:    jb .LBB6_2
201 ; X64-WIN32-NEXT:  # %bb.1: # %normal
202 ; X64-WIN32-NEXT:    movl $0, (%r8)
203 ; X64-WIN32-NEXT:  .LBB6_2: # %carry
204 ; X64-WIN32-NEXT:    xorl %eax, %eax
205 ; X64-WIN32-NEXT:    retq
206 entry:
207   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
208   %sum = extractvalue {i32, i1} %t, 0
209   %obit = extractvalue {i32, i1} %t, 1
210   br i1 %obit, label %carry, label %normal
212 normal:
213   store i32 0, ptr %X
214   br label %carry
216 carry:
217   ret i1 false
220 define i64 @test6(i64 %A, i32 %B) nounwind {
221 ; X86-LABEL: test6:
222 ; X86:       # %bb.0: # %entry
223 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
224 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
225 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %edx
226 ; X86-NEXT:    retl
228 ; X64-LINUX-LABEL: test6:
229 ; X64-LINUX:       # %bb.0: # %entry
230 ; X64-LINUX-NEXT:    # kill: def $esi killed $esi def $rsi
231 ; X64-LINUX-NEXT:    shlq $32, %rsi
232 ; X64-LINUX-NEXT:    leaq (%rsi,%rdi), %rax
233 ; X64-LINUX-NEXT:    retq
235 ; X64-WIN32-LABEL: test6:
236 ; X64-WIN32:       # %bb.0: # %entry
237 ; X64-WIN32-NEXT:    # kill: def $edx killed $edx def $rdx
238 ; X64-WIN32-NEXT:    shlq $32, %rdx
239 ; X64-WIN32-NEXT:    leaq (%rdx,%rcx), %rax
240 ; X64-WIN32-NEXT:    retq
241 entry:
242   %tmp12 = zext i32 %B to i64
243   %tmp3 = shl i64 %tmp12, 32
244   %tmp5 = add i64 %tmp3, %A
245   ret i64 %tmp5
248 define {i32, i1} @test7(i32 %v1, i32 %v2) nounwind {
249 ; X86-LABEL: test7:
250 ; X86:       # %bb.0: # %entry
251 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
252 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
253 ; X86-NEXT:    setb %dl
254 ; X86-NEXT:    retl
256 ; X64-LINUX-LABEL: test7:
257 ; X64-LINUX:       # %bb.0: # %entry
258 ; X64-LINUX-NEXT:    movl %edi, %eax
259 ; X64-LINUX-NEXT:    addl %esi, %eax
260 ; X64-LINUX-NEXT:    setb %dl
261 ; X64-LINUX-NEXT:    retq
263 ; X64-WIN32-LABEL: test7:
264 ; X64-WIN32:       # %bb.0: # %entry
265 ; X64-WIN32-NEXT:    movl %ecx, %eax
266 ; X64-WIN32-NEXT:    addl %edx, %eax
267 ; X64-WIN32-NEXT:    setb %dl
268 ; X64-WIN32-NEXT:    retq
269 entry:
270   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
271   ret {i32, i1} %t
274 ; PR5443
275 define {i64, i1} @test8(i64 %left, i64 %right) nounwind {
276 ; X86-LABEL: test8:
277 ; X86:       # %bb.0: # %entry
278 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
279 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
280 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
281 ; X86-NEXT:    adcl {{[0-9]+}}(%esp), %edx
282 ; X86-NEXT:    setb %cl
283 ; X86-NEXT:    retl
285 ; X64-LINUX-LABEL: test8:
286 ; X64-LINUX:       # %bb.0: # %entry
287 ; X64-LINUX-NEXT:    movq %rdi, %rax
288 ; X64-LINUX-NEXT:    addq %rsi, %rax
289 ; X64-LINUX-NEXT:    setb %dl
290 ; X64-LINUX-NEXT:    retq
292 ; X64-WIN32-LABEL: test8:
293 ; X64-WIN32:       # %bb.0: # %entry
294 ; X64-WIN32-NEXT:    movq %rcx, %rax
295 ; X64-WIN32-NEXT:    addq %rdx, %rax
296 ; X64-WIN32-NEXT:    setb %dl
297 ; X64-WIN32-NEXT:    retq
298 entry:
299   %extleft = zext i64 %left to i65
300   %extright = zext i64 %right to i65
301   %sum = add i65 %extleft, %extright
302   %res.0 = trunc i65 %sum to i64
303   %overflow = and i65 %sum, -18446744073709551616
304   %res.1 = icmp ne i65 %overflow, 0
305   %final0 = insertvalue {i64, i1} undef, i64 %res.0, 0
306   %final1 = insertvalue {i64, i1} %final0, i1 %res.1, 1
307   ret {i64, i1} %final1
310 define i32 @test9(i32 %x, i32 %y) nounwind readnone {
311 ; X86-LABEL: test9:
312 ; X86:       # %bb.0: # %entry
313 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
314 ; X86-NEXT:    xorl %ecx, %ecx
315 ; X86-NEXT:    cmpl $10, {{[0-9]+}}(%esp)
316 ; X86-NEXT:    sete %cl
317 ; X86-NEXT:    subl %ecx, %eax
318 ; X86-NEXT:    retl
320 ; X64-LINUX-LABEL: test9:
321 ; X64-LINUX:       # %bb.0: # %entry
322 ; X64-LINUX-NEXT:    movl %esi, %eax
323 ; X64-LINUX-NEXT:    xorl %ecx, %ecx
324 ; X64-LINUX-NEXT:    cmpl $10, %edi
325 ; X64-LINUX-NEXT:    sete %cl
326 ; X64-LINUX-NEXT:    subl %ecx, %eax
327 ; X64-LINUX-NEXT:    retq
329 ; X64-WIN32-LABEL: test9:
330 ; X64-WIN32:       # %bb.0: # %entry
331 ; X64-WIN32-NEXT:    movl %edx, %eax
332 ; X64-WIN32-NEXT:    xorl %edx, %edx
333 ; X64-WIN32-NEXT:    cmpl $10, %ecx
334 ; X64-WIN32-NEXT:    sete %dl
335 ; X64-WIN32-NEXT:    subl %edx, %eax
336 ; X64-WIN32-NEXT:    retq
337 entry:
338   %cmp = icmp eq i32 %x, 10
339   %sub = sext i1 %cmp to i32
340   %cond = add i32 %sub, %y
341   ret i32 %cond
344 define i1 @test10(i32 %x) nounwind {
345 ; X86-LABEL: test10:
346 ; X86:       # %bb.0: # %entry
347 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
348 ; X86-NEXT:    incl %eax
349 ; X86-NEXT:    seto %al
350 ; X86-NEXT:    retl
352 ; X64-LINUX-LABEL: test10:
353 ; X64-LINUX:       # %bb.0: # %entry
354 ; X64-LINUX-NEXT:    incl %edi
355 ; X64-LINUX-NEXT:    seto %al
356 ; X64-LINUX-NEXT:    retq
358 ; X64-WIN32-LABEL: test10:
359 ; X64-WIN32:       # %bb.0: # %entry
360 ; X64-WIN32-NEXT:    incl %ecx
361 ; X64-WIN32-NEXT:    seto %al
362 ; X64-WIN32-NEXT:    retq
363 entry:
364   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
365   %obit = extractvalue {i32, i1} %t, 1
366   ret i1 %obit
369 define void @test11(ptr inreg %a) nounwind {
370 ; X86-LABEL: test11:
371 ; X86:       # %bb.0: # %entry
372 ; X86-NEXT:    subl $-128, (%eax)
373 ; X86-NEXT:    retl
375 ; X64-LINUX-LABEL: test11:
376 ; X64-LINUX:       # %bb.0: # %entry
377 ; X64-LINUX-NEXT:    subl $-128, (%rdi)
378 ; X64-LINUX-NEXT:    retq
380 ; X64-WIN32-LABEL: test11:
381 ; X64-WIN32:       # %bb.0: # %entry
382 ; X64-WIN32-NEXT:    subl $-128, (%rcx)
383 ; X64-WIN32-NEXT:    retq
384 entry:
385   %aa = load i32, ptr %a
386   %b = add i32 %aa, 128
387   store i32 %b, ptr %a
388   ret void
391 define void @test12(ptr inreg %a) nounwind {
392 ; X86-LABEL: test12:
393 ; X86:       # %bb.0: # %entry
394 ; X86-NEXT:    addl $-2147483648, (%eax) # imm = 0x80000000
395 ; X86-NEXT:    adcl $0, 4(%eax)
396 ; X86-NEXT:    retl
398 ; X64-LINUX-LABEL: test12:
399 ; X64-LINUX:       # %bb.0: # %entry
400 ; X64-LINUX-NEXT:    subq $-2147483648, (%rdi) # imm = 0x80000000
401 ; X64-LINUX-NEXT:    retq
403 ; X64-WIN32-LABEL: test12:
404 ; X64-WIN32:       # %bb.0: # %entry
405 ; X64-WIN32-NEXT:    subq $-2147483648, (%rcx) # imm = 0x80000000
406 ; X64-WIN32-NEXT:    retq
407 entry:
408   %aa = load i64, ptr %a
409   %b = add i64 %aa, 2147483648
410   store i64 %b, ptr %a
411   ret void
414 define void @test13(ptr inreg %a) nounwind {
415 ; X86-LABEL: test13:
416 ; X86:       # %bb.0: # %entry
417 ; X86-NEXT:    addl $128, (%eax)
418 ; X86-NEXT:    adcl $0, 4(%eax)
419 ; X86-NEXT:    retl
421 ; X64-LINUX-LABEL: test13:
422 ; X64-LINUX:       # %bb.0: # %entry
423 ; X64-LINUX-NEXT:    subq $-128, (%rdi)
424 ; X64-LINUX-NEXT:    retq
426 ; X64-WIN32-LABEL: test13:
427 ; X64-WIN32:       # %bb.0: # %entry
428 ; X64-WIN32-NEXT:    subq $-128, (%rcx)
429 ; X64-WIN32-NEXT:    retq
430 entry:
431   %aa = load i64, ptr %a
432   %b = add i64 %aa, 128
433   store i64 %b, ptr %a
434   ret void
437 define i32 @inc_not(i32 %a) {
438 ; X86-LABEL: inc_not:
439 ; X86:       # %bb.0:
440 ; X86-NEXT:    xorl %eax, %eax
441 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
442 ; X86-NEXT:    retl
444 ; X64-LINUX-LABEL: inc_not:
445 ; X64-LINUX:       # %bb.0:
446 ; X64-LINUX-NEXT:    movl %edi, %eax
447 ; X64-LINUX-NEXT:    negl %eax
448 ; X64-LINUX-NEXT:    retq
450 ; X64-WIN32-LABEL: inc_not:
451 ; X64-WIN32:       # %bb.0:
452 ; X64-WIN32-NEXT:    movl %ecx, %eax
453 ; X64-WIN32-NEXT:    negl %eax
454 ; X64-WIN32-NEXT:    retq
455   %nota = xor i32 %a, -1
456   %r = add i32 %nota, 1
457   ret i32 %r
460 define <4 x i32> @inc_not_vec(<4 x i32> %a) nounwind {
461 ; X86-LABEL: inc_not_vec:
462 ; X86:       # %bb.0:
463 ; X86-NEXT:    pushl %edi
464 ; X86-NEXT:    pushl %esi
465 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
466 ; X86-NEXT:    xorl %ecx, %ecx
467 ; X86-NEXT:    xorl %edx, %edx
468 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
469 ; X86-NEXT:    xorl %esi, %esi
470 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %esi
471 ; X86-NEXT:    xorl %edi, %edi
472 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edi
473 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %ecx
474 ; X86-NEXT:    movl %ecx, 12(%eax)
475 ; X86-NEXT:    movl %edi, 8(%eax)
476 ; X86-NEXT:    movl %esi, 4(%eax)
477 ; X86-NEXT:    movl %edx, (%eax)
478 ; X86-NEXT:    popl %esi
479 ; X86-NEXT:    popl %edi
480 ; X86-NEXT:    retl $4
482 ; X64-LINUX-LABEL: inc_not_vec:
483 ; X64-LINUX:       # %bb.0:
484 ; X64-LINUX-NEXT:    pxor %xmm1, %xmm1
485 ; X64-LINUX-NEXT:    psubd %xmm0, %xmm1
486 ; X64-LINUX-NEXT:    movdqa %xmm1, %xmm0
487 ; X64-LINUX-NEXT:    retq
489 ; X64-WIN32-LABEL: inc_not_vec:
490 ; X64-WIN32:       # %bb.0:
491 ; X64-WIN32-NEXT:    pxor %xmm0, %xmm0
492 ; X64-WIN32-NEXT:    psubd (%rcx), %xmm0
493 ; X64-WIN32-NEXT:    retq
494   %nota = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
495   %r = add <4 x i32> %nota, <i32 1, i32 1, i32 1, i32 1>
496   ret <4 x i32> %r
499 define void @uaddo1_not(i32 %a, ptr %p0, ptr %p1) {
500 ; X86-LABEL: uaddo1_not:
501 ; X86:       # %bb.0:
502 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
503 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
504 ; X86-NEXT:    xorl %edx, %edx
505 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
506 ; X86-NEXT:    movl %edx, (%ecx)
507 ; X86-NEXT:    setae (%eax)
508 ; X86-NEXT:    retl
510 ; X64-LINUX-LABEL: uaddo1_not:
511 ; X64-LINUX:       # %bb.0:
512 ; X64-LINUX-NEXT:    negl %edi
513 ; X64-LINUX-NEXT:    movl %edi, (%rsi)
514 ; X64-LINUX-NEXT:    setae (%rdx)
515 ; X64-LINUX-NEXT:    retq
517 ; X64-WIN32-LABEL: uaddo1_not:
518 ; X64-WIN32:       # %bb.0:
519 ; X64-WIN32-NEXT:    negl %ecx
520 ; X64-WIN32-NEXT:    movl %ecx, (%rdx)
521 ; X64-WIN32-NEXT:    setae (%r8)
522 ; X64-WIN32-NEXT:    retq
523   %nota = xor i32 %a, -1
524   %uaddo = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %nota, i32 1)
525   %r0 = extractvalue {i32, i1} %uaddo, 0
526   %r1 = extractvalue {i32, i1} %uaddo, 1
527   store i32 %r0, ptr %p0
528   store i1 %r1, ptr %p1
529   ret void
532 define i32 @add_to_sub(i32 %a, i32 %b) {
533 ; X86-LABEL: add_to_sub:
534 ; X86:       # %bb.0:
535 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
536 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
537 ; X86-NEXT:    retl
539 ; X64-LINUX-LABEL: add_to_sub:
540 ; X64-LINUX:       # %bb.0:
541 ; X64-LINUX-NEXT:    movl %esi, %eax
542 ; X64-LINUX-NEXT:    subl %edi, %eax
543 ; X64-LINUX-NEXT:    retq
545 ; X64-WIN32-LABEL: add_to_sub:
546 ; X64-WIN32:       # %bb.0:
547 ; X64-WIN32-NEXT:    movl %edx, %eax
548 ; X64-WIN32-NEXT:    subl %ecx, %eax
549 ; X64-WIN32-NEXT:    retq
550   %nota = xor i32 %a, -1
551   %add = add i32 %nota, %b
552   %r = add i32 %add, 1
553   ret i32 %r
556 declare dso_local void @bar_i32(i32)
557 declare dso_local void @bar_i64(i64)
559 ; Make sure we can use sub -128 for add 128 when the flags are used.
560 define void @add_i32_128_flag(i32 %x) {
561 ; X86-LABEL: add_i32_128_flag:
562 ; X86:       # %bb.0: # %entry
563 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
564 ; X86-NEXT:    subl $-128, %eax
565 ; X86-NEXT:    je .LBB19_2
566 ; X86-NEXT:  # %bb.1: # %if.then
567 ; X86-NEXT:    pushl %eax
568 ; X86-NEXT:    .cfi_adjust_cfa_offset 4
569 ; X86-NEXT:    calll bar_i32
570 ; X86-NEXT:    addl $4, %esp
571 ; X86-NEXT:    .cfi_adjust_cfa_offset -4
572 ; X86-NEXT:  .LBB19_2: # %if.end
573 ; X86-NEXT:    retl
575 ; X64-LINUX-LABEL: add_i32_128_flag:
576 ; X64-LINUX:       # %bb.0: # %entry
577 ; X64-LINUX-NEXT:    subl $-128, %edi
578 ; X64-LINUX-NEXT:    jne bar_i32 # TAILCALL
579 ; X64-LINUX-NEXT:  # %bb.1: # %if.end
580 ; X64-LINUX-NEXT:    retq
582 ; X64-WIN32-LABEL: add_i32_128_flag:
583 ; X64-WIN32:       # %bb.0: # %entry
584 ; X64-WIN32-NEXT:    subl $-128, %ecx
585 ; X64-WIN32-NEXT:    jne bar_i32 # TAILCALL
586 ; X64-WIN32-NEXT:  # %bb.1: # %if.end
587 ; X64-WIN32-NEXT:    retq
588 entry:
589   %add = add i32 %x, 128
590   %tobool = icmp eq i32 %add, 0
591   br i1 %tobool, label %if.end, label %if.then
593 if.then:
594   tail call void @bar_i32(i32 %add)
595   br label %if.end
597 if.end:
598   ret void
601 ; Make sure we can use sub -128 for add 128 when the flags are used.
602 define void @add_i64_128_flag(i64 %x) {
603 ; X86-LABEL: add_i64_128_flag:
604 ; X86:       # %bb.0: # %entry
605 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
606 ; X86-NEXT:    movl $128, %eax
607 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
608 ; X86-NEXT:    adcl $0, %ecx
609 ; X86-NEXT:    movl %eax, %edx
610 ; X86-NEXT:    orl %ecx, %edx
611 ; X86-NEXT:    je .LBB20_2
612 ; X86-NEXT:  # %bb.1: # %if.then
613 ; X86-NEXT:    pushl %ecx
614 ; X86-NEXT:    .cfi_adjust_cfa_offset 4
615 ; X86-NEXT:    pushl %eax
616 ; X86-NEXT:    .cfi_adjust_cfa_offset 4
617 ; X86-NEXT:    calll bar_i64
618 ; X86-NEXT:    addl $8, %esp
619 ; X86-NEXT:    .cfi_adjust_cfa_offset -8
620 ; X86-NEXT:  .LBB20_2: # %if.end
621 ; X86-NEXT:    retl
623 ; X64-LINUX-LABEL: add_i64_128_flag:
624 ; X64-LINUX:       # %bb.0: # %entry
625 ; X64-LINUX-NEXT:    subq $-128, %rdi
626 ; X64-LINUX-NEXT:    jne bar_i64 # TAILCALL
627 ; X64-LINUX-NEXT:  # %bb.1: # %if.end
628 ; X64-LINUX-NEXT:    retq
630 ; X64-WIN32-LABEL: add_i64_128_flag:
631 ; X64-WIN32:       # %bb.0: # %entry
632 ; X64-WIN32-NEXT:    subq $-128, %rcx
633 ; X64-WIN32-NEXT:    jne bar_i64 # TAILCALL
634 ; X64-WIN32-NEXT:  # %bb.1: # %if.end
635 ; X64-WIN32-NEXT:    retq
636 entry:
637   %add = add i64 %x, 128
638   %tobool = icmp eq i64 %add, 0
639   br i1 %tobool, label %if.end, label %if.then
641 if.then:
642   tail call void @bar_i64(i64 %add)
643   br label %if.end
645 if.end:
646   ret void
649 ; Make sure we can use sub -2147483648 for add 2147483648 when the flags are used.
650 define void @add_i64_2147483648_flag(i64 %x) {
651 ; X86-LABEL: add_i64_2147483648_flag:
652 ; X86:       # %bb.0: # %entry
653 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
654 ; X86-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
655 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
656 ; X86-NEXT:    adcl $0, %ecx
657 ; X86-NEXT:    movl %eax, %edx
658 ; X86-NEXT:    orl %ecx, %edx
659 ; X86-NEXT:    je .LBB21_2
660 ; X86-NEXT:  # %bb.1: # %if.then
661 ; X86-NEXT:    pushl %ecx
662 ; X86-NEXT:    .cfi_adjust_cfa_offset 4
663 ; X86-NEXT:    pushl %eax
664 ; X86-NEXT:    .cfi_adjust_cfa_offset 4
665 ; X86-NEXT:    calll bar_i64
666 ; X86-NEXT:    addl $8, %esp
667 ; X86-NEXT:    .cfi_adjust_cfa_offset -8
668 ; X86-NEXT:  .LBB21_2: # %if.end
669 ; X86-NEXT:    retl
671 ; X64-LINUX-LABEL: add_i64_2147483648_flag:
672 ; X64-LINUX:       # %bb.0: # %entry
673 ; X64-LINUX-NEXT:    subq $-2147483648, %rdi # imm = 0x80000000
674 ; X64-LINUX-NEXT:    jne bar_i64 # TAILCALL
675 ; X64-LINUX-NEXT:  # %bb.1: # %if.end
676 ; X64-LINUX-NEXT:    retq
678 ; X64-WIN32-LABEL: add_i64_2147483648_flag:
679 ; X64-WIN32:       # %bb.0: # %entry
680 ; X64-WIN32-NEXT:    subq $-2147483648, %rcx # imm = 0x80000000
681 ; X64-WIN32-NEXT:    jne bar_i64 # TAILCALL
682 ; X64-WIN32-NEXT:  # %bb.1: # %if.end
683 ; X64-WIN32-NEXT:    retq
684 entry:
685   %add = add i64 %x, 2147483648
686   %tobool = icmp eq i64 %add, 0
687   br i1 %tobool, label %if.end, label %if.then
689 if.then:
690   tail call void @bar_i64(i64 %add)
691   br label %if.end
693 if.end:
694   ret void