[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / codegen-prepare-uaddo.ll
bloba0686cfe5e13eefbf731d6e8445835ff06662777
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s
4 ; PR31754
6 ; #include <x86intrin.h>
7 ; using u64 = unsigned long long;
9 ; template<u64 K>
10 ; void test(u64& alo, u64& ahi)
11 ; {
12 ;     u64 blo = K;
13 ;     u64 bhi = 0;
14 ;     bool cf = (alo += blo) < blo;
15 ;     _addcarry_u64(cf, ahi, bhi, &ahi);
16 ; }
18 ; template void test<0ull>(u64&, u64&);
19 ; template void test<1ull>(u64&, u64&);
20 ; template void test<2ull>(u64&, u64&);
21 ; template void test<3ull>(u64&, u64&);
22 ; template void test<4ull>(u64&, u64&);
23 ; template void test<0x7fffffffffffffffull>(u64&, u64&);
24 ; template void test<0x8000000000000000ull>(u64&, u64&);
25 ; template void test<0x8000000000000001ull>(u64&, u64&);
26 ; template void test<0xffffffff80000000ull>(u64&, u64&);
27 ; template void test<0xfffffffffffffffdull>(u64&, u64&);
28 ; template void test<0xfffffffffffffffeull>(u64&, u64&);
29 ; template void test<0xffffffffffffffffull>(u64&, u64&);
31 define void @test_0(ptr, ptr) {
32 ; CHECK-LABEL: test_0:
33 ; CHECK:       # %bb.0:
34 ; CHECK-NEXT:    retq
35   %3 = load i64, ptr %1, align 8
36   %4 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 0, i64 %3, i64 0)
37   %5 = extractvalue { i8, i64 } %4, 1
38   store i64 %5, ptr %1, align 8
39   ret void
42 define void @test_1(ptr, ptr) {
43 ; CHECK-LABEL: test_1:
44 ; CHECK:       # %bb.0:
45 ; CHECK-NEXT:    addq $1, (%rdi)
46 ; CHECK-NEXT:    adcq $0, (%rsi)
47 ; CHECK-NEXT:    retq
48   %3 = load i64, ptr %0, align 8
49   %4 = add i64 %3, 1
50   store i64 %4, ptr %0, align 8
51   %5 = icmp eq i64 %4, 0
52   %6 = zext i1 %5 to i8
53   %7 = load i64, ptr %1, align 8
54   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
55   %9 = extractvalue { i8, i64 } %8, 1
56   store i64 %9, ptr %1, align 8
57   ret void
60 define void @test_2(ptr, ptr) {
61 ; CHECK-LABEL: test_2:
62 ; CHECK:       # %bb.0:
63 ; CHECK-NEXT:    addq $2, (%rdi)
64 ; CHECK-NEXT:    adcq $0, (%rsi)
65 ; CHECK-NEXT:    retq
66   %3 = load i64, ptr %0, align 8
67   %4 = add i64 %3, 2
68   store i64 %4, ptr %0, align 8
69   %5 = icmp ult i64 %4, 2
70   %6 = zext i1 %5 to i8
71   %7 = load i64, ptr %1, align 8
72   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
73   %9 = extractvalue { i8, i64 } %8, 1
74   store i64 %9, ptr %1, align 8
75   ret void
78 define void @test_3(ptr, ptr) {
79 ; CHECK-LABEL: test_3:
80 ; CHECK:       # %bb.0:
81 ; CHECK-NEXT:    addq $3, (%rdi)
82 ; CHECK-NEXT:    adcq $0, (%rsi)
83 ; CHECK-NEXT:    retq
84   %3 = load i64, ptr %0, align 8
85   %4 = add i64 %3, 3
86   store i64 %4, ptr %0, align 8
87   %5 = icmp ult i64 %4, 3
88   %6 = zext i1 %5 to i8
89   %7 = load i64, ptr %1, align 8
90   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
91   %9 = extractvalue { i8, i64 } %8, 1
92   store i64 %9, ptr %1, align 8
93   ret void
96 define void @test_4(ptr, ptr) {
97 ; CHECK-LABEL: test_4:
98 ; CHECK:       # %bb.0:
99 ; CHECK-NEXT:    addq $4, (%rdi)
100 ; CHECK-NEXT:    adcq $0, (%rsi)
101 ; CHECK-NEXT:    retq
102   %3 = load i64, ptr %0, align 8
103   %4 = add i64 %3, 4
104   store i64 %4, ptr %0, align 8
105   %5 = icmp ult i64 %4, 4
106   %6 = zext i1 %5 to i8
107   %7 = load i64, ptr %1, align 8
108   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
109   %9 = extractvalue { i8, i64 } %8, 1
110   store i64 %9, ptr %1, align 8
111   ret void
114 define void @test_9223372036854775807(ptr, ptr) {
115 ; CHECK-LABEL: test_9223372036854775807:
116 ; CHECK:       # %bb.0:
117 ; CHECK-NEXT:    movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF
118 ; CHECK-NEXT:    addq %rax, (%rdi)
119 ; CHECK-NEXT:    adcq $0, (%rsi)
120 ; CHECK-NEXT:    retq
121   %3 = load i64, ptr %0, align 8
122   %4 = add i64 %3, 9223372036854775807
123   store i64 %4, ptr %0, align 8
124   %5 = icmp ult i64 %4, 9223372036854775807
125   %6 = zext i1 %5 to i8
126   %7 = load i64, ptr %1, align 8
127   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
128   %9 = extractvalue { i8, i64 } %8, 1
129   store i64 %9, ptr %1, align 8
130   ret void
133 define void @test_9223372036854775808(ptr, ptr) {
134 ; CHECK-LABEL: test_9223372036854775808:
135 ; CHECK:       # %bb.0:
136 ; CHECK-NEXT:    movq (%rdi), %rax
137 ; CHECK-NEXT:    movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
138 ; CHECK-NEXT:    xorq %rax, %rcx
139 ; CHECK-NEXT:    movq %rcx, (%rdi)
140 ; CHECK-NEXT:    shrq $63, %rax
141 ; CHECK-NEXT:    addb $-1, %al
142 ; CHECK-NEXT:    adcq $0, (%rsi)
143 ; CHECK-NEXT:    retq
144   %3 = load i64, ptr %0, align 8
145   %4 = xor i64 %3, -9223372036854775808
146   store i64 %4, ptr %0, align 8
147   %5 = lshr i64 %3, 63
148   %6 = trunc i64 %5 to i8
149   %7 = load i64, ptr %1, align 8
150   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
151   %9 = extractvalue { i8, i64 } %8, 1
152   store i64 %9, ptr %1, align 8
153   ret void
156 define void @test_9223372036854775809(ptr, ptr) {
157 ; CHECK-LABEL: test_9223372036854775809:
158 ; CHECK:       # %bb.0:
159 ; CHECK-NEXT:    movabsq $-9223372036854775807, %rax # imm = 0x8000000000000001
160 ; CHECK-NEXT:    addq %rax, (%rdi)
161 ; CHECK-NEXT:    adcq $0, (%rsi)
162 ; CHECK-NEXT:    retq
163   %3 = load i64, ptr %0, align 8
164   %4 = add i64 %3, -9223372036854775807
165   store i64 %4, ptr %0, align 8
166   %5 = icmp ult i64 %4, -9223372036854775807
167   %6 = zext i1 %5 to i8
168   %7 = load i64, ptr %1, align 8
169   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
170   %9 = extractvalue { i8, i64 } %8, 1
171   store i64 %9, ptr %1, align 8
172   ret void
175 define void @test_18446744071562067968(ptr, ptr) {
176 ; CHECK-LABEL: test_18446744071562067968:
177 ; CHECK:       # %bb.0:
178 ; CHECK-NEXT:    addq $-2147483648, (%rdi) # imm = 0x80000000
179 ; CHECK-NEXT:    adcq $0, (%rsi)
180 ; CHECK-NEXT:    retq
181   %3 = load i64, ptr %0, align 8
182   %4 = add i64 %3, -2147483648
183   store i64 %4, ptr %0, align 8
184   %5 = icmp ult i64 %4, -2147483648
185   %6 = zext i1 %5 to i8
186   %7 = load i64, ptr %1, align 8
187   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
188   %9 = extractvalue { i8, i64 } %8, 1
189   store i64 %9, ptr %1, align 8
190   ret void
193 define void @test_18446744073709551613(ptr, ptr) {
194 ; CHECK-LABEL: test_18446744073709551613:
195 ; CHECK:       # %bb.0:
196 ; CHECK-NEXT:    addq $-3, (%rdi)
197 ; CHECK-NEXT:    adcq $0, (%rsi)
198 ; CHECK-NEXT:    retq
199   %3 = load i64, ptr %0, align 8
200   %4 = add i64 %3, -3
201   store i64 %4, ptr %0, align 8
202   %5 = icmp ult i64 %4, -3
203   %6 = zext i1 %5 to i8
204   %7 = load i64, ptr %1, align 8
205   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
206   %9 = extractvalue { i8, i64 } %8, 1
207   store i64 %9, ptr %1, align 8
208   ret void
211 define void @test_18446744073709551614(ptr, ptr) {
212 ; CHECK-LABEL: test_18446744073709551614:
213 ; CHECK:       # %bb.0:
214 ; CHECK-NEXT:    addq $-2, (%rdi)
215 ; CHECK-NEXT:    adcq $0, (%rsi)
216 ; CHECK-NEXT:    retq
217   %3 = load i64, ptr %0, align 8
218   %4 = add i64 %3, -2
219   store i64 %4, ptr %0, align 8
220   %5 = icmp ult i64 %4, -2
221   %6 = zext i1 %5 to i8
222   %7 = load i64, ptr %1, align 8
223   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
224   %9 = extractvalue { i8, i64 } %8, 1
225   store i64 %9, ptr %1, align 8
226   ret void
229 define void @test_18446744073709551615(ptr, ptr) {
230 ; CHECK-LABEL: test_18446744073709551615:
231 ; CHECK:       # %bb.0:
232 ; CHECK-NEXT:    addq $-1, (%rdi)
233 ; CHECK-NEXT:    adcq $0, (%rsi)
234 ; CHECK-NEXT:    retq
235   %3 = load i64, ptr %0, align 8
236   %4 = add i64 %3, -1
237   store i64 %4, ptr %0, align 8
238   %5 = icmp ne i64 %3, 0
239   %6 = zext i1 %5 to i8
240   %7 = load i64, ptr %1, align 8
241   %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
242   %9 = extractvalue { i8, i64 } %8, 1
243   store i64 %9, ptr %1, align 8
244   ret void
247 define i1 @illegal_type(i17 %x, ptr %p) {
248 ; CHECK-LABEL: illegal_type:
249 ; CHECK:       # %bb.0:
250 ; CHECK-NEXT:    addl $29, %edi
251 ; CHECK-NEXT:    movw %di, (%rsi)
252 ; CHECK-NEXT:    andl $131071, %edi # imm = 0x1FFFF
253 ; CHECK-NEXT:    movl %edi, %eax
254 ; CHECK-NEXT:    shrl $16, %eax
255 ; CHECK-NEXT:    movb %al, 2(%rsi)
256 ; CHECK-NEXT:    cmpl $29, %edi
257 ; CHECK-NEXT:    setb %al
258 ; CHECK-NEXT:    retq
259   %a = add i17 %x, 29
260   store i17 %a, ptr %p
261   %ov = icmp ult i17 %a, 29
262   ret i1 %ov
265 ; The overflow check may be against the input rather than the sum.
267 define i1 @uaddo_i64_increment_alt(i64 %x, ptr %p) {
268 ; CHECK-LABEL: uaddo_i64_increment_alt:
269 ; CHECK:       # %bb.0:
270 ; CHECK-NEXT:    incq %rdi
271 ; CHECK-NEXT:    sete %al
272 ; CHECK-NEXT:    movq %rdi, (%rsi)
273 ; CHECK-NEXT:    retq
274   %a = add i64 %x, 1
275   store i64 %a, ptr %p
276   %ov = icmp eq i64 %x, -1
277   ret i1 %ov
280 ; Make sure insertion is done correctly based on dominance.
282 define i1 @uaddo_i64_increment_alt_dom(i64 %x, ptr %p) {
283 ; CHECK-LABEL: uaddo_i64_increment_alt_dom:
284 ; CHECK:       # %bb.0:
285 ; CHECK-NEXT:    incq %rdi
286 ; CHECK-NEXT:    sete %al
287 ; CHECK-NEXT:    movq %rdi, (%rsi)
288 ; CHECK-NEXT:    retq
289   %ov = icmp eq i64 %x, -1
290   %a = add i64 %x, 1
291   store i64 %a, ptr %p
292   ret i1 %ov
295 ; The overflow check may be against the input rather than the sum.
297 define i1 @uaddo_i64_decrement_alt(i64 %x, ptr %p) {
298 ; CHECK-LABEL: uaddo_i64_decrement_alt:
299 ; CHECK:       # %bb.0:
300 ; CHECK-NEXT:    addq $-1, %rdi
301 ; CHECK-NEXT:    setb %al
302 ; CHECK-NEXT:    movq %rdi, (%rsi)
303 ; CHECK-NEXT:    retq
304   %a = add i64 %x, -1
305   store i64 %a, ptr %p
306   %ov = icmp ne i64 %x, 0
307   ret i1 %ov
310 ; Make sure insertion is done correctly based on dominance.
312 define i1 @uaddo_i64_decrement_alt_dom(i64 %x, ptr %p) {
313 ; CHECK-LABEL: uaddo_i64_decrement_alt_dom:
314 ; CHECK:       # %bb.0:
315 ; CHECK-NEXT:    addq $-1, %rdi
316 ; CHECK-NEXT:    setb %al
317 ; CHECK-NEXT:    movq %rdi, (%rsi)
318 ; CHECK-NEXT:    retq
319   %ov = icmp ne i64 %x, 0
320   %a = add i64 %x, -1
321   store i64 %a, ptr %p
322   ret i1 %ov
325 declare { i8, i64 } @llvm.x86.addcarry.64(i8, i64, i64)