]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/X86/add.ll
Vendor import of llvm trunk r338150:
[FreeBSD/FreeBSD.git] / test / CodeGen / X86 / add.ll
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
6 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32)
7 declare {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.
11 define 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
28 entry:
29   %b = add i32 %a, 128
30   ret i32 %b
31 }
32 define 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
50 entry:
51   %b = add i64 %a, 2147483648
52   ret i64 %b
53 }
54 define 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
72 entry:
73   %b = add i64 %a, 128
74   ret i64 %b
75 }
76
77 define 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
109 entry:
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
115 normal:
116   store i32 0, i32* %X
117   br label %overflow
118
119 overflow:
120   ret i1 false
121 }
122
123 define 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
155 entry:
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
161 normal:
162   store i32 0, i32* %X
163   br label %carry
164
165 carry:
166   ret i1 false
167 }
168
169 define 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
190 entry:
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
197 define {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
218 entry:
219   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
220   ret {i32, i1} %t
221 }
222
223 ; PR5443
224 define {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
247 entry:
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
259 define 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
286 entry:
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
293 define 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
312 entry:
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
318 define 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
333 entry:
334   %aa = load i32, i32* %a
335   %b = add i32 %aa, 128
336   store i32 %b, i32* %a
337   ret void
338 }
339
340 define 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
356 entry:
357   %aa = load i64, i64* %a
358   %b = add i64 %aa, 2147483648
359   store i64 %b, i64* %a
360   ret void
361 }
362
363 define 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
379 entry:
380   %aa = load i64, i64* %a
381   %b = add i64 %aa, 128
382   store i64 %b, i64* %a
383   ret void
384 }
385
386 define 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
409 define 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 }