[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / CodeGen / X86 / hoist-invariant-load.ll
blob5611c2068e2b506e01dbbcc0169a2a54bdf2b997
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
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
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.
17 target 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"
18 target triple = "x86_64-apple-macosx10.7.2"
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 ptr @"\01L_OBJC_METH_VAR_NAME_", 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 ptr] [ptr @"\01L_OBJC_METH_VAR_NAME_", ptr @"\01L_OBJC_SELECTOR_REFERENCES_", ptr @"\01L_OBJC_IMAGE_INFO"], section "llvm.metadata"
25 define void @test(ptr %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
61 entry:
62   br label %for.body
64 for.body:                                         ; preds = %for.body, %entry
65   %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
66   %0 = load ptr, ptr @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load !0
67   %call = tail call ptr @objc_msgSend(ptr %x, ptr %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
72 for.end:                                          ; preds = %for.body
73   ret void
76 define void @test_unordered(ptr %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
112 entry:
113   br label %for.body
115 for.body:                                         ; preds = %for.body, %entry
116   %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
117   %0 = load atomic ptr, ptr @"\01L_OBJC_SELECTOR_REFERENCES_" unordered, align 8, !invariant.load !0
118   %call = tail call ptr @objc_msgSend(ptr %x, ptr %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
123 for.end:                                          ; preds = %for.body
124   ret void
127 define void @test_volatile(ptr %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
155 entry:
156   br label %for.body
158 for.body:                                         ; preds = %for.body, %entry
159   %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
160   %0 = load volatile ptr, ptr @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load !0
161   %call = tail call ptr @objc_msgSend(ptr %x, ptr %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
166 for.end:                                          ; preds = %for.body
167   ret void
170 define void @test_seq_cst(ptr %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
198 entry:
199   br label %for.body
201 for.body:                                         ; preds = %for.body, %entry
202   %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
203   %0 = load atomic ptr, ptr @"\01L_OBJC_SELECTOR_REFERENCES_" seq_cst, align 8, !invariant.load !0
204   %call = tail call ptr @objc_msgSend(ptr %x, ptr %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
209 for.end:                                          ; preds = %for.body
210   ret void
213 declare ptr @objc_msgSend(ptr, ptr, ...) nonlazybind
215 define void @test_multi_def(ptr 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                             ptr dereferenceable(8) %x2,
237                             ptr %y, i64 %count) nounwind nofree nosync {
238 entry:
239   br label %for.body
241 for.check:
242   %inc = add nsw i64 %i, 1
243   %done = icmp sge i64 %inc, %count
244   br i1 %done, label %exit, label %for.body
246 for.body:
247   %i = phi i64 [ 0, %entry ], [ %inc, %for.check ]
248   %x1_load = load i64, ptr %x1, align 8, !invariant.load !0
249   %x1_zext = zext i64 %x1_load to i128
250   %x2_load = load i64, ptr %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, ptr %y, i64 %i
254   %y_load = load i128, ptr %y_elem, align 8
255   %y_plus = add i128 %x_prod, %y_load
256   store i128 %y_plus, ptr %y_elem, align 8
257   br label %for.check
259 exit:
260   ret void
263 define void @test_div_def(ptr 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                           ptr dereferenceable(8) %x2,
285                           ptr %y, i32 %count) nounwind nofree nosync {
286 entry:
287   br label %for.body
289 for.check:
290   %inc = add nsw i32 %i, 1
291   %done = icmp sge i32 %inc, %count
292   br i1 %done, label %exit, label %for.body
294 for.body:
295   %i = phi i32 [ 0, %entry ], [ %inc, %for.check ]
296   %x1_load = load i32, ptr %x1, align 8, !invariant.load !0
297   %x2_load = load i32, ptr %x2, align 8, !invariant.load !0
298   %x_quot = udiv i32 %x1_load, %x2_load
299   %y_elem = getelementptr inbounds i32, ptr %y, i32 %i
300   %y_load = load i32, ptr %y_elem, align 8
301   %y_plus = add i32 %x_quot, %y_load
302   store i32 %y_plus, ptr %y_elem, align 8
303   br label %for.check
305 exit:
306   ret void
309 !0 = !{}