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
7 define i32 @test(i32* %a) {
14 define void @test2(i32* %"a value") {
16 %b = load i32, i32* %"a value"
18 store i32 %c, i32* %"a value"
22 define void @test3(i32*) {
25 %b = load i32, i32* %0
31 define i32 @volatile_inc(i32* %x) {
33 %0 = load volatile i32, i32* %x
35 store volatile i32 %1, i32* %x
39 define void @non_temporal_store(i32* %a, i32 %b) {
41 store i32 %b, i32* %a, align 16, !nontemporal !0
47 define i32 @invariant_load(i32* %x) {
49 %v = load i32, i32* %x, !invariant.load !1
55 define void @memory_offset(<8 x float>* %vec) {
57 %v = load <8 x float>, <8 x float>* %vec
58 %v2 = insertelement <8 x float> %v, float 0.0, i32 4
59 store <8 x float> %v2, <8 x float>* %vec
63 define void @memory_alignment(<8 x float>* %vec) {
65 %v = load <8 x float>, <8 x float>* %vec
66 %v2 = insertelement <8 x float> %v, float 0.0, i32 4
67 store <8 x float> %v2, <8 x float>* %vec
71 define double @constant_pool_psv(double %a) {
73 %b = fadd double %a, 3.250000e+00
77 declare x86_fp80 @cosl(x86_fp80) #0
79 define x86_fp80 @stack_psv(x86_fp80 %x) {
81 %y = call x86_fp80 @cosl(x86_fp80 %x) #0
85 attributes #0 = { readonly }
87 @G = external global i32
89 define i32 @got_psv() {
91 %a = load i32, i32* @G
96 define i32 @global_value() {
98 %a = load i32, i32* @G
103 define i32 @jumptable_psv(i32 %in) {
105 switch i32 %in, label %def [
123 %struct.XXH_state64_t = type { i32, i32, i64, i64, i64 }
125 @a = common global i32 0, align 4
127 define i32 @tbaa_metadata() {
129 %0 = load i32, i32* @a, align 4, !tbaa !2
130 %1 = inttoptr i32 %0 to %struct.XXH_state64_t*
131 %total_len2 = bitcast %struct.XXH_state64_t* %1 to i32*
132 %2 = load i32, i32* %total_len2, align 4, !tbaa !6
136 !2 = !{!3, !3, i64 0}
137 !3 = !{!"int", !4, i64 0}
138 !4 = !{!"omnipotent char", !5, i64 0}
139 !5 = !{!"Simple C/C++ TBAA"}
140 !6 = !{!7, !3, i64 0}
141 !7 = !{!"XXH_state64_t", !3, i64 0, !3, i64 4, !8, i64 8, !8, i64 16, !8, i64 24}
142 !8 = !{!"long long", !4, i64 0}
144 define void @aa_scope(float* nocapture %a, float* nocapture readonly %c) #1 {
146 %0 = load float, float* %c, align 4, !alias.scope !9
147 %arrayidx.i = getelementptr inbounds float, float* %a, i64 5
148 store float %0, float* %arrayidx.i, align 4, !noalias !9
149 %1 = load float, float* %c, align 4
150 %arrayidx = getelementptr inbounds float, float* %a, i64 7
151 store float %1, float* %arrayidx, align 4
155 attributes #1 = { nounwind uwtable }
157 !9 = distinct !{!9, !10, !"some scope"}
158 !10 = distinct !{!10, !"some domain"}
160 define zeroext i1 @range_metadata(i8* %x) {
162 %0 = load i8, i8* %x, align 1, !range !11
163 %tobool = trunc i8 %0 to i1
172 tracksRegLiveness: true
178 ; CHECK: %eax = MOV32rm %rdi, 1, _, 0, _ :: (load 4 from %ir.a)
179 ; CHECK-NEXT: MOV32mi killed %rdi, 1, _, 0, _, 42 :: (store 4 into %ir.a)
180 %eax = MOV32rm %rdi, 1, _, 0, _ :: (load 4 from %ir.a)
181 MOV32mi killed %rdi, 1, _, 0, _, 42 :: (store 4 into %ir.a)
186 tracksRegLiveness: true
192 ; CHECK: INC32m killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (store 4 into %ir."a value"), (load 4 from %ir."a value")
193 INC32m killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (store 4 into %ir."a value"), (load 4 from %ir."a value")
198 tracksRegLiveness: true
204 - { id: 0, offset: -12, size: 4, alignment: 4 }
208 ; Verify that the unnamed local values can be serialized.
209 ; CHECK-LABEL: name: test3
210 ; CHECK: %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (load 4 from %ir.0)
211 ; CHECK: MOV32mr %rsp, 1, _, -4, _, killed %eax :: (store 4 into %ir.1)
212 %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (load 4 from %ir.0)
213 %eax = INC32r killed %eax, implicit-def dead %eflags
214 MOV32mr %rsp, 1, _, -4, _, killed %eax :: (store 4 into %ir.1)
219 tracksRegLiveness: true
225 ; CHECK: name: volatile_inc
226 ; CHECK: %eax = MOV32rm %rdi, 1, _, 0, _ :: (volatile load 4 from %ir.x)
227 ; CHECK: MOV32mr killed %rdi, 1, _, 0, _, %eax :: (volatile store 4 into %ir.x)
228 %eax = MOV32rm %rdi, 1, _, 0, _ :: (volatile load 4 from %ir.x)
229 %eax = INC32r killed %eax, implicit-def dead %eflags
230 MOV32mr killed %rdi, 1, _, 0, _, %eax :: (volatile store 4 into %ir.x)
234 name: non_temporal_store
235 tracksRegLiveness: true
242 ; CHECK: name: non_temporal_store
243 ; CHECK: MOVNTImr killed %rdi, 1, _, 0, _, killed %esi :: (non-temporal store 4 into %ir.a)
244 MOVNTImr killed %rdi, 1, _, 0, _, killed %esi :: (non-temporal store 4 into %ir.a)
249 tracksRegLiveness: true
255 ; CHECK: name: invariant_load
256 ; CHECK: %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (invariant load 4 from %ir.x)
257 %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (invariant load 4 from %ir.x)
262 tracksRegLiveness: true
268 ; CHECK: name: memory_offset
269 ; CHECK: %xmm0 = MOVAPSrm %rdi, 1, _, 0, _ :: (load 16 from %ir.vec)
270 ; CHECK-NEXT: %xmm1 = MOVAPSrm %rdi, 1, _, 16, _ :: (load 16 from %ir.vec + 16)
271 ; CHECK: MOVAPSmr %rdi, 1, _, 0, _, killed %xmm0 :: (store 16 into %ir.vec)
272 ; CHECK-NEXT: MOVAPSmr killed %rdi, 1, _, 16, _, killed %xmm1 :: (store 16 into %ir.vec + 16)
273 %xmm0 = MOVAPSrm %rdi, 1, _, 0, _ :: (load 16 from %ir.vec)
274 %xmm1 = MOVAPSrm %rdi, 1, _, 16, _ :: (load 16 from %ir.vec + 16)
276 %xmm1 = MOVSSrr killed %xmm1, killed %xmm2
277 MOVAPSmr %rdi, 1, _, 0, _, killed %xmm0 :: (store 16 into %ir.vec)
278 MOVAPSmr killed %rdi, 1, _, 16, _, killed %xmm1 :: (store 16 into %ir.vec + 16)
282 name: memory_alignment
283 tracksRegLiveness: true
289 ; CHECK: name: memory_alignment
290 ; CHECK: %xmm0 = MOVAPSrm %rdi, 1, _, 0, _ :: (load 16 from %ir.vec, align 32)
291 ; CHECK-NEXT: %xmm1 = MOVAPSrm %rdi, 1, _, 16, _ :: (load 16 from %ir.vec + 16, align 32)
292 ; CHECK: MOVAPSmr %rdi, 1, _, 0, _, killed %xmm0 :: (store 16 into %ir.vec, align 32)
293 ; CHECK-NEXT: MOVAPSmr killed %rdi, 1, _, 16, _, killed %xmm1 :: (store 16 into %ir.vec + 16, align 32)
294 %xmm0 = MOVAPSrm %rdi, 1, _, 0, _ :: (load 16 from %ir.vec, align 32)
295 %xmm1 = MOVAPSrm %rdi, 1, _, 16, _ :: (load 16 from %ir.vec + 16, align 32)
297 %xmm1 = MOVSSrr killed %xmm1, killed %xmm2
298 MOVAPSmr %rdi, 1, _, 0, _, killed %xmm0 :: (store 16 into %ir.vec, align 32)
299 MOVAPSmr killed %rdi, 1, _, 16, _, killed %xmm1 :: (store 16 into %ir.vec + 16, align 32)
303 name: constant_pool_psv
304 tracksRegLiveness: true
309 value: 'double 3.250000e+00'
313 ; CHECK: name: constant_pool_psv
314 ; CHECK: %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _ :: (load 8 from constant-pool)
315 ; CHECK-NEXT: %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _ :: (load 8 from constant-pool + 8)
316 %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _ :: (load 8 from constant-pool)
317 %xmm0 = ADDSDrm killed %xmm0, %rip, 1, _, %const.0, _ :: (load 8 from constant-pool + 8)
322 tracksRegLiveness: true
330 - { id: 0, offset: 0, size: 10, alignment: 16, isImmutable: true, isAliased: false }
333 %rsp = frame-setup SUB64ri8 %rsp, 24, implicit-def dead %eflags
334 CFI_INSTRUCTION .cfi_def_cfa_offset 32
335 LD_F80m %rsp, 1, _, 32, _, implicit-def dead %fpsw
336 ; CHECK: name: stack_psv
337 ; CHECK: ST_FP80m %rsp, 1, _, 0, _, implicit-def dead %fpsw :: (store 10 into stack, align 16)
338 ST_FP80m %rsp, 1, _, 0, _, implicit-def dead %fpsw :: (store 10 into stack, align 16)
339 CALL64pcrel32 $cosl, csr_64, implicit %rsp, implicit-def %rsp, implicit-def %fp0
340 %rsp = ADD64ri8 %rsp, 24, implicit-def dead %eflags
345 tracksRegLiveness: true
348 ; CHECK: name: got_psv
349 ; CHECK: %rax = MOV64rm %rip, 1, _, @G, _ :: (load 8 from got)
350 %rax = MOV64rm %rip, 1, _, @G, _ :: (load 8 from got)
351 %eax = MOV32rm killed %rax, 1, _, 0, _
352 %eax = INC32r killed %eax, implicit-def dead %eflags
357 tracksRegLiveness: true
360 %rax = MOV64rm %rip, 1, _, @G, _
361 ; CHECK: name: global_value
362 ; CHECK: %eax = MOV32rm killed %rax, 1, _, 0, _ :: (load 4 from %ir.G)
363 %eax = MOV32rm killed %rax, 1, _, 0, _ :: (load 4 from %ir.G)
364 %eax = INC32r killed %eax, implicit-def dead %eflags
369 tracksRegLiveness: true
373 kind: label-difference32
376 blocks: [ '%bb.3.lbl1', '%bb.4.lbl2', '%bb.5.lbl3', '%bb.6.lbl4' ]
379 successors: %bb.2.def, %bb.1.entry
382 %eax = MOV32rr %edi, implicit-def %rax
383 CMP32ri8 killed %edi, 3, implicit-def %eflags
384 JA_1 %bb.2.def, implicit killed %eflags
387 successors: %bb.3.lbl1, %bb.4.lbl2, %bb.5.lbl3, %bb.6.lbl4
390 %rcx = LEA64r %rip, 1, _, %jump-table.0, _
391 ; CHECK: name: jumptable_psv
392 ; CHECK: %rax = MOVSX64rm32 %rcx, 4, killed %rax, 0, _ :: (load 4 from jump-table, align 8)
393 %rax = MOVSX64rm32 %rcx, 4, killed %rax, 0, _ :: (load 4 from jump-table, align 8)
394 %rax = ADD64rr killed %rax, killed %rcx, implicit-def dead %eflags
398 %eax = MOV32r0 implicit-def dead %eflags
419 tracksRegLiveness: true
422 %rax = MOV64rm %rip, 1, _, @a, _ :: (load 8 from got)
423 ; CHECK-LABEL: name: tbaa_metadata
424 ; CHECK: %eax = MOV32rm killed %rax, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.a, !tbaa !2)
425 ; CHECK-NEXT: %eax = MOV32rm killed %rax, 1, _, 0, _ :: (load 4 from %ir.total_len2, !tbaa !6)
426 %eax = MOV32rm killed %rax, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.a, !tbaa !2)
427 %eax = MOV32rm killed %rax, 1, _, 0, _ :: (load 4 from %ir.total_len2, !tbaa !6)
432 tracksRegLiveness: true
439 ; CHECK-LABEL: name: aa_scope
440 ; CHECK: %xmm0 = MOVSSrm %rsi, 1, _, 0, _ :: (load 4 from %ir.c, !alias.scope !9)
441 %xmm0 = MOVSSrm %rsi, 1, _, 0, _ :: (load 4 from %ir.c, !alias.scope !9)
442 ; CHECK-NEXT: MOVSSmr %rdi, 1, _, 20, _, killed %xmm0 :: (store 4 into %ir.arrayidx.i, !noalias !9)
443 MOVSSmr %rdi, 1, _, 20, _, killed %xmm0 :: (store 4 into %ir.arrayidx.i, !noalias !9)
444 %xmm0 = MOVSSrm killed %rsi, 1, _, 0, _ :: (load 4 from %ir.c)
445 MOVSSmr killed %rdi, 1, _, 28, _, killed %xmm0 :: (store 4 into %ir.arrayidx)
450 tracksRegLiveness: true
456 ; CHECK-LABEL: name: range_metadata
457 ; CHECK: %al = MOV8rm killed %rdi, 1, _, 0, _ :: (load 1 from %ir.x, !range !11)
458 %al = MOV8rm killed %rdi, 1, _, 0, _ :: (load 1 from %ir.x, !range !11)