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 {
13 ; X86: # %bb.0: # %entry
14 ; X86-NEXT: subl $-128, %eax
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
33 define i32 @test1b(ptr %p) nounwind {
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
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
58 define i64 @test2(i64 inreg %a) nounwind {
60 ; X86: # %bb.0: # %entry
61 ; X86-NEXT: addl $-2147483648, %eax # imm = 0x80000000
62 ; X86-NEXT: adcl $0, %edx
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
77 %b = add i64 %a, 2147483648
80 define i64 @test3(i64 inreg %a) nounwind {
82 ; X86: # %bb.0: # %entry
83 ; X86-NEXT: addl $128, %eax
84 ; X86-NEXT: adcl $0, %edx
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
101 define i64 @test3b(ptr %p) nounwind {
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
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
123 %a = load i64, ptr %p
128 define i1 @test4(i32 %v1, i32 %v2, ptr %X) nounwind {
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
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
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
174 define i1 @test5(i32 %v1, i32 %v2, ptr %X) nounwind {
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
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
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
220 define i64 @test6(i64 %A, i32 %B) nounwind {
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
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
242 %tmp12 = zext i32 %B to i64
243 %tmp3 = shl i64 %tmp12, 32
244 %tmp5 = add i64 %tmp3, %A
248 define {i32, i1} @test7(i32 %v1, i32 %v2) nounwind {
250 ; X86: # %bb.0: # %entry
251 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
252 ; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
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
270 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
275 define {i64, i1} @test8(i64 %left, i64 %right) nounwind {
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
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
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 {
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)
317 ; X86-NEXT: subl %ecx, %eax
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
338 %cmp = icmp eq i32 %x, 10
339 %sub = sext i1 %cmp to i32
340 %cond = add i32 %sub, %y
344 define i1 @test10(i32 %x) nounwind {
346 ; X86: # %bb.0: # %entry
347 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
348 ; X86-NEXT: incl %eax
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
364 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
365 %obit = extractvalue {i32, i1} %t, 1
369 define void @test11(ptr inreg %a) nounwind {
371 ; X86: # %bb.0: # %entry
372 ; X86-NEXT: subl $-128, (%eax)
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
385 %aa = load i32, ptr %a
386 %b = add i32 %aa, 128
391 define void @test12(ptr inreg %a) nounwind {
393 ; X86: # %bb.0: # %entry
394 ; X86-NEXT: addl $-2147483648, (%eax) # imm = 0x80000000
395 ; X86-NEXT: adcl $0, 4(%eax)
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
408 %aa = load i64, ptr %a
409 %b = add i64 %aa, 2147483648
414 define void @test13(ptr inreg %a) nounwind {
416 ; X86: # %bb.0: # %entry
417 ; X86-NEXT: addl $128, (%eax)
418 ; X86-NEXT: adcl $0, 4(%eax)
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
431 %aa = load i64, ptr %a
432 %b = add i64 %aa, 128
437 define i32 @inc_not(i32 %a) {
438 ; X86-LABEL: inc_not:
440 ; X86-NEXT: xorl %eax, %eax
441 ; X86-NEXT: subl {{[0-9]+}}(%esp), %eax
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
460 define <4 x i32> @inc_not_vec(<4 x i32> %a) nounwind {
461 ; X86-LABEL: inc_not_vec:
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
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>
499 define void @uaddo1_not(i32 %a, ptr %p0, ptr %p1) {
500 ; X86-LABEL: uaddo1_not:
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)
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
532 define i32 @add_to_sub(i32 %a, i32 %b) {
533 ; X86-LABEL: add_to_sub:
535 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
536 ; X86-NEXT: subl {{[0-9]+}}(%esp), %eax
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
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
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
589 %add = add i32 %x, 128
590 %tobool = icmp eq i32 %add, 0
591 br i1 %tobool, label %if.end, label %if.then
594 tail call void @bar_i32(i32 %add)
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
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
637 %add = add i64 %x, 128
638 %tobool = icmp eq i64 %add, 0
639 br i1 %tobool, label %if.end, label %if.then
642 tail call void @bar_i64(i64 %add)
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
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
685 %add = add i64 %x, 2147483648
686 %tobool = icmp eq i64 %add, 0
687 br i1 %tobool, label %if.end, label %if.then
690 tail call void @bar_i64(i64 %add)