1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown-unknown --show-mc-encoding | FileCheck %s --check-prefix=X32
3 ; RUN: llc < %s -mtriple=x86_64-unknown --show-mc-encoding | FileCheck %s --check-prefix=X64
5 define void @adc_load_store_64_15(i64* inreg %x, i64* inreg %x2, i64 inreg %y) nounwind {
6 ; X32-LABEL: adc_load_store_64_15:
8 ; X32-NEXT: pushl %esi # encoding: [0x56]
9 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x08]
10 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01]
11 ; X32-NEXT: adcl $0, %esi # encoding: [0x83,0xd6,0x00]
12 ; X32-NEXT: adcl $15, (%eax) # encoding: [0x83,0x10,0x0f]
13 ; X32-NEXT: adcl $0, 4(%eax) # encoding: [0x83,0x50,0x04,0x00]
14 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
15 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0]
16 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02]
17 ; X32-NEXT: movl $0, 4(%edx) # encoding: [0xc7,0x42,0x04,0x00,0x00,0x00,0x00]
18 ; X32-NEXT: popl %esi # encoding: [0x5e]
19 ; X32-NEXT: retl # encoding: [0xc3]
21 ; X64-LABEL: adc_load_store_64_15:
23 ; X64-NEXT: addq $1, %rdx # encoding: [0x48,0x83,0xc2,0x01]
24 ; X64-NEXT: adcq $15, (%rdi) # encoding: [0x48,0x83,0x17,0x0f]
25 ; X64-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
26 ; X64-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0]
27 ; X64-NEXT: movq %rax, (%rsi) # encoding: [0x48,0x89,0x06]
28 ; X64-NEXT: retq # encoding: [0xc3]
29 %vx = load i64, i64* %x
30 %zvx = zext i64 %vx to i192
31 %szvx = shl i192 %zvx, 64
32 %zy = zext i64 %y to i192
33 %op = or i192 %szvx, %zy
34 %zsum = add i192 %op, 276701161105643274241 ; 0x0000_0000_0000_0000__0000_0000_0000_000F__0000_0000_0000_0001
35 %ssum = lshr i192 %zsum, 64
36 %val = trunc i192 %ssum to i64
37 store i64 %val, i64* %x
38 %ssum2 = lshr i192 %zsum, 128
39 %val2 = trunc i192 %ssum2 to i64
40 store i64 %val2, i64* %x2
44 define void @adc_load_store_64_0x1000F(i64* inreg %x, i64* inreg %x2, i64 inreg %y) nounwind {
45 ; X32-LABEL: adc_load_store_64_0x1000F:
47 ; X32-NEXT: pushl %esi # encoding: [0x56]
48 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x08]
49 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01]
50 ; X32-NEXT: adcl $0, %esi # encoding: [0x83,0xd6,0x00]
51 ; X32-NEXT: adcl $65551, (%eax) # encoding: [0x81,0x10,0x0f,0x00,0x01,0x00]
52 ; X32-NEXT: # imm = 0x1000F
53 ; X32-NEXT: adcl $0, 4(%eax) # encoding: [0x83,0x50,0x04,0x00]
54 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
55 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0]
56 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02]
57 ; X32-NEXT: movl $0, 4(%edx) # encoding: [0xc7,0x42,0x04,0x00,0x00,0x00,0x00]
58 ; X32-NEXT: popl %esi # encoding: [0x5e]
59 ; X32-NEXT: retl # encoding: [0xc3]
61 ; X64-LABEL: adc_load_store_64_0x1000F:
63 ; X64-NEXT: addq $1, %rdx # encoding: [0x48,0x83,0xc2,0x01]
64 ; X64-NEXT: adcq $65551, (%rdi) # encoding: [0x48,0x81,0x17,0x0f,0x00,0x01,0x00]
65 ; X64-NEXT: # imm = 0x1000F
66 ; X64-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
67 ; X64-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0]
68 ; X64-NEXT: movq %rax, (%rsi) # encoding: [0x48,0x89,0x06]
69 ; X64-NEXT: retq # encoding: [0xc3]
70 %vx = load i64, i64* %x
71 %zvx = zext i64 %vx to i192
72 %szvx = shl i192 %zvx, 64
73 %zy = zext i64 %y to i192
74 %op = or i192 %szvx, %zy
75 %zsum = add i192 %op, 1209202520775734817980417 ; 0x0000_0000_0000_0000__0000_0000_0001_000F__0000_0000_0000_0001
76 %ssum = lshr i192 %zsum, 64
77 %val = trunc i192 %ssum to i64
78 store i64 %val, i64* %x
79 %ssum2 = lshr i192 %zsum, 128
80 %val2 = trunc i192 %ssum2 to i64
81 store i64 %val2, i64* %x2
85 define void @adc_load_store_64_0x100001000F(i64* inreg %x, i64* inreg %x2, i64 inreg %y) nounwind {
86 ; X32-LABEL: adc_load_store_64_0x100001000F:
88 ; X32-NEXT: pushl %esi # encoding: [0x56]
89 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x08]
90 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01]
91 ; X32-NEXT: adcl $0, %esi # encoding: [0x83,0xd6,0x00]
92 ; X32-NEXT: adcl $15, (%eax) # encoding: [0x83,0x10,0x0f]
93 ; X32-NEXT: adcl $16, 4(%eax) # encoding: [0x83,0x50,0x04,0x10]
94 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
95 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0]
96 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02]
97 ; X32-NEXT: movl $0, 4(%edx) # encoding: [0xc7,0x42,0x04,0x00,0x00,0x00,0x00]
98 ; X32-NEXT: popl %esi # encoding: [0x5e]
99 ; X32-NEXT: retl # encoding: [0xc3]
101 ; X64-LABEL: adc_load_store_64_0x100001000F:
103 ; X64-NEXT: addq $1, %rdx # encoding: [0x48,0x83,0xc2,0x01]
104 ; X64-NEXT: movabsq $68719476751, %rax # encoding: [0x48,0xb8,0x0f,0x00,0x00,0x00,0x10,0x00,0x00,0x00]
105 ; X64-NEXT: # imm = 0x100000000F
106 ; X64-NEXT: adcq %rax, (%rdi) # encoding: [0x48,0x11,0x07]
107 ; X64-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
108 ; X64-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0]
109 ; X64-NEXT: movq %rax, (%rsi) # encoding: [0x48,0x89,0x06]
110 ; X64-NEXT: retq # encoding: [0xc3]
111 %vx = load i64, i64* %x
112 %zvx = zext i64 %vx to i192
113 %szvx = shl i192 %zvx, 64
114 %zy = zext i64 %y to i192
115 %op = or i192 %szvx, %zy
116 %zsum = add i192 %op, 1267650600504930562602346479617 ; 0x0000_0000_0000_0000__0000_0010_0000_000F__0000_0000_0000_0001
117 %ssum = lshr i192 %zsum, 64
118 %val = trunc i192 %ssum to i64
119 store i64 %val, i64* %x
120 %ssum2 = lshr i192 %zsum, 128
121 %val2 = trunc i192 %ssum2 to i64
122 store i64 %val2, i64* %x2
126 define void @adc_load_store_32_127(i32* inreg %x, i32* inreg %x2, i32 inreg %y) nounwind {
127 ; X32-LABEL: adc_load_store_32_127:
129 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01]
130 ; X32-NEXT: adcl $127, (%eax) # encoding: [0x83,0x10,0x7f]
131 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
132 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0]
133 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02]
134 ; X32-NEXT: retl # encoding: [0xc3]
136 ; X64-LABEL: adc_load_store_32_127:
138 ; X64-NEXT: movl (%rdi), %eax # encoding: [0x8b,0x07]
139 ; X64-NEXT: shlq $32, %rax # encoding: [0x48,0xc1,0xe0,0x20]
140 ; X64-NEXT: movl %edx, %ecx # encoding: [0x89,0xd1]
141 ; X64-NEXT: orq %rax, %rcx # encoding: [0x48,0x09,0xc1]
142 ; X64-NEXT: movabsq $545460846593, %rax # encoding: [0x48,0xb8,0x01,0x00,0x00,0x00,0x7f,0x00,0x00,0x00]
143 ; X64-NEXT: # imm = 0x7F00000001
144 ; X64-NEXT: xorl %edx, %edx # encoding: [0x31,0xd2]
145 ; X64-NEXT: addq %rcx, %rax # encoding: [0x48,0x01,0xc8]
146 ; X64-NEXT: setb %dl # encoding: [0x0f,0x92,0xc2]
147 ; X64-NEXT: shrq $32, %rax # encoding: [0x48,0xc1,0xe8,0x20]
148 ; X64-NEXT: movl %eax, (%rdi) # encoding: [0x89,0x07]
149 ; X64-NEXT: movl %edx, (%rsi) # encoding: [0x89,0x16]
150 ; X64-NEXT: retq # encoding: [0xc3]
151 %vx = load i32, i32* %x
152 %zvx = zext i32 %vx to i96
153 %szvx = shl i96 %zvx, 32
154 %zy = zext i32 %y to i96
155 %op = or i96 %szvx, %zy
156 %zsum = add i96 %op, 545460846593 ; 0x0000_0000__0000_007F__0000_0001
157 %ssum = lshr i96 %zsum, 32
158 %val = trunc i96 %ssum to i32
159 store i32 %val, i32* %x
160 %ssum2 = lshr i96 %zsum, 64
161 %val2 = trunc i96 %ssum2 to i32
162 store i32 %val2, i32* %x2
166 define void @adc_load_store_32_128(i32* inreg %x, i32* inreg %x2, i32 inreg %y) nounwind {
167 ; X32-LABEL: adc_load_store_32_128:
169 ; X32-NEXT: addl $1, %ecx # encoding: [0x83,0xc1,0x01]
170 ; X32-NEXT: adcl $128, (%eax) # encoding: [0x81,0x10,0x80,0x00,0x00,0x00]
171 ; X32-NEXT: setb %al # encoding: [0x0f,0x92,0xc0]
172 ; X32-NEXT: movzbl %al, %eax # encoding: [0x0f,0xb6,0xc0]
173 ; X32-NEXT: movl %eax, (%edx) # encoding: [0x89,0x02]
174 ; X32-NEXT: retl # encoding: [0xc3]
176 ; X64-LABEL: adc_load_store_32_128:
178 ; X64-NEXT: movl (%rdi), %eax # encoding: [0x8b,0x07]
179 ; X64-NEXT: shlq $32, %rax # encoding: [0x48,0xc1,0xe0,0x20]
180 ; X64-NEXT: movl %edx, %ecx # encoding: [0x89,0xd1]
181 ; X64-NEXT: orq %rax, %rcx # encoding: [0x48,0x09,0xc1]
182 ; X64-NEXT: movabsq $549755813889, %rax # encoding: [0x48,0xb8,0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00]
183 ; X64-NEXT: # imm = 0x8000000001
184 ; X64-NEXT: xorl %edx, %edx # encoding: [0x31,0xd2]
185 ; X64-NEXT: addq %rcx, %rax # encoding: [0x48,0x01,0xc8]
186 ; X64-NEXT: setb %dl # encoding: [0x0f,0x92,0xc2]
187 ; X64-NEXT: shrq $32, %rax # encoding: [0x48,0xc1,0xe8,0x20]
188 ; X64-NEXT: movl %eax, (%rdi) # encoding: [0x89,0x07]
189 ; X64-NEXT: movl %edx, (%rsi) # encoding: [0x89,0x16]
190 ; X64-NEXT: retq # encoding: [0xc3]
191 %vx = load i32, i32* %x
192 %zvx = zext i32 %vx to i96
193 %szvx = shl i96 %zvx, 32
194 %zy = zext i32 %y to i96
195 %op = or i96 %szvx, %zy
196 %zsum = add i96 %op, 549755813889 ; 0x0000_0000__0000_0080__0000_0001
197 %ssum = lshr i96 %zsum, 32
198 %val = trunc i96 %ssum to i32
199 store i32 %val, i32* %x
200 %ssum2 = lshr i96 %zsum, 64
201 %val2 = trunc i96 %ssum2 to i32
202 store i32 %val2, i32* %x2
206 ; These tests all verify the load-op-store fusion does not generate
207 ; larger instructions than mainline DAG Instruction selection.
209 define void @adc_load_store_8_15(i64 inreg %ca, i64 inreg %cb, i8* inreg %x) nounwind {
210 ; X32-LABEL: adc_load_store_8_15:
212 ; X32-NEXT: pushl %esi # encoding: [0x56]
213 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x0c]
214 ; X32-NEXT: addl %ecx, %eax # encoding: [0x01,0xc8]
215 ; X32-NEXT: adcl {{[0-9]+}}(%esp), %edx # encoding: [0x13,0x54,0x24,0x08]
216 ; X32-NEXT: adcb $15, (%esi) # encoding: [0x80,0x16,0x0f]
217 ; X32-NEXT: popl %esi # encoding: [0x5e]
218 ; X32-NEXT: retl # encoding: [0xc3]
220 ; X64-LABEL: adc_load_store_8_15:
222 ; X64-NEXT: addq %rsi, %rdi # encoding: [0x48,0x01,0xf7]
223 ; X64-NEXT: adcb $15, (%rdx) # encoding: [0x80,0x12,0x0f]
224 ; X64-NEXT: retq # encoding: [0xc3]
225 %zca = zext i64 %ca to i65
226 %zcb = zext i64 %cb to i65
227 %zc = add i65 %zca, %zcb
228 %ec = lshr i65 %zc, 64
229 %c = trunc i65 %ec to i1
230 %cc = zext i1 %c to i8
231 %vx = load i8, i8* %x
232 %cc_off = add i8 15, %cc
233 %vsum = add i8 %vx, %cc_off
234 store i8 %vsum, i8* %x
238 define void @adc_load_store_16_15(i64 inreg %ca, i64 inreg %cb, i16* inreg %x) nounwind {
239 ; X32-LABEL: adc_load_store_16_15:
241 ; X32-NEXT: pushl %esi # encoding: [0x56]
242 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x0c]
243 ; X32-NEXT: addl %ecx, %eax # encoding: [0x01,0xc8]
244 ; X32-NEXT: adcl {{[0-9]+}}(%esp), %edx # encoding: [0x13,0x54,0x24,0x08]
245 ; X32-NEXT: adcw $15, (%esi) # encoding: [0x66,0x83,0x16,0x0f]
246 ; X32-NEXT: popl %esi # encoding: [0x5e]
247 ; X32-NEXT: retl # encoding: [0xc3]
249 ; X64-LABEL: adc_load_store_16_15:
251 ; X64-NEXT: addq %rsi, %rdi # encoding: [0x48,0x01,0xf7]
252 ; X64-NEXT: adcw $15, (%rdx) # encoding: [0x66,0x83,0x12,0x0f]
253 ; X64-NEXT: retq # encoding: [0xc3]
254 %zca = zext i64 %ca to i65
255 %zcb = zext i64 %cb to i65
256 %zc = add i65 %zca, %zcb
257 %ec = lshr i65 %zc, 64
258 %c = trunc i65 %ec to i1
259 %cc = zext i1 %c to i16
260 %vx = load i16, i16* %x
261 %cc_off = add i16 15, %cc
262 %vsum = add i16 %vx, %cc_off
263 store i16 %vsum, i16* %x
267 define void @adc_load_store_16_256(i64 inreg %ca, i64 inreg %cb, i16* inreg %x) nounwind {
268 ; X32-LABEL: adc_load_store_16_256:
270 ; X32-NEXT: pushl %esi # encoding: [0x56]
271 ; X32-NEXT: movl {{[0-9]+}}(%esp), %esi # encoding: [0x8b,0x74,0x24,0x0c]
272 ; X32-NEXT: addl %ecx, %eax # encoding: [0x01,0xc8]
273 ; X32-NEXT: adcl {{[0-9]+}}(%esp), %edx # encoding: [0x13,0x54,0x24,0x08]
274 ; X32-NEXT: adcw $256, (%esi) # encoding: [0x66,0x81,0x16,0x00,0x01]
275 ; X32-NEXT: # imm = 0x100
276 ; X32-NEXT: popl %esi # encoding: [0x5e]
277 ; X32-NEXT: retl # encoding: [0xc3]
279 ; X64-LABEL: adc_load_store_16_256:
281 ; X64-NEXT: addq %rsi, %rdi # encoding: [0x48,0x01,0xf7]
282 ; X64-NEXT: adcw $256, (%rdx) # encoding: [0x66,0x81,0x12,0x00,0x01]
283 ; X64-NEXT: # imm = 0x100
284 ; X64-NEXT: retq # encoding: [0xc3]
285 %zca = zext i64 %ca to i65
286 %zcb = zext i64 %cb to i65
287 %zc = add i65 %zca, %zcb
288 %ec = lshr i65 %zc, 64
289 %c = trunc i65 %ec to i1
290 %cc = zext i1 %c to i16
291 %vx = load i16, i16* %x
292 %cc_off = add i16 256, %cc
293 %vsum = add i16 %vx, %cc_off
294 store i16 %vsum, i16* %x