fabea5ebcbfa237d1937b83a00eeadb1aad36439
[oota-llvm.git] / test / CodeGen / MIR / X86 / memory-operands.mir
1 # RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
2 # This test ensures that the MIR parser parses the machine memory operands
3 # correctly.
4
5 --- |
6
7   define i32 @test(i32* %a) {
8   entry:
9     %b = load i32, i32* %a
10     store i32 42, i32* %a
11     ret i32 %b
12   }
13
14   define void @test2(i32* %"a value") {
15   entry2:
16     %b = load i32, i32* %"a value"
17     %c = add i32 %b, 1
18     store i32 %c, i32* %"a value"
19     ret void
20   }
21
22   define i32 @volatile_inc(i32* %x) {
23   entry:
24     %0 = load volatile i32, i32* %x
25     %1 = add i32 %0, 1
26     store volatile i32 %1, i32* %x
27     ret i32 %1
28   }
29
30   define void @non_temporal_store(i32* %a, i32 %b) {
31   entry:
32     store i32 %b, i32* %a, align 16, !nontemporal !0
33     ret void
34   }
35
36   !0 = !{i32 1}
37
38   define i32 @invariant_load(i32* %x) {
39   entry:
40     %v = load i32, i32* %x, !invariant.load !1
41     ret i32 %v
42   }
43
44   !1 = !{}
45
46   define void @memory_offset(<8 x float>* %vec) {
47   entry:
48     %v = load <8 x float>, <8 x float>* %vec
49     %v2 = insertelement <8 x float> %v, float 0.0, i32 4
50     store <8 x float> %v2, <8 x float>* %vec
51     ret void
52   }
53
54   define void @memory_alignment(<8 x float>* %vec) {
55   entry:
56     %v = load <8 x float>, <8 x float>* %vec
57     %v2 = insertelement <8 x float> %v, float 0.0, i32 4
58     store <8 x float> %v2, <8 x float>* %vec
59     ret void
60   }
61
62   define double @constant_pool_psv(double %a) {
63   entry:
64     %b = fadd double %a, 3.250000e+00
65     ret double %b
66   }
67
68   declare x86_fp80 @cosl(x86_fp80) #0
69
70   define x86_fp80 @stack_psv(x86_fp80 %x) {
71   entry:
72     %y = call x86_fp80 @cosl(x86_fp80 %x) #0
73     ret x86_fp80 %y
74   }
75
76   attributes #0 = { readonly }
77
78   @G = external global i32
79
80   define i32 @got_psv() {
81   entry:
82     %a = load i32, i32* @G
83     %b = add i32 %a, 1
84     ret i32 %b
85   }
86
87   define i32 @global_value() {
88   entry:
89     %a = load i32, i32* @G
90     %b = add i32 %a, 1
91     ret i32 %b
92   }
93
94   define i32 @jumptable_psv(i32 %in) {
95   entry:
96     switch i32 %in, label %def [
97       i32 0, label %lbl1
98       i32 1, label %lbl2
99       i32 2, label %lbl3
100       i32 3, label %lbl4
101     ]
102   def:
103     ret i32 0
104   lbl1:
105     ret i32 1
106   lbl2:
107     ret i32 2
108   lbl3:
109     ret i32 4
110   lbl4:
111     ret i32 8
112   }
113
114   %struct.XXH_state64_t = type { i32, i32, i64, i64, i64 }
115
116   @a = common global i32 0, align 4
117
118   define i32 @tbaa_metadata() {
119   entry:
120     %0 = load i32, i32* @a, align 4, !tbaa !2
121     %1 = inttoptr i32 %0 to %struct.XXH_state64_t*
122     %total_len2 = bitcast %struct.XXH_state64_t* %1 to i32*
123     %2 = load i32, i32* %total_len2, align 4, !tbaa !6
124     ret i32 %2
125   }
126
127   !2 = !{!3, !3, i64 0}
128   !3 = !{!"int", !4, i64 0}
129   !4 = !{!"omnipotent char", !5, i64 0}
130   !5 = !{!"Simple C/C++ TBAA"}
131   !6 = !{!7, !3, i64 0}
132   !7 = !{!"XXH_state64_t", !3, i64 0, !3, i64 4, !8, i64 8, !8, i64 16, !8, i64 24}
133   !8 = !{!"long long", !4, i64 0}
134
135   define void @aa_scope(float* nocapture %a, float* nocapture readonly %c) #1 {
136   entry:
137     %0 = load float, float* %c, align 4, !alias.scope !9
138     %arrayidx.i = getelementptr inbounds float, float* %a, i64 5
139     store float %0, float* %arrayidx.i, align 4, !noalias !9
140     %1 = load float, float* %c, align 4
141     %arrayidx = getelementptr inbounds float, float* %a, i64 7
142     store float %1, float* %arrayidx, align 4
143     ret void
144   }
145
146   attributes #1 = { nounwind uwtable }
147
148   !9 = distinct !{!9, !10, !"some scope"}
149   !10 = distinct !{!10, !"some domain"}
150
151   define zeroext i1 @range_metadata(i8* %x) {
152   entry:
153     %0 = load i8, i8* %x, align 1, !range !11
154     %tobool = trunc i8 %0 to i1
155     ret i1 %tobool
156   }
157
158   !11 = !{i8 0, i8 2}
159
160 ...
161 ---
162 name:            test
163 tracksRegLiveness: true
164 liveins:
165   - { reg: '%rdi' }
166 body: |
167   bb.0.entry:
168     liveins: %rdi
169   ; CHECK:      %eax = MOV32rm %rdi, 1, _, 0, _ :: (load 4 from %ir.a)
170   ; CHECK-NEXT: MOV32mi killed %rdi, 1, _, 0, _, 42 :: (store 4 into %ir.a)
171     %eax = MOV32rm %rdi, 1, _, 0, _ :: (load 4 from %ir.a)
172     MOV32mi killed %rdi, 1, _, 0, _, 42 :: (store 4 into %ir.a)
173     RETQ %eax
174 ...
175 ---
176 name:            test2
177 tracksRegLiveness: true
178 liveins:
179   - { reg: '%rdi' }
180 body: |
181   bb.0.entry2:
182     liveins: %rdi
183   ; CHECK: INC32m killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (store 4 into %ir."a value"), (load 4 from %ir."a value")
184     INC32m killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (store 4 into %ir."a value"), (load 4 from %ir."a value")
185     RETQ
186 ...
187 ---
188 name:            volatile_inc
189 tracksRegLiveness: true
190 liveins:
191   - { reg: '%rdi' }
192 body: |
193   bb.0.entry:
194     liveins: %rdi
195     ; CHECK: name: volatile_inc
196     ; CHECK: %eax = MOV32rm %rdi, 1, _, 0, _ :: (volatile load 4 from %ir.x)
197     ; CHECK: MOV32mr killed %rdi, 1, _, 0, _, %eax :: (volatile store 4 into %ir.x)
198     %eax = MOV32rm %rdi, 1, _, 0, _ :: (volatile load 4 from %ir.x)
199     %eax = INC32r killed %eax, implicit-def dead %eflags
200     MOV32mr killed %rdi, 1, _, 0, _, %eax :: (volatile store 4 into %ir.x)
201     RETQ %eax
202 ...
203 ---
204 name:            non_temporal_store
205 tracksRegLiveness: true
206 liveins:
207   - { reg: '%rdi' }
208   - { reg: '%esi' }
209 body: |
210   bb.0.entry:
211     liveins: %esi, %rdi
212   ; CHECK: name: non_temporal_store
213   ; CHECK: MOVNTImr killed %rdi, 1, _, 0, _, killed %esi :: (non-temporal store 4 into %ir.a)
214     MOVNTImr killed %rdi, 1, _, 0, _, killed %esi :: (non-temporal store 4 into %ir.a)
215     RETQ
216 ...
217 ---
218 name:            invariant_load
219 tracksRegLiveness: true
220 liveins:
221   - { reg: '%rdi' }
222 body: |
223   bb.0.entry:
224     liveins: %rdi
225   ; CHECK: name: invariant_load
226   ; CHECK: %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (invariant load 4 from %ir.x)
227     %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (invariant load 4 from %ir.x)
228     RETQ %eax
229 ...
230 ---
231 name:            memory_offset
232 tracksRegLiveness: true
233 liveins:
234   - { reg: '%rdi' }
235 body: |
236   bb.0.entry:
237     liveins: %rdi
238   ; CHECK: name: memory_offset
239   ; CHECK:      %xmm0 = MOVAPSrm %rdi, 1, _, 0, _ :: (load 16 from %ir.vec)
240   ; CHECK-NEXT: %xmm1 = MOVAPSrm %rdi, 1, _, 16, _ :: (load 16 from %ir.vec + 16)
241   ; CHECK:      MOVAPSmr %rdi, 1, _, 0, _, killed %xmm0 :: (store 16 into %ir.vec)
242   ; CHECK-NEXT: MOVAPSmr killed %rdi, 1, _, 16, _, killed %xmm1 :: (store 16 into %ir.vec + 16)
243     %xmm0 = MOVAPSrm %rdi, 1, _, 0, _ :: (load 16 from %ir.vec)
244     %xmm1 = MOVAPSrm %rdi, 1, _, 16, _ :: (load 16 from %ir.vec + 16)
245     %xmm2 = FsFLD0SS
246     %xmm1 = MOVSSrr killed %xmm1, killed %xmm2
247     MOVAPSmr %rdi, 1, _, 0, _, killed %xmm0 :: (store 16 into %ir.vec)
248     MOVAPSmr killed %rdi, 1, _, 16, _, killed %xmm1 :: (store 16 into %ir.vec + 16)
249     RETQ
250 ...
251 ---
252 name:            memory_alignment
253 tracksRegLiveness: true
254 liveins:
255   - { reg: '%rdi' }
256 body: |
257   bb.0.entry:
258     liveins: %rdi
259   ; CHECK: name: memory_alignment
260   ; CHECK:      %xmm0 = MOVAPSrm %rdi, 1, _, 0, _ :: (load 16 from %ir.vec, align 32)
261   ; CHECK-NEXT: %xmm1 = MOVAPSrm %rdi, 1, _, 16, _ :: (load 16 from %ir.vec + 16, align 32)
262   ; CHECK:      MOVAPSmr %rdi, 1, _, 0, _, killed %xmm0 :: (store 16 into %ir.vec, align 32)
263   ; CHECK-NEXT: MOVAPSmr killed %rdi, 1, _, 16, _, killed %xmm1 :: (store 16 into %ir.vec + 16, align 32)
264     %xmm0 = MOVAPSrm %rdi, 1, _, 0, _ :: (load 16 from %ir.vec, align 32)
265     %xmm1 = MOVAPSrm %rdi, 1, _, 16, _ :: (load 16 from %ir.vec + 16, align 32)
266     %xmm2 = FsFLD0SS
267     %xmm1 = MOVSSrr killed %xmm1, killed %xmm2
268     MOVAPSmr %rdi, 1, _, 0, _, killed %xmm0 :: (store 16 into %ir.vec, align 32)
269     MOVAPSmr killed %rdi, 1, _, 16, _, killed %xmm1 :: (store 16 into %ir.vec + 16, align 32)
270     RETQ
271 ...
272 ---
273 name:            constant_pool_psv
274 tracksRegLiveness: true
275 liveins:
276   - { reg: '%xmm0' }
277 constants:
278   - id:          0
279     value:       'double 3.250000e+00'
280 body: |
281   bb.0.entry:
282     liveins: %xmm0
283   ; CHECK: name: constant_pool_psv
284   ; CHECK:      %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _ :: (load 8 from constant-pool)
285   ; CHECK-NEXT: %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _ :: (load 8 from constant-pool + 8)
286     %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _ :: (load 8 from constant-pool)
287     %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _ :: (load 8 from constant-pool + 8)
288     RETQ %xmm0
289 ...
290 ---
291 name:            stack_psv
292 tracksRegLiveness: true
293 frameInfo:
294   stackSize:       24
295   maxAlignment:    16
296   adjustsStack:    true
297   hasCalls:        true
298   maxCallFrameSize: 16
299 fixedStack:
300   - { id: 0, offset: 0, size: 10, alignment: 16, isImmutable: true, isAliased: false }
301 body: |
302   bb.0.entry:
303     %rsp = frame-setup SUB64ri8 %rsp, 24, implicit-def dead %eflags
304     CFI_INSTRUCTION .cfi_def_cfa_offset 32
305     LD_F80m %rsp, 1, _, 32, _, implicit-def dead %fpsw
306   ; CHECK: name: stack_psv
307   ; CHECK: ST_FP80m %rsp, 1, _, 0, _, implicit-def dead %fpsw :: (store 10 into stack, align 16)
308     ST_FP80m %rsp, 1, _, 0, _, implicit-def dead %fpsw :: (store 10 into stack, align 16)
309     CALL64pcrel32 $cosl, csr_64, implicit %rsp, implicit-def %rsp, implicit-def %fp0
310     %rsp = ADD64ri8 %rsp, 24, implicit-def dead %eflags
311     RETQ
312 ...
313 ---
314 name:            got_psv
315 tracksRegLiveness: true
316 body: |
317   bb.0.entry:
318   ; CHECK: name: got_psv
319   ; CHECK: %rax = MOV64rm %rip, 1, _, @G, _ :: (load 8 from got)
320     %rax = MOV64rm %rip, 1, _, @G, _ :: (load 8 from got)
321     %eax = MOV32rm killed %rax, 1, _, 0, _
322     %eax = INC32r killed %eax, implicit-def dead %eflags
323     RETQ %eax
324 ...
325 ---
326 name:            global_value
327 tracksRegLiveness: true
328 body: |
329   bb.0.entry:
330     %rax = MOV64rm %rip, 1, _, @G, _
331   ; CHECK: name: global_value
332   ; CHECK: %eax = MOV32rm killed %rax, 1, _, 0, _ :: (load 4 from %ir.G)
333     %eax = MOV32rm killed %rax, 1, _, 0, _ :: (load 4 from %ir.G)
334     %eax = INC32r killed %eax, implicit-def dead %eflags
335     RETQ %eax
336 ...
337 ---
338 name:            jumptable_psv
339 tracksRegLiveness: true
340 liveins:
341   - { reg: '%edi' }
342 jumpTable:
343   kind:          label-difference32
344   entries:
345     - id:        0
346       blocks:    [ '%bb.3.lbl1', '%bb.4.lbl2', '%bb.5.lbl3', '%bb.6.lbl4' ]
347 body: |
348   bb.0.entry:
349     successors: %bb.2.def, %bb.1.entry
350     liveins: %edi
351
352     %eax = MOV32rr %edi, implicit-def %rax
353     CMP32ri8 killed %edi, 3, implicit-def %eflags
354     JA_1 %bb.2.def, implicit killed %eflags
355
356   bb.1.entry:
357     successors: %bb.3.lbl1, %bb.4.lbl2, %bb.5.lbl3, %bb.6.lbl4
358     liveins: %rax
359
360     %rcx = LEA64r %rip, 1, _, %jump-table.0, _
361   ; CHECK: name: jumptable_psv
362   ; CHECK: %rax = MOVSX64rm32 %rcx, 4, killed %rax, 0, _ :: (load 4 from jump-table, align 8)
363     %rax = MOVSX64rm32 %rcx, 4, killed %rax, 0, _ :: (load 4 from jump-table, align 8)
364     %rax = ADD64rr killed %rax, killed %rcx, implicit-def dead %eflags
365     JMP64r killed %rax
366
367   bb.2.def:
368     %eax = MOV32r0 implicit-def dead %eflags
369     RETQ %eax
370
371   bb.3.lbl1:
372     %eax = MOV32ri 1
373     RETQ %eax
374
375   bb.4.lbl2:
376     %eax = MOV32ri 2
377     RETQ %eax
378
379   bb.5.lbl3:
380     %eax = MOV32ri 4
381     RETQ %eax
382
383   bb.6.lbl4:
384     %eax = MOV32ri 8
385     RETQ %eax
386 ...
387 ---
388 name:            tbaa_metadata
389 tracksRegLiveness: true
390 body: |
391   bb.0.entry:
392     %rax = MOV64rm %rip, 1, _, @a, _ :: (load 8 from got)
393   ; CHECK-LABEL: name: tbaa_metadata
394   ; CHECK:      %eax = MOV32rm killed %rax, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.a, !tbaa !2)
395   ; CHECK-NEXT: %eax = MOV32rm killed %rax, 1, _, 0, _ :: (load 4 from %ir.total_len2, !tbaa !6)
396     %eax = MOV32rm killed %rax, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.a, !tbaa !2)
397     %eax = MOV32rm killed %rax, 1, _, 0, _ :: (load 4 from %ir.total_len2, !tbaa !6)
398     RETQ %eax
399 ...
400 ---
401 name:            aa_scope
402 tracksRegLiveness: true
403 liveins:
404   - { reg: '%rdi' }
405   - { reg: '%rsi' }
406 body: |
407   bb.0.entry:
408     liveins: %rdi, %rsi
409   ; CHECK-LABEL: name: aa_scope
410   ; CHECK: %xmm0 = MOVSSrm %rsi, 1, _, 0, _ :: (load 4 from %ir.c, !alias.scope !9)
411     %xmm0 = MOVSSrm %rsi, 1, _, 0, _ :: (load 4 from %ir.c, !alias.scope !9)
412   ; CHECK-NEXT: MOVSSmr %rdi, 1, _, 20, _, killed %xmm0 :: (store 4 into %ir.arrayidx.i, !noalias !9)
413     MOVSSmr %rdi, 1, _, 20, _, killed %xmm0 :: (store 4 into %ir.arrayidx.i, !noalias !9)
414     %xmm0 = MOVSSrm killed %rsi, 1, _, 0, _ :: (load 4 from %ir.c)
415     MOVSSmr killed %rdi, 1, _, 28, _, killed %xmm0 :: (store 4 into %ir.arrayidx)
416     RETQ
417 ...
418 ---
419 name:            range_metadata
420 tracksRegLiveness: true
421 liveins:
422   - { reg: '%rdi' }
423 body: |
424   bb.0.entry:
425     liveins: %rdi
426   ; CHECK-LABEL: name: range_metadata
427   ; CHECK: %al = MOV8rm killed %rdi, 1, _, 0, _ :: (load 1 from %ir.x, !range !11)
428     %al = MOV8rm killed %rdi, 1, _, 0, _ :: (load 1 from %ir.x, !range !11)
429     RETQ %al
430 ...