1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=X86
3 ; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s --check-prefix=X64
5 ; Test coverage for matchAddressRecursively's MUL handling
15 ; void foo(bool b, int i) {
18 ; int j = c.m_data[i + 1].m_bar();
22 %struct.A = type { [5 x i32] }
24 define void @foo_sext_nsw(i1 zeroext, i32) nounwind {
25 ; X86-LABEL: foo_sext_nsw:
27 ; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp)
28 ; X86-NEXT: je .LBB0_1
31 ; X86-NEXT: .LBB0_1: # %.preheader
32 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
33 ; X86-NEXT: .p2align 4, 0x90
34 ; X86-NEXT: .LBB0_2: # =>This Inner Loop Header: Depth=1
35 ; X86-NEXT: leal (%eax,%eax,4), %eax
36 ; X86-NEXT: leal 20(,%eax,4), %eax
37 ; X86-NEXT: pushl %eax
38 ; X86-NEXT: calll bar@PLT
39 ; X86-NEXT: addl $4, %esp
40 ; X86-NEXT: jmp .LBB0_2
42 ; X64-LABEL: foo_sext_nsw:
44 ; X64-NEXT: pushq %rax
45 ; X64-NEXT: testl %edi, %edi
46 ; X64-NEXT: je .LBB0_1
50 ; X64-NEXT: .LBB0_1: # %.preheader
51 ; X64-NEXT: movl %esi, %eax
52 ; X64-NEXT: .p2align 4, 0x90
53 ; X64-NEXT: .LBB0_2: # =>This Inner Loop Header: Depth=1
55 ; X64-NEXT: shlq $2, %rax
56 ; X64-NEXT: leaq 20(%rax,%rax,4), %rdi
57 ; X64-NEXT: callq bar@PLT
58 ; X64-NEXT: jmp .LBB0_2
59 br i1 %0, label %9, label %3
61 %4 = phi i32 [ %8, %3 ], [ %1, %2 ]
62 %5 = add nsw i32 %4, 1
63 %6 = sext i32 %5 to i64
64 %7 = getelementptr inbounds %struct.A, ptr null, i64 %6
65 %8 = tail call i32 @bar(ptr %7)
71 define void @foo_sext_nuw(i1 zeroext, i32) nounwind {
72 ; X86-LABEL: foo_sext_nuw:
74 ; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp)
75 ; X86-NEXT: je .LBB1_1
78 ; X86-NEXT: .LBB1_1: # %.preheader
79 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
80 ; X86-NEXT: .p2align 4, 0x90
81 ; X86-NEXT: .LBB1_2: # =>This Inner Loop Header: Depth=1
82 ; X86-NEXT: leal (%eax,%eax,4), %eax
83 ; X86-NEXT: leal 20(,%eax,4), %eax
84 ; X86-NEXT: pushl %eax
85 ; X86-NEXT: calll bar@PLT
86 ; X86-NEXT: addl $4, %esp
87 ; X86-NEXT: jmp .LBB1_2
89 ; X64-LABEL: foo_sext_nuw:
91 ; X64-NEXT: pushq %rax
92 ; X64-NEXT: testl %edi, %edi
93 ; X64-NEXT: je .LBB1_1
97 ; X64-NEXT: .LBB1_1: # %.preheader
98 ; X64-NEXT: movl %esi, %eax
99 ; X64-NEXT: .p2align 4, 0x90
100 ; X64-NEXT: .LBB1_2: # =>This Inner Loop Header: Depth=1
101 ; X64-NEXT: incl %eax
103 ; X64-NEXT: shlq $2, %rax
104 ; X64-NEXT: leaq (%rax,%rax,4), %rdi
105 ; X64-NEXT: callq bar@PLT
106 ; X64-NEXT: jmp .LBB1_2
107 br i1 %0, label %9, label %3
109 %4 = phi i32 [ %8, %3 ], [ %1, %2 ]
110 %5 = add nuw i32 %4, 1
111 %6 = sext i32 %5 to i64
112 %7 = getelementptr inbounds %struct.A, ptr null, i64 %6
113 %8 = tail call i32 @bar(ptr %7)
119 define void @foo_zext_nsw(i1 zeroext, i32) nounwind {
120 ; X86-LABEL: foo_zext_nsw:
122 ; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp)
123 ; X86-NEXT: je .LBB2_1
126 ; X86-NEXT: .LBB2_1: # %.preheader
127 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
128 ; X86-NEXT: .p2align 4, 0x90
129 ; X86-NEXT: .LBB2_2: # =>This Inner Loop Header: Depth=1
130 ; X86-NEXT: leal (%eax,%eax,4), %eax
131 ; X86-NEXT: leal 20(,%eax,4), %eax
132 ; X86-NEXT: pushl %eax
133 ; X86-NEXT: calll bar@PLT
134 ; X86-NEXT: addl $4, %esp
135 ; X86-NEXT: jmp .LBB2_2
137 ; X64-LABEL: foo_zext_nsw:
139 ; X64-NEXT: pushq %rax
140 ; X64-NEXT: testl %edi, %edi
141 ; X64-NEXT: je .LBB2_1
143 ; X64-NEXT: popq %rax
145 ; X64-NEXT: .LBB2_1: # %.preheader
146 ; X64-NEXT: movl %esi, %eax
147 ; X64-NEXT: .p2align 4, 0x90
148 ; X64-NEXT: .LBB2_2: # =>This Inner Loop Header: Depth=1
149 ; X64-NEXT: incl %eax
150 ; X64-NEXT: shlq $2, %rax
151 ; X64-NEXT: leaq (%rax,%rax,4), %rdi
152 ; X64-NEXT: callq bar@PLT
153 ; X64-NEXT: # kill: def $eax killed $eax def $rax
154 ; X64-NEXT: jmp .LBB2_2
155 br i1 %0, label %9, label %3
157 %4 = phi i32 [ %8, %3 ], [ %1, %2 ]
158 %5 = add nsw i32 %4, 1
159 %6 = zext i32 %5 to i64
160 %7 = getelementptr inbounds %struct.A, ptr null, i64 %6
161 %8 = tail call i32 @bar(ptr %7)
167 define void @foo_zext_nuw(i1 zeroext, i32) nounwind {
168 ; X86-LABEL: foo_zext_nuw:
170 ; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp)
171 ; X86-NEXT: je .LBB3_1
174 ; X86-NEXT: .LBB3_1: # %.preheader
175 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
176 ; X86-NEXT: .p2align 4, 0x90
177 ; X86-NEXT: .LBB3_2: # =>This Inner Loop Header: Depth=1
178 ; X86-NEXT: leal (%eax,%eax,4), %eax
179 ; X86-NEXT: leal 20(,%eax,4), %eax
180 ; X86-NEXT: pushl %eax
181 ; X86-NEXT: calll bar@PLT
182 ; X86-NEXT: addl $4, %esp
183 ; X86-NEXT: jmp .LBB3_2
185 ; X64-LABEL: foo_zext_nuw:
187 ; X64-NEXT: pushq %rax
188 ; X64-NEXT: testl %edi, %edi
189 ; X64-NEXT: je .LBB3_1
191 ; X64-NEXT: popq %rax
193 ; X64-NEXT: .LBB3_1: # %.preheader
194 ; X64-NEXT: movl %esi, %eax
195 ; X64-NEXT: .p2align 4, 0x90
196 ; X64-NEXT: .LBB3_2: # =>This Inner Loop Header: Depth=1
197 ; X64-NEXT: movl %eax, %eax
198 ; X64-NEXT: shlq $2, %rax
199 ; X64-NEXT: leaq 20(%rax,%rax,4), %rdi
200 ; X64-NEXT: callq bar@PLT
201 ; X64-NEXT: jmp .LBB3_2
202 br i1 %0, label %9, label %3
204 %4 = phi i32 [ %8, %3 ], [ %1, %2 ]
205 %5 = add nuw i32 %4, 1
206 %6 = zext i32 %5 to i64
207 %7 = getelementptr inbounds %struct.A, ptr null, i64 %6
208 %8 = tail call i32 @bar(ptr %7)
214 define void @foo_sext(i1 zeroext, i32) nounwind {
215 ; X86-LABEL: foo_sext:
217 ; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp)
218 ; X86-NEXT: je .LBB4_1
221 ; X86-NEXT: .LBB4_1: # %.preheader
222 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
223 ; X86-NEXT: .p2align 4, 0x90
224 ; X86-NEXT: .LBB4_2: # =>This Inner Loop Header: Depth=1
225 ; X86-NEXT: leal (%eax,%eax,4), %eax
226 ; X86-NEXT: leal 20(,%eax,4), %eax
227 ; X86-NEXT: pushl %eax
228 ; X86-NEXT: calll bar@PLT
229 ; X86-NEXT: addl $4, %esp
230 ; X86-NEXT: jmp .LBB4_2
232 ; X64-LABEL: foo_sext:
234 ; X64-NEXT: pushq %rax
235 ; X64-NEXT: testl %edi, %edi
236 ; X64-NEXT: je .LBB4_1
238 ; X64-NEXT: popq %rax
240 ; X64-NEXT: .LBB4_1: # %.preheader
241 ; X64-NEXT: movl %esi, %eax
242 ; X64-NEXT: .p2align 4, 0x90
243 ; X64-NEXT: .LBB4_2: # =>This Inner Loop Header: Depth=1
244 ; X64-NEXT: incl %eax
246 ; X64-NEXT: shlq $2, %rax
247 ; X64-NEXT: leaq (%rax,%rax,4), %rdi
248 ; X64-NEXT: callq bar@PLT
249 ; X64-NEXT: jmp .LBB4_2
250 br i1 %0, label %9, label %3
252 %4 = phi i32 [ %8, %3 ], [ %1, %2 ]
254 %6 = sext i32 %5 to i64
255 %7 = getelementptr inbounds %struct.A, ptr null, i64 %6
256 %8 = tail call i32 @bar(ptr %7)
262 define void @foo_zext(i1 zeroext, i32) nounwind {
263 ; X86-LABEL: foo_zext:
265 ; X86-NEXT: cmpb $0, {{[0-9]+}}(%esp)
266 ; X86-NEXT: je .LBB5_1
269 ; X86-NEXT: .LBB5_1: # %.preheader
270 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
271 ; X86-NEXT: .p2align 4, 0x90
272 ; X86-NEXT: .LBB5_2: # =>This Inner Loop Header: Depth=1
273 ; X86-NEXT: leal (%eax,%eax,4), %eax
274 ; X86-NEXT: leal 20(,%eax,4), %eax
275 ; X86-NEXT: pushl %eax
276 ; X86-NEXT: calll bar@PLT
277 ; X86-NEXT: addl $4, %esp
278 ; X86-NEXT: jmp .LBB5_2
280 ; X64-LABEL: foo_zext:
282 ; X64-NEXT: pushq %rax
283 ; X64-NEXT: testl %edi, %edi
284 ; X64-NEXT: je .LBB5_1
286 ; X64-NEXT: popq %rax
288 ; X64-NEXT: .LBB5_1: # %.preheader
289 ; X64-NEXT: movl %esi, %eax
290 ; X64-NEXT: .p2align 4, 0x90
291 ; X64-NEXT: .LBB5_2: # =>This Inner Loop Header: Depth=1
292 ; X64-NEXT: incl %eax
293 ; X64-NEXT: shlq $2, %rax
294 ; X64-NEXT: leaq (%rax,%rax,4), %rdi
295 ; X64-NEXT: callq bar@PLT
296 ; X64-NEXT: # kill: def $eax killed $eax def $rax
297 ; X64-NEXT: jmp .LBB5_2
298 br i1 %0, label %9, label %3
300 %4 = phi i32 [ %8, %3 ], [ %1, %2 ]
302 %6 = zext i32 %5 to i64
303 %7 = getelementptr inbounds %struct.A, ptr null, i64 %6
304 %8 = tail call i32 @bar(ptr %7)
310 declare i32 @bar(ptr)