1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2
3; Verify the call site info. If the call site info is not
4; in the valid state, an assert should be triggered.
5; RUN: llc < %s -debug-entry-values -stop-after=machineverifier
6
7; REQUIRES: asserts
8; RUN: llc -mcpu=haswell < %s -O2 2>&1 | FileCheck %s
9; For test:
10; 2 invariant loads, 1 for OBJC_SELECTOR_REFERENCES_
11; and 1 for objc_msgSend from the GOT
12; For test_multi_def:
13; 2 invariant load (full multiply, both loads should be hoisted.)
14; For test_div_def:
15; 2 invariant load (full divide, both loads should be hoisted.) 1 additional instruction for a zeroing edx that gets hoisted and then rematerialized.
16
17target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
18target triple = "x86_64-apple-macosx10.7.2"
19
20@"\01L_OBJC_METH_VAR_NAME_" = internal global [4 x i8] c"foo\00", section "__TEXT,__objc_methname,cstring_literals", align 1
21@"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
22@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
23@llvm.used = appending global [3 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i32 0, i32 0), i8* bitcast (i8** @"\01L_OBJC_SELECTOR_REFERENCES_" to i8*), i8* bitcast ([2 x i32]* @"\01L_OBJC_IMAGE_INFO" to i8*)], section "llvm.metadata"
24
25define void @test(i8* %x) uwtable ssp {
26; CHECK-LABEL: test:
27; CHECK:       ## %bb.0: ## %entry
28; CHECK-NEXT:    pushq %rbp
29; CHECK-NEXT:    .cfi_def_cfa_offset 16
30; CHECK-NEXT:    pushq %r15
31; CHECK-NEXT:    .cfi_def_cfa_offset 24
32; CHECK-NEXT:    pushq %r14
33; CHECK-NEXT:    .cfi_def_cfa_offset 32
34; CHECK-NEXT:    pushq %rbx
35; CHECK-NEXT:    .cfi_def_cfa_offset 40
36; CHECK-NEXT:    pushq %rax
37; CHECK-NEXT:    .cfi_def_cfa_offset 48
38; CHECK-NEXT:    .cfi_offset %rbx, -40
39; CHECK-NEXT:    .cfi_offset %r14, -32
40; CHECK-NEXT:    .cfi_offset %r15, -24
41; CHECK-NEXT:    .cfi_offset %rbp, -16
42; CHECK-NEXT:    movq %rdi, %rbx
43; CHECK-NEXT:    movl $10000, %ebp ## imm = 0x2710
44; CHECK-NEXT:    movq L_OBJC_SELECTOR_REFERENCES_(%rip), %r14
45; CHECK-NEXT:    movq _objc_msgSend@GOTPCREL(%rip), %r15
46; CHECK-NEXT:    .p2align 4, 0x90
47; CHECK-NEXT:  LBB0_1: ## %for.body
48; CHECK-NEXT:    ## =>This Inner Loop Header: Depth=1
49; CHECK-NEXT:    movq %rbx, %rdi
50; CHECK-NEXT:    movq %r14, %rsi
51; CHECK-NEXT:    callq *%r15
52; CHECK-NEXT:    decl %ebp
53; CHECK-NEXT:    jne LBB0_1
54; CHECK-NEXT:  ## %bb.2: ## %for.end
55; CHECK-NEXT:    addq $8, %rsp
56; CHECK-NEXT:    popq %rbx
57; CHECK-NEXT:    popq %r14
58; CHECK-NEXT:    popq %r15
59; CHECK-NEXT:    popq %rbp
60; CHECK-NEXT:    retq
61entry:
62  br label %for.body
63
64for.body:                                         ; preds = %for.body, %entry
65  %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
66  %0 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load !0
67  %call = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %x, i8* %0)
68  %inc = add i32 %i.01, 1
69  %exitcond = icmp eq i32 %inc, 10000
70  br i1 %exitcond, label %for.end, label %for.body
71
72for.end:                                          ; preds = %for.body
73  ret void
74}
75
76define void @test_unordered(i8* %x) uwtable ssp {
77; CHECK-LABEL: test_unordered:
78; CHECK:       ## %bb.0: ## %entry
79; CHECK-NEXT:    pushq %rbp
80; CHECK-NEXT:    .cfi_def_cfa_offset 16
81; CHECK-NEXT:    pushq %r15
82; CHECK-NEXT:    .cfi_def_cfa_offset 24
83; CHECK-NEXT:    pushq %r14
84; CHECK-NEXT:    .cfi_def_cfa_offset 32
85; CHECK-NEXT:    pushq %rbx
86; CHECK-NEXT:    .cfi_def_cfa_offset 40
87; CHECK-NEXT:    pushq %rax
88; CHECK-NEXT:    .cfi_def_cfa_offset 48
89; CHECK-NEXT:    .cfi_offset %rbx, -40
90; CHECK-NEXT:    .cfi_offset %r14, -32
91; CHECK-NEXT:    .cfi_offset %r15, -24
92; CHECK-NEXT:    .cfi_offset %rbp, -16
93; CHECK-NEXT:    movq %rdi, %rbx
94; CHECK-NEXT:    movl $10000, %ebp ## imm = 0x2710
95; CHECK-NEXT:    movq L_OBJC_SELECTOR_REFERENCES_(%rip), %r14
96; CHECK-NEXT:    movq _objc_msgSend@GOTPCREL(%rip), %r15
97; CHECK-NEXT:    .p2align 4, 0x90
98; CHECK-NEXT:  LBB1_1: ## %for.body
99; CHECK-NEXT:    ## =>This Inner Loop Header: Depth=1
100; CHECK-NEXT:    movq %rbx, %rdi
101; CHECK-NEXT:    movq %r14, %rsi
102; CHECK-NEXT:    callq *%r15
103; CHECK-NEXT:    decl %ebp
104; CHECK-NEXT:    jne LBB1_1
105; CHECK-NEXT:  ## %bb.2: ## %for.end
106; CHECK-NEXT:    addq $8, %rsp
107; CHECK-NEXT:    popq %rbx
108; CHECK-NEXT:    popq %r14
109; CHECK-NEXT:    popq %r15
110; CHECK-NEXT:    popq %rbp
111; CHECK-NEXT:    retq
112entry:
113  br label %for.body
114
115for.body:                                         ; preds = %for.body, %entry
116  %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
117  %0 = load atomic i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_" unordered, align 8, !invariant.load !0
118  %call = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %x, i8* %0)
119  %inc = add i32 %i.01, 1
120  %exitcond = icmp eq i32 %inc, 10000
121  br i1 %exitcond, label %for.end, label %for.body
122
123for.end:                                          ; preds = %for.body
124  ret void
125}
126
127define void @test_volatile(i8* %x) uwtable ssp {
128; CHECK-LABEL: test_volatile:
129; CHECK:       ## %bb.0: ## %entry
130; CHECK-NEXT:    pushq %rbp
131; CHECK-NEXT:    .cfi_def_cfa_offset 16
132; CHECK-NEXT:    pushq %r14
133; CHECK-NEXT:    .cfi_def_cfa_offset 24
134; CHECK-NEXT:    pushq %rbx
135; CHECK-NEXT:    .cfi_def_cfa_offset 32
136; CHECK-NEXT:    .cfi_offset %rbx, -32
137; CHECK-NEXT:    .cfi_offset %r14, -24
138; CHECK-NEXT:    .cfi_offset %rbp, -16
139; CHECK-NEXT:    movq %rdi, %rbx
140; CHECK-NEXT:    movl $10000, %ebp ## imm = 0x2710
141; CHECK-NEXT:    movq _objc_msgSend@GOTPCREL(%rip), %r14
142; CHECK-NEXT:    .p2align 4, 0x90
143; CHECK-NEXT:  LBB2_1: ## %for.body
144; CHECK-NEXT:    ## =>This Inner Loop Header: Depth=1
145; CHECK-NEXT:    movq L_OBJC_SELECTOR_REFERENCES_(%rip), %rsi
146; CHECK-NEXT:    movq %rbx, %rdi
147; CHECK-NEXT:    callq *%r14
148; CHECK-NEXT:    decl %ebp
149; CHECK-NEXT:    jne LBB2_1
150; CHECK-NEXT:  ## %bb.2: ## %for.end
151; CHECK-NEXT:    popq %rbx
152; CHECK-NEXT:    popq %r14
153; CHECK-NEXT:    popq %rbp
154; CHECK-NEXT:    retq
155entry:
156  br label %for.body
157
158for.body:                                         ; preds = %for.body, %entry
159  %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
160  %0 = load volatile i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load !0
161  %call = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %x, i8* %0)
162  %inc = add i32 %i.01, 1
163  %exitcond = icmp eq i32 %inc, 10000
164  br i1 %exitcond, label %for.end, label %for.body
165
166for.end:                                          ; preds = %for.body
167  ret void
168}
169
170define void @test_seq_cst(i8* %x) uwtable ssp {
171; CHECK-LABEL: test_seq_cst:
172; CHECK:       ## %bb.0: ## %entry
173; CHECK-NEXT:    pushq %rbp
174; CHECK-NEXT:    .cfi_def_cfa_offset 16
175; CHECK-NEXT:    pushq %r14
176; CHECK-NEXT:    .cfi_def_cfa_offset 24
177; CHECK-NEXT:    pushq %rbx
178; CHECK-NEXT:    .cfi_def_cfa_offset 32
179; CHECK-NEXT:    .cfi_offset %rbx, -32
180; CHECK-NEXT:    .cfi_offset %r14, -24
181; CHECK-NEXT:    .cfi_offset %rbp, -16
182; CHECK-NEXT:    movq %rdi, %rbx
183; CHECK-NEXT:    movl $10000, %ebp ## imm = 0x2710
184; CHECK-NEXT:    movq _objc_msgSend@GOTPCREL(%rip), %r14
185; CHECK-NEXT:    .p2align 4, 0x90
186; CHECK-NEXT:  LBB3_1: ## %for.body
187; CHECK-NEXT:    ## =>This Inner Loop Header: Depth=1
188; CHECK-NEXT:    movq L_OBJC_SELECTOR_REFERENCES_(%rip), %rsi
189; CHECK-NEXT:    movq %rbx, %rdi
190; CHECK-NEXT:    callq *%r14
191; CHECK-NEXT:    decl %ebp
192; CHECK-NEXT:    jne LBB3_1
193; CHECK-NEXT:  ## %bb.2: ## %for.end
194; CHECK-NEXT:    popq %rbx
195; CHECK-NEXT:    popq %r14
196; CHECK-NEXT:    popq %rbp
197; CHECK-NEXT:    retq
198entry:
199  br label %for.body
200
201for.body:                                         ; preds = %for.body, %entry
202  %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
203  %0 = load atomic i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_" seq_cst, align 8, !invariant.load !0
204  %call = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %x, i8* %0)
205  %inc = add i32 %i.01, 1
206  %exitcond = icmp eq i32 %inc, 10000
207  br i1 %exitcond, label %for.end, label %for.body
208
209for.end:                                          ; preds = %for.body
210  ret void
211}
212
213declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
214
215define void @test_multi_def(i64* dereferenceable(8) %x1,
216; CHECK-LABEL: test_multi_def:
217; CHECK:       ## %bb.0: ## %entry
218; CHECK-NEXT:    movq %rdx, %rax
219; CHECK-NEXT:    xorl %r8d, %r8d
220; CHECK-NEXT:    movq (%rdi), %rdx
221; CHECK-NEXT:    movq (%rsi), %r9
222; CHECK-NEXT:    .p2align 4, 0x90
223; CHECK-NEXT:  LBB4_2: ## %for.body
224; CHECK-NEXT:    ## =>This Inner Loop Header: Depth=1
225; CHECK-NEXT:    mulxq %r9, %rsi, %rdi
226; CHECK-NEXT:    addq %rsi, (%rax)
227; CHECK-NEXT:    adcq %rdi, 8(%rax)
228; CHECK-NEXT:  ## %bb.1: ## %for.check
229; CHECK-NEXT:    ## in Loop: Header=BB4_2 Depth=1
230; CHECK-NEXT:    incq %r8
231; CHECK-NEXT:    addq $16, %rax
232; CHECK-NEXT:    cmpq %rcx, %r8
233; CHECK-NEXT:    jl LBB4_2
234; CHECK-NEXT:  ## %bb.3: ## %exit
235; CHECK-NEXT:    retq
236                            i64* dereferenceable(8) %x2,
237                            i128* %y, i64 %count) nounwind nofree nosync {
238entry:
239  br label %for.body
240
241for.check:
242  %inc = add nsw i64 %i, 1
243  %done = icmp sge i64 %inc, %count
244  br i1 %done, label %exit, label %for.body
245
246for.body:
247  %i = phi i64 [ 0, %entry ], [ %inc, %for.check ]
248  %x1_load = load i64, i64* %x1, align 8, !invariant.load !0
249  %x1_zext = zext i64 %x1_load to i128
250  %x2_load = load i64, i64* %x2, align 8, !invariant.load !0
251  %x2_zext = zext i64 %x2_load to i128
252  %x_prod = mul i128 %x1_zext, %x2_zext
253  %y_elem = getelementptr inbounds i128, i128* %y, i64 %i
254  %y_load = load i128, i128* %y_elem, align 8
255  %y_plus = add i128 %x_prod, %y_load
256  store i128 %y_plus, i128* %y_elem, align 8
257  br label %for.check
258
259exit:
260  ret void
261}
262
263define void @test_div_def(i32* dereferenceable(8) %x1,
264; CHECK-LABEL: test_div_def:
265; CHECK:       ## %bb.0: ## %entry
266; CHECK-NEXT:    movq %rdx, %r8
267; CHECK-NEXT:    xorl %r9d, %r9d
268; CHECK-NEXT:    movl (%rdi), %edi
269; CHECK-NEXT:    movl (%rsi), %esi
270; CHECK-NEXT:    .p2align 4, 0x90
271; CHECK-NEXT:  LBB5_2: ## %for.body
272; CHECK-NEXT:    ## =>This Inner Loop Header: Depth=1
273; CHECK-NEXT:    movl %edi, %eax
274; CHECK-NEXT:    xorl %edx, %edx
275; CHECK-NEXT:    divl %esi
276; CHECK-NEXT:    addl %eax, (%r8,%r9,4)
277; CHECK-NEXT:  ## %bb.1: ## %for.check
278; CHECK-NEXT:    ## in Loop: Header=BB5_2 Depth=1
279; CHECK-NEXT:    incq %r9
280; CHECK-NEXT:    cmpl %ecx, %r9d
281; CHECK-NEXT:    jl LBB5_2
282; CHECK-NEXT:  ## %bb.3: ## %exit
283; CHECK-NEXT:    retq
284                          i32* dereferenceable(8) %x2,
285                          i32* %y, i32 %count) nounwind nofree nosync {
286entry:
287  br label %for.body
288
289for.check:
290  %inc = add nsw i32 %i, 1
291  %done = icmp sge i32 %inc, %count
292  br i1 %done, label %exit, label %for.body
293
294for.body:
295  %i = phi i32 [ 0, %entry ], [ %inc, %for.check ]
296  %x1_load = load i32, i32* %x1, align 8, !invariant.load !0
297  %x2_load = load i32, i32* %x2, align 8, !invariant.load !0
298  %x_quot = udiv i32 %x1_load, %x2_load
299  %y_elem = getelementptr inbounds i32, i32* %y, i32 %i
300  %y_load = load i32, i32* %y_elem, align 8
301  %y_plus = add i32 %x_quot, %y_load
302  store i32 %y_plus, i32* %y_elem, align 8
303  br label %for.check
304
305exit:
306  ret void
307}
308
309!0 = !{}
310