• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s
3
4define i128 @add128(i128 %a, i128 %b) nounwind {
5; CHECK-LABEL: add128:
6; CHECK:       # %bb.0: # %entry
7; CHECK-NEXT:    addq %rdx, %rdi
8; CHECK-NEXT:    adcq %rcx, %rsi
9; CHECK-NEXT:    movq %rdi, %rax
10; CHECK-NEXT:    movq %rsi, %rdx
11; CHECK-NEXT:    retq
12entry:
13  %0 = add i128 %a, %b
14  ret i128 %0
15}
16
17define i256 @add256(i256 %a, i256 %b) nounwind {
18; CHECK-LABEL: add256:
19; CHECK:       # %bb.0: # %entry
20; CHECK-NEXT:    addq %r9, %rsi
21; CHECK-NEXT:    adcq {{[0-9]+}}(%rsp), %rdx
22; CHECK-NEXT:    adcq {{[0-9]+}}(%rsp), %rcx
23; CHECK-NEXT:    adcq {{[0-9]+}}(%rsp), %r8
24; CHECK-NEXT:    movq %rdx, 8(%rdi)
25; CHECK-NEXT:    movq %rsi, (%rdi)
26; CHECK-NEXT:    movq %rcx, 16(%rdi)
27; CHECK-NEXT:    movq %r8, 24(%rdi)
28; CHECK-NEXT:    movq %rdi, %rax
29; CHECK-NEXT:    retq
30entry:
31  %0 = add i256 %a, %b
32  ret i256 %0
33}
34
35define void @a(i64* nocapture %s, i64* nocapture %t, i64 %a, i64 %b, i64 %c) nounwind {
36; CHECK-LABEL: a:
37; CHECK:       # %bb.0: # %entry
38; CHECK-NEXT:    addq %rcx, %rdx
39; CHECK-NEXT:    adcq $0, %r8
40; CHECK-NEXT:    movq %r8, (%rdi)
41; CHECK-NEXT:    movq %rdx, (%rsi)
42; CHECK-NEXT:    retq
43entry:
44 %0 = zext i64 %a to i128
45 %1 = zext i64 %b to i128
46 %2 = add i128 %1, %0
47 %3 = zext i64 %c to i128
48 %4 = shl i128 %3, 64
49 %5 = add i128 %4, %2
50 %6 = lshr i128 %5, 64
51 %7 = trunc i128 %6 to i64
52 store i64 %7, i64* %s, align 8
53 %8 = trunc i128 %2 to i64
54 store i64 %8, i64* %t, align 8
55 ret void
56}
57
58define void @b(i32* nocapture %r, i64 %a, i64 %b, i32 %c) nounwind {
59; CHECK-LABEL: b:
60; CHECK:       # %bb.0: # %entry
61; CHECK-NEXT:    addq %rdx, %rsi
62; CHECK-NEXT:    adcl $0, %ecx
63; CHECK-NEXT:    movl %ecx, (%rdi)
64; CHECK-NEXT:    retq
65entry:
66 %0 = zext i64 %a to i128
67 %1 = zext i64 %b to i128
68 %2 = zext i32 %c to i128
69 %3 = add i128 %1, %0
70 %4 = lshr i128 %3, 64
71 %5 = add i128 %4, %2
72 %6 = trunc i128 %5 to i32
73 store i32 %6, i32* %r, align 4
74 ret void
75}
76
77define void @c(i16* nocapture %r, i64 %a, i64 %b, i16 %c) nounwind {
78; CHECK-LABEL: c:
79; CHECK:       # %bb.0: # %entry
80; CHECK-NEXT:    addq %rdx, %rsi
81; CHECK-NEXT:    adcw $0, %cx
82; CHECK-NEXT:    movw %cx, (%rdi)
83; CHECK-NEXT:    retq
84entry:
85 %0 = zext i64 %a to i128
86 %1 = zext i64 %b to i128
87 %2 = zext i16 %c to i128
88 %3 = add i128 %1, %0
89 %4 = lshr i128 %3, 64
90 %5 = add i128 %4, %2
91 %6 = trunc i128 %5 to i16
92 store i16 %6, i16* %r, align 4
93 ret void
94}
95
96define void @d(i8* nocapture %r, i64 %a, i64 %b, i8 %c) nounwind {
97; CHECK-LABEL: d:
98; CHECK:       # %bb.0: # %entry
99; CHECK-NEXT:    addq %rdx, %rsi
100; CHECK-NEXT:    adcb $0, %cl
101; CHECK-NEXT:    movb %cl, (%rdi)
102; CHECK-NEXT:    retq
103entry:
104 %0 = zext i64 %a to i128
105 %1 = zext i64 %b to i128
106 %2 = zext i8 %c to i128
107 %3 = add i128 %1, %0
108 %4 = lshr i128 %3, 64
109 %5 = add i128 %4, %2
110 %6 = trunc i128 %5 to i8
111 store i8 %6, i8* %r, align 4
112 ret void
113}
114
115define i8 @e(i32* nocapture %a, i32 %b) nounwind {
116; CHECK-LABEL: e:
117; CHECK:       # %bb.0:
118; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
119; CHECK-NEXT:    movl (%rdi), %ecx
120; CHECK-NEXT:    leal (%rsi,%rcx), %edx
121; CHECK-NEXT:    addl %esi, %edx
122; CHECK-NEXT:    setb %al
123; CHECK-NEXT:    addl %esi, %ecx
124; CHECK-NEXT:    movl %edx, (%rdi)
125; CHECK-NEXT:    adcb $0, %al
126; CHECK-NEXT:    retq
127  %1 = load i32, i32* %a, align 4
128  %2 = add i32 %1, %b
129  %3 = icmp ult i32 %2, %b
130  %4 = zext i1 %3 to i8
131  %5 = add i32 %2, %b
132  store i32 %5, i32* %a, align 4
133  %6 = icmp ult i32 %5, %b
134  %7 = zext i1 %6 to i8
135  %8 = add nuw nsw i8 %7, %4
136  ret i8 %8
137}
138
139%scalar = type { [4 x i64] }
140
141define %scalar @pr31719(%scalar* nocapture readonly %this, %scalar %arg.b) {
142; CHECK-LABEL: pr31719:
143; CHECK:       # %bb.0: # %entry
144; CHECK-NEXT:    addq (%rsi), %rdx
145; CHECK-NEXT:    adcq 8(%rsi), %rcx
146; CHECK-NEXT:    adcq 16(%rsi), %r8
147; CHECK-NEXT:    adcq 24(%rsi), %r9
148; CHECK-NEXT:    movq %rdx, (%rdi)
149; CHECK-NEXT:    movq %rcx, 8(%rdi)
150; CHECK-NEXT:    movq %r8, 16(%rdi)
151; CHECK-NEXT:    movq %r9, 24(%rdi)
152; CHECK-NEXT:    movq %rdi, %rax
153; CHECK-NEXT:    retq
154entry:
155  %0 = extractvalue %scalar %arg.b, 0
156  %.elt = extractvalue [4 x i64] %0, 0
157  %.elt24 = extractvalue [4 x i64] %0, 1
158  %.elt26 = extractvalue [4 x i64] %0, 2
159  %.elt28 = extractvalue [4 x i64] %0, 3
160  %1 = getelementptr inbounds %scalar , %scalar* %this, i64 0, i32 0, i64 0
161  %2 = load i64, i64* %1, align 8
162  %3 = zext i64 %2 to i128
163  %4 = zext i64 %.elt to i128
164  %5 = add nuw nsw i128 %3, %4
165  %6 = trunc i128 %5 to i64
166  %7 = lshr i128 %5, 64
167  %8 = getelementptr inbounds %scalar , %scalar * %this, i64 0, i32 0, i64 1
168  %9 = load i64, i64* %8, align 8
169  %10 = zext i64 %9 to i128
170  %11 = zext i64 %.elt24 to i128
171  %12 = add nuw nsw i128 %10, %11
172  %13 = add nuw nsw i128 %12, %7
173  %14 = trunc i128 %13 to i64
174  %15 = lshr i128 %13, 64
175  %16 = getelementptr inbounds %scalar , %scalar* %this, i64 0, i32 0, i64 2
176  %17 = load i64, i64* %16, align 8
177  %18 = zext i64 %17 to i128
178  %19 = zext i64 %.elt26 to i128
179  %20 = add nuw nsw i128 %18, %19
180  %21 = add nuw nsw i128 %20, %15
181  %22 = trunc i128 %21 to i64
182  %23 = lshr i128 %21, 64
183  %24 = getelementptr inbounds %scalar , %scalar* %this, i64 0, i32 0, i64 3
184  %25 = load i64, i64* %24, align 8
185  %26 = zext i64 %25 to i128
186  %27 = zext i64 %.elt28 to i128
187  %28 = add nuw nsw i128 %26, %27
188  %29 = add nuw nsw i128 %28, %23
189  %30 = trunc i128 %29 to i64
190  %31 = insertvalue [4 x i64] undef, i64 %6, 0
191  %32 = insertvalue [4 x i64] %31, i64 %14, 1
192  %33 = insertvalue [4 x i64] %32, i64 %22, 2
193  %34 = insertvalue [4 x i64] %33, i64 %30, 3
194  %35 = insertvalue %scalar undef, [4 x i64] %34, 0
195  ret %scalar %35
196}
197
198%accumulator= type { i64, i64, i32 }
199
200define void @muladd(%accumulator* nocapture %this, i64 %arg.a, i64 %arg.b) {
201; CHECK-LABEL: muladd:
202; CHECK:       # %bb.0: # %entry
203; CHECK-NEXT:    movq %rdx, %rax
204; CHECK-NEXT:    mulq %rsi
205; CHECK-NEXT:    addq %rax, (%rdi)
206; CHECK-NEXT:    adcq %rdx, 8(%rdi)
207; CHECK-NEXT:    adcl $0, 16(%rdi)
208; CHECK-NEXT:    retq
209entry:
210  %0 = zext i64 %arg.a to i128
211  %1 = zext i64 %arg.b to i128
212  %2 = mul nuw i128 %1, %0
213  %3 = getelementptr inbounds %accumulator, %accumulator* %this, i64 0, i32 0
214  %4 = load i64, i64* %3, align 8
215  %5 = zext i64 %4 to i128
216  %6 = add i128 %5, %2
217  %7 = trunc i128 %6 to i64
218  store i64 %7, i64* %3, align 8
219  %8 = lshr i128 %6, 64
220  %9 = getelementptr inbounds %accumulator, %accumulator* %this, i64 0, i32 1
221  %10 = load i64, i64* %9, align 8
222  %11 = zext i64 %10 to i128
223  %12 = add nuw nsw i128 %8, %11
224  %13 = trunc i128 %12 to i64
225  store i64 %13, i64* %9, align 8
226  %14 = lshr i128 %12, 64
227  %15 = getelementptr inbounds %accumulator, %accumulator* %this, i64 0, i32 2
228  %16 = load i32, i32* %15, align 4
229  %17 = zext i32 %16 to i128
230  %18 = add nuw nsw i128 %14, %17
231  %19 = trunc i128 %18 to i32
232  store i32 %19, i32* %15, align 4
233  ret void
234}
235
236define i64 @shiftadd(i64 %a, i64 %b, i64 %c, i64 %d) {
237; CHECK-LABEL: shiftadd:
238; CHECK:       # %bb.0: # %entry
239; CHECK-NEXT:    addq %rsi, %rdi
240; CHECK-NEXT:    adcq %rcx, %rdx
241; CHECK-NEXT:    movq %rdx, %rax
242; CHECK-NEXT:    retq
243entry:
244  %0 = zext i64 %a to i128
245  %1 = zext i64 %b to i128
246  %2 = add i128 %0, %1
247  %3 = lshr i128 %2, 64
248  %4 = trunc i128 %3 to i64
249  %5 = add i64 %c, %d
250  %6 = add i64 %4, %5
251  ret i64 %6
252}
253
254%S = type { [4 x i64] }
255
256define %S @readd(%S* nocapture readonly %this, %S %arg.b) {
257; CHECK-LABEL: readd:
258; CHECK:       # %bb.0: # %entry
259; CHECK-NEXT:    addq (%rsi), %rdx
260; CHECK-NEXT:    movq 8(%rsi), %r10
261; CHECK-NEXT:    adcq $0, %r10
262; CHECK-NEXT:    setb %al
263; CHECK-NEXT:    movzbl %al, %eax
264; CHECK-NEXT:    addq %rcx, %r10
265; CHECK-NEXT:    adcq 16(%rsi), %rax
266; CHECK-NEXT:    setb %cl
267; CHECK-NEXT:    movzbl %cl, %ecx
268; CHECK-NEXT:    addq %r8, %rax
269; CHECK-NEXT:    adcq 24(%rsi), %rcx
270; CHECK-NEXT:    addq %r9, %rcx
271; CHECK-NEXT:    movq %rdx, (%rdi)
272; CHECK-NEXT:    movq %r10, 8(%rdi)
273; CHECK-NEXT:    movq %rax, 16(%rdi)
274; CHECK-NEXT:    movq %rcx, 24(%rdi)
275; CHECK-NEXT:    movq %rdi, %rax
276; CHECK-NEXT:    retq
277entry:
278  %0 = extractvalue %S %arg.b, 0
279  %.elt6 = extractvalue [4 x i64] %0, 1
280  %.elt8 = extractvalue [4 x i64] %0, 2
281  %.elt10 = extractvalue [4 x i64] %0, 3
282  %.elt = extractvalue [4 x i64] %0, 0
283  %1 = getelementptr inbounds %S, %S* %this, i64 0, i32 0, i64 0
284  %2 = load i64, i64* %1, align 8
285  %3 = zext i64 %2 to i128
286  %4 = zext i64 %.elt to i128
287  %5 = add nuw nsw i128 %3, %4
288  %6 = trunc i128 %5 to i64
289  %7 = lshr i128 %5, 64
290  %8 = getelementptr inbounds %S, %S* %this, i64 0, i32 0, i64 1
291  %9 = load i64, i64* %8, align 8
292  %10 = zext i64 %9 to i128
293  %11 = add nuw nsw i128 %7, %10
294  %12 = zext i64 %.elt6 to i128
295  %13 = add nuw nsw i128 %11, %12
296  %14 = trunc i128 %13 to i64
297  %15 = lshr i128 %13, 64
298  %16 = getelementptr inbounds %S, %S* %this, i64 0, i32 0, i64 2
299  %17 = load i64, i64* %16, align 8
300  %18 = zext i64 %17 to i128
301  %19 = add nuw nsw i128 %15, %18
302  %20 = zext i64 %.elt8 to i128
303  %21 = add nuw nsw i128 %19, %20
304  %22 = lshr i128 %21, 64
305  %23 = trunc i128 %21 to i64
306  %24 = getelementptr inbounds %S, %S* %this, i64 0,i32 0, i64 3
307  %25 = load i64, i64* %24, align 8
308  %26 = zext i64 %25 to i128
309  %27 = add nuw nsw i128 %22, %26
310  %28 = zext i64 %.elt10 to i128
311  %29 = add nuw nsw i128 %27, %28
312  %30 = trunc i128 %29 to i64
313  %31 = insertvalue [4 x i64] undef, i64 %6, 0
314  %32 = insertvalue [4 x i64] %31, i64 %14, 1
315  %33 = insertvalue [4 x i64] %32, i64 %23, 2
316  %34 = insertvalue [4 x i64] %33, i64 %30, 3
317  %35 = insertvalue %S undef, [4 x i64] %34, 0
318  ret %S %35
319}
320
321define i128 @addcarry1_not(i128 %n) {
322; CHECK-LABEL: addcarry1_not:
323; CHECK:       # %bb.0:
324; CHECK-NEXT:    xorl %edx, %edx
325; CHECK-NEXT:    negq %rdi
326; CHECK-NEXT:    sbbq %rsi, %rdx
327; CHECK-NEXT:    movq %rdi, %rax
328; CHECK-NEXT:    retq
329  %1 = xor i128 %n, -1
330  %2 = add i128 %1, 1
331  ret i128 %2
332}
333