blob: 2bc13cc57d2cebdcf6acc544ed96f6cc9207d9a7 [file] [log] [blame]
Simon Pilgrimf6d7cfe2019-01-27 14:04:45 +00001; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s
3
4; PR31754
5;
6; #include <x86intrin.h>
7; using u64 = unsigned long long;
8;
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; }
17;
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&);
30
31define void @test_0(i64*, i64*) {
32; CHECK-LABEL: test_0:
33; CHECK: # %bb.0:
34; CHECK-NEXT: retq
35 %3 = load i64, i64* %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, i64* %1, align 8
39 ret void
40}
41
42define void @test_1(i64*, i64*) {
43; CHECK-LABEL: test_1:
44; CHECK: # %bb.0:
Craig Topper950ca192019-02-03 07:25:06 +000045; CHECK-NEXT: addq $1, (%rdi)
Simon Pilgrimf6d7cfe2019-01-27 14:04:45 +000046; CHECK-NEXT: adcq $0, (%rsi)
47; CHECK-NEXT: retq
48 %3 = load i64, i64* %0, align 8
49 %4 = add i64 %3, 1
50 store i64 %4, i64* %0, align 8
51 %5 = icmp eq i64 %4, 0
52 %6 = zext i1 %5 to i8
53 %7 = load i64, i64* %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, i64* %1, align 8
57 ret void
58}
59
60define void @test_2(i64*, i64*) {
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, i64* %0, align 8
67 %4 = add i64 %3, 2
68 store i64 %4, i64* %0, align 8
69 %5 = icmp ult i64 %4, 2
70 %6 = zext i1 %5 to i8
71 %7 = load i64, i64* %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, i64* %1, align 8
75 ret void
76}
77
78define void @test_3(i64*, i64*) {
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, i64* %0, align 8
85 %4 = add i64 %3, 3
86 store i64 %4, i64* %0, align 8
87 %5 = icmp ult i64 %4, 3
88 %6 = zext i1 %5 to i8
89 %7 = load i64, i64* %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, i64* %1, align 8
93 ret void
94}
95
96define void @test_4(i64*, i64*) {
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, i64* %0, align 8
103 %4 = add i64 %3, 4
104 store i64 %4, i64* %0, align 8
105 %5 = icmp ult i64 %4, 4
106 %6 = zext i1 %5 to i8
107 %7 = load i64, i64* %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, i64* %1, align 8
111 ret void
112}
113
114define void @test_9223372036854775807(i64*, i64*) {
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, i64* %0, align 8
122 %4 = add i64 %3, 9223372036854775807
123 store i64 %4, i64* %0, align 8
124 %5 = icmp ult i64 %4, 9223372036854775807
125 %6 = zext i1 %5 to i8
126 %7 = load i64, i64* %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, i64* %1, align 8
130 ret void
131}
132
133define void @test_9223372036854775808(i64*, i64*) {
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, i64* %0, align 8
145 %4 = xor i64 %3, -9223372036854775808
146 store i64 %4, i64* %0, align 8
147 %5 = lshr i64 %3, 63
148 %6 = trunc i64 %5 to i8
149 %7 = load i64, i64* %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, i64* %1, align 8
153 ret void
154}
155
156define void @test_9223372036854775809(i64*, i64*) {
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, i64* %0, align 8
164 %4 = add i64 %3, -9223372036854775807
165 store i64 %4, i64* %0, align 8
166 %5 = icmp ult i64 %4, -9223372036854775807
167 %6 = zext i1 %5 to i8
168 %7 = load i64, i64* %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, i64* %1, align 8
172 ret void
173}
174
175define void @test_18446744071562067968(i64*, i64*) {
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, i64* %0, align 8
182 %4 = add i64 %3, -2147483648
183 store i64 %4, i64* %0, align 8
184 %5 = icmp ult i64 %4, -2147483648
185 %6 = zext i1 %5 to i8
186 %7 = load i64, i64* %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, i64* %1, align 8
190 ret void
191}
192
193define void @test_18446744073709551613(i64*, i64*) {
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, i64* %0, align 8
200 %4 = add i64 %3, -3
201 store i64 %4, i64* %0, align 8
202 %5 = icmp ult i64 %4, -3
203 %6 = zext i1 %5 to i8
204 %7 = load i64, i64* %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, i64* %1, align 8
208 ret void
209}
210
211define void @test_18446744073709551614(i64*, i64*) {
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, i64* %0, align 8
218 %4 = add i64 %3, -2
219 store i64 %4, i64* %0, align 8
220 %5 = icmp ult i64 %4, -2
221 %6 = zext i1 %5 to i8
222 %7 = load i64, i64* %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, i64* %1, align 8
226 ret void
227}
228
229define void @test_18446744073709551615(i64*, i64*) {
230; CHECK-LABEL: test_18446744073709551615:
231; CHECK: # %bb.0:
232; CHECK-NEXT: movq (%rdi), %rax
233; CHECK-NEXT: leaq -1(%rax), %rcx
234; CHECK-NEXT: movq %rcx, (%rdi)
235; CHECK-NEXT: testq %rax, %rax
236; CHECK-NEXT: setne %al
237; CHECK-NEXT: addb $-1, %al
238; CHECK-NEXT: adcq $0, (%rsi)
239; CHECK-NEXT: retq
240 %3 = load i64, i64* %0, align 8
241 %4 = add i64 %3, -1
242 store i64 %4, i64* %0, align 8
243 %5 = icmp ne i64 %3, 0
244 %6 = zext i1 %5 to i8
245 %7 = load i64, i64* %1, align 8
246 %8 = tail call { i8, i64 } @llvm.x86.addcarry.64(i8 %6, i64 %7, i64 0)
247 %9 = extractvalue { i8, i64 } %8, 1
248 store i64 %9, i64* %1, align 8
249 ret void
250}
251
Sanjay Patel3d6ecfc2019-02-03 14:22:43 +0000252define i1 @illegal_type(i17 %x, i17* %p) {
253; CHECK-LABEL: illegal_type:
254; CHECK: # %bb.0:
Sanjay Patel3d6ecfc2019-02-03 14:22:43 +0000255; CHECK-NEXT: addl $29, %edi
Sanjay Patel3d6ecfc2019-02-03 14:22:43 +0000256; CHECK-NEXT: movw %di, (%rsi)
Sanjay Patel84ceae62019-02-03 17:53:09 +0000257; CHECK-NEXT: andl $131071, %edi # imm = 0x1FFFF
258; CHECK-NEXT: movl %edi, %eax
259; CHECK-NEXT: shrl $16, %eax
260; CHECK-NEXT: movb %al, 2(%rsi)
261; CHECK-NEXT: cmpl $29, %edi
262; CHECK-NEXT: setb %al
Sanjay Patel3d6ecfc2019-02-03 14:22:43 +0000263; CHECK-NEXT: retq
264 %a = add i17 %x, 29
265 store i17 %a, i17* %p
266 %ov = icmp ult i17 %a, 29
267 ret i1 %ov
268}
269
Simon Pilgrimf6d7cfe2019-01-27 14:04:45 +0000270declare { i8, i64 } @llvm.x86.addcarry.64(i8, i64, i64)