572 lines · plain
1# RUN: llc -mtriple=x86_64 -run-pass none -o - %s | FileCheck %s2# This test ensures that the MIR parser parses the machine memory operands3# correctly.4 5--- |6 7 define i32 @test(ptr %a) {8 entry:9 %b = load i32, ptr %a10 store i32 42, ptr %a11 ret i32 %b12 }13 14 define void @test2(ptr %"a value") {15 entry2:16 %b = load i32, ptr %"a value"17 %c = add i32 %b, 118 store i32 %c, ptr %"a value"19 ret void20 }21 22 define void @test3(ptr) {23 entry3:24 %1 = alloca i3225 %b = load i32, ptr %026 %c = add i32 %b, 127 store i32 %c, ptr %128 ret void29 }30 31 define i32 @volatile_inc(ptr %x) {32 entry:33 %0 = load volatile i32, ptr %x34 %1 = add i32 %0, 135 store volatile i32 %1, ptr %x36 ret i32 %137 }38 39 define void @non_temporal_store(ptr %a, i32 %b) {40 entry:41 store i32 %b, ptr %a, align 16, !nontemporal !042 ret void43 }44 45 !0 = !{i32 1}46 47 define i32 @invariant_load(ptr %x) {48 entry:49 %v = load i32, ptr %x, !invariant.load !150 ret i32 %v51 }52 53 !1 = !{}54 55 define void @memory_offset(ptr %vec) {56 entry:57 %v = load <8 x float>, ptr %vec58 %v2 = insertelement <8 x float> %v, float 0.0, i32 459 store <8 x float> %v2, ptr %vec60 ret void61 }62 63 define void @memory_alignment(ptr %vec) {64 entry:65 %v = load <16 x float>, ptr %vec66 %v2 = insertelement <16 x float> %v, float 0.0, i32 467 store <16 x float> %v2, ptr %vec68 ret void69 }70 71 define double @constant_pool_psv(double %a) {72 entry:73 %b = fadd double %a, 3.250000e+0074 ret double %b75 }76 77 declare x86_fp80 @cosl(x86_fp80) #078 79 define x86_fp80 @stack_psv(x86_fp80 %x) {80 entry:81 %y = call x86_fp80 @cosl(x86_fp80 %x) #082 ret x86_fp80 %y83 }84 85 attributes #0 = { readonly }86 87 @G = external global i3288 89 define i32 @got_psv() {90 entry:91 %a = load i32, ptr @G92 %b = add i32 %a, 193 ret i32 %b94 }95 96 @0 = external global i3297 98 define i32 @global_value() {99 entry:100 %a = load i32, ptr @G101 %b = add i32 %a, 1102 %c = load i32, ptr @0103 %d = add i32 %b, %c104 ret i32 %d105 }106 107 define i32 @jumptable_psv(i32 %in) {108 entry:109 switch i32 %in, label %def [110 i32 0, label %lbl1111 i32 1, label %lbl2112 i32 2, label %lbl3113 i32 3, label %lbl4114 ]115 def:116 ret i32 0117 lbl1:118 ret i32 1119 lbl2:120 ret i32 2121 lbl3:122 ret i32 4123 lbl4:124 ret i32 8125 }126 127 %struct.XXH_state64_t = type { i32, i32, i64, i64, i64 }128 129 @a = common global i32 0, align 4130 131 define i32 @tbaa_metadata() {132 entry:133 %0 = load i32, ptr @a, align 4, !tbaa !2134 %1 = inttoptr i32 %0 to ptr135 %2 = load i32, ptr %1, align 4, !tbaa !6136 ret i32 %2137 }138 139 !2 = !{!3, !3, i64 0}140 !3 = !{!"int", !4, i64 0}141 !4 = !{!"omnipotent char", !5, i64 0}142 !5 = !{!"Simple C/C++ TBAA"}143 !6 = !{!7, !3, i64 0}144 !7 = !{!"XXH_state64_t", !3, i64 0, !3, i64 4, !8, i64 8, !8, i64 16, !8, i64 24}145 !8 = !{!"long long", !4, i64 0}146 147 define void @aa_scope(ptr nocapture %a, ptr nocapture readonly %c) #1 {148 entry:149 %0 = load float, ptr %c, align 4, !alias.scope !9150 %arrayidx.i = getelementptr inbounds float, ptr %a, i64 5151 store float %0, ptr %arrayidx.i, align 4, !noalias !9152 %1 = load float, ptr %c, align 4153 %arrayidx = getelementptr inbounds float, ptr %a, i64 7154 store float %1, ptr %arrayidx, align 4155 ret void156 }157 158 attributes #1 = { nounwind uwtable }159 160 !9 = !{!10}161 !10 = distinct !{!10, !11, !"some scope"}162 !11 = distinct !{!11, !"some domain"}163 164 define zeroext i1 @range_metadata(ptr %x) {165 entry:166 %0 = load i8, ptr %x, align 1, !range !12167 %tobool = trunc i8 %0 to i1168 ret i1 %tobool169 }170 171 !12 = !{i8 0, i8 2}172 173 %st = type { i32, i32 }174 175 @values = common global [50 x %st] zeroinitializer, align 16176 177 define void @gep_value(i64 %d) {178 entry:179 %conv = trunc i64 %d to i32180 store i32 %conv, ptr @values, align 16181 ret void182 }183 184 define ptr @undef_value() {185 entry:186 %0 = load ptr, ptr poison, align 8187 ret ptr %0188 }189 190 define void @dummy0() { ret void }191 define void @dummy1() { ret void }192 define void @dummy2() { ret void }193 define void @dummy3() { ret void }194...195---196name: test197tracksRegLiveness: true198liveins:199 - { reg: '$rdi' }200body: |201 bb.0.entry:202 liveins: $rdi203 ; CHECK: $eax = MOV32rm $rdi, 1, $noreg, 0, $noreg :: (load (s32) from %ir.a)204 ; CHECK-NEXT: MOV32mi killed $rdi, 1, $noreg, 0, $noreg, 42 :: (store (s32) into %ir.a)205 $eax = MOV32rm $rdi, 1, _, 0, _ :: (load (s32) from %ir.a)206 MOV32mi killed $rdi, 1, _, 0, _, 42 :: (store (s32) into %ir.a)207 RET64 $eax208...209---210name: test2211tracksRegLiveness: true212liveins:213 - { reg: '$rdi' }214body: |215 bb.0.entry2:216 liveins: $rdi217 ; CHECK: INC32m killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (store (s32) into %ir."a value"), (load (s32) from %ir."a value")218 INC32m killed $rdi, 1, _, 0, _, implicit-def dead $eflags :: (store (s32) into %ir."a value"), (load (s32) from %ir."a value")219 RET64220...221---222name: test3223tracksRegLiveness: true224liveins:225 - { reg: '$rdi' }226frameInfo:227 maxAlignment: 4228stack:229 - { id: 0, offset: -12, size: 4, alignment: 4 }230body: |231 bb.0.entry3:232 liveins: $rdi233 ; Verify that the unnamed local values can be serialized.234 ; CHECK-LABEL: name: test3235 ; CHECK: $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg :: (load (s32) from %ir.0)236 ; CHECK: MOV32mr $rsp, 1, $noreg, -4, $noreg, killed $eax :: (store (s32) into %ir.1)237 $eax = MOV32rm killed $rdi, 1, _, 0, _ :: (load (s32) from %ir.0)238 $eax = INC32r killed $eax, implicit-def dead $eflags239 MOV32mr $rsp, 1, _, -4, _, killed $eax :: (store (s32) into %ir.1)240 RET64241...242---243name: volatile_inc244tracksRegLiveness: true245liveins:246 - { reg: '$rdi' }247body: |248 bb.0.entry:249 liveins: $rdi250 ; CHECK: name: volatile_inc251 ; CHECK: $eax = MOV32rm $rdi, 1, $noreg, 0, $noreg :: (volatile load (s32) from %ir.x)252 ; CHECK: MOV32mr killed $rdi, 1, $noreg, 0, $noreg, $eax :: (volatile store (s32) into %ir.x)253 $eax = MOV32rm $rdi, 1, _, 0, _ :: (volatile load (s32) from %ir.x)254 $eax = INC32r killed $eax, implicit-def dead $eflags255 MOV32mr killed $rdi, 1, _, 0, _, $eax :: (volatile store (s32) into %ir.x)256 RET64 $eax257...258---259name: non_temporal_store260tracksRegLiveness: true261liveins:262 - { reg: '$rdi' }263 - { reg: '$esi' }264body: |265 bb.0.entry:266 liveins: $esi, $rdi267 ; CHECK: name: non_temporal_store268 ; CHECK: MOVNTImr killed $rdi, 1, $noreg, 0, $noreg, killed $esi :: (non-temporal store (s32) into %ir.a)269 MOVNTImr killed $rdi, 1, _, 0, _, killed $esi :: (non-temporal store (s32) into %ir.a)270 RET64271...272---273name: invariant_load274tracksRegLiveness: true275liveins:276 - { reg: '$rdi' }277body: |278 bb.0.entry:279 liveins: $rdi280 ; CHECK: name: invariant_load281 ; CHECK: $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg :: (invariant load (s32) from %ir.x)282 $eax = MOV32rm killed $rdi, 1, _, 0, _ :: (invariant load (s32) from %ir.x)283 RET64 $eax284...285---286name: memory_offset287tracksRegLiveness: true288liveins:289 - { reg: '$rdi' }290body: |291 bb.0.entry:292 liveins: $rdi293 ; CHECK: name: memory_offset294 ; CHECK: $xmm0 = MOVAPSrm $rdi, 1, $noreg, 0, $noreg :: (load (s128) from %ir.vec)295 ; CHECK-NEXT: $xmm1 = MOVAPSrm $rdi, 1, $noreg, 16, $noreg :: (load (s128) from %ir.vec + 16)296 ; CHECK: MOVAPSmr $rdi, 1, $noreg, 0, $noreg, killed $xmm0 :: (store (s128) into %ir.vec)297 ; CHECK-NEXT: MOVAPSmr killed $rdi, 1, $noreg, 16, $noreg, killed $xmm1 :: (store (s128) into %ir.vec + 16)298 $xmm0 = MOVAPSrm $rdi, 1, _, 0, _ :: (load (s128) from %ir.vec)299 $xmm1 = MOVAPSrm $rdi, 1, _, 16, _ :: (load (s128) from %ir.vec + 16)300 $xmm2 = FsFLD0SS301 $xmm1 = MOVSSrr killed $xmm1, killed $xmm2302 MOVAPSmr $rdi, 1, _, 0, _, killed $xmm0 :: (store (s128) into %ir.vec)303 MOVAPSmr killed $rdi, 1, _, 16, _, killed $xmm1 :: (store (s128) into %ir.vec + 16)304 RET64305...306---307name: memory_alignment308tracksRegLiveness: true309liveins:310 - { reg: '$rdi' }311body: |312 bb.0.entry:313 liveins: $rdi314 ; CHECK: name: memory_alignment315 ; CHECK: $xmm0 = MOVAPSrm $rdi, 1, $noreg, 0, $noreg :: (load (s128) from %ir.vec, align 64)316 ; CHECK-NEXT: $xmm1 = MOVAPSrm $rdi, 1, $noreg, 16, $noreg :: (load (s128) from %ir.vec + 16, basealign 64)317 ; CHECK-NEXT: $xmm2 = MOVAPSrm $rdi, 1, $noreg, 32, $noreg :: (load (s128) from %ir.vec + 32, align 32, basealign 64)318 ; CHECK-NEXT: $xmm3 = MOVAPSrm $rdi, 1, $noreg, 48, $noreg :: (load (s128) from %ir.vec + 48, basealign 64)319 ; CHECK: MOVAPSmr $rdi, 1, $noreg, 0, $noreg, killed $xmm0 :: (store (s128) into %ir.vec, align 64)320 ; CHECK-NEXT: MOVAPSmr $rdi, 1, $noreg, 16, $noreg, killed $xmm1 :: (store (s128) into %ir.vec + 16, basealign 64)321 ; CHECK-NEXT: MOVAPSmr $rdi, 1, $noreg, 32, $noreg, killed $xmm2 :: (store (s128) into %ir.vec + 32, align 32, basealign 64)322 ; CHECK-NEXT: MOVAPSmr killed $rdi, 1, $noreg, 48, $noreg, killed $xmm3 :: (store (s128) into %ir.vec + 48, basealign 64)323 $xmm0 = MOVAPSrm $rdi, 1, _, 0, _ :: (load (s128) from %ir.vec, align 64)324 $xmm1 = MOVAPSrm $rdi, 1, _, 16, _ :: (load (s128) from %ir.vec + 16, basealign 64)325 $xmm2 = MOVAPSrm $rdi, 1, _, 32, _ :: (load (s128) from %ir.vec + 32, align 32, basealign 64)326 $xmm3 = MOVAPSrm $rdi, 1, _, 48, _ :: (load (s128) from %ir.vec + 48, basealign 64)327 $xmm4 = FsFLD0SS328 $xmm1 = MOVSSrr killed $xmm1, killed $xmm4329 MOVAPSmr $rdi, 1, _, 0, _, killed $xmm0 :: (store (s128) into %ir.vec, align 64)330 MOVAPSmr $rdi, 1, _, 16, _, killed $xmm1 :: (store (s128) into %ir.vec + 16, basealign 64)331 MOVAPSmr $rdi, 1, _, 32, _, killed $xmm2 :: (store (s128) into %ir.vec + 32, align 32, basealign 64)332 MOVAPSmr killed $rdi, 1, _, 48, _, killed $xmm3 :: (store (s128) into %ir.vec + 48, basealign 64)333 RET64334...335---336name: constant_pool_psv337tracksRegLiveness: true338liveins:339 - { reg: '$xmm0' }340constants:341 - id: 0342 value: 'double 3.250000e+00'343body: |344 bb.0.entry:345 liveins: $xmm0346 ; CHECK: name: constant_pool_psv347 ; CHECK: $xmm0 = ADDSDrm killed $xmm0, $rip, 1, $noreg, %const.0, $noreg, implicit $mxcsr :: (load (s64) from constant-pool)348 ; CHECK-NEXT: $xmm0 = ADDSDrm killed $xmm0, $rip, 1, $noreg, %const.0, $noreg, implicit $mxcsr :: (load (s64) from constant-pool + 8)349 $xmm0 = ADDSDrm killed $xmm0, $rip, 1, _, %const.0, _, implicit $mxcsr :: (load (s64) from constant-pool)350 $xmm0 = ADDSDrm killed $xmm0, $rip, 1, _, %const.0, _, implicit $mxcsr :: (load (s64) from constant-pool + 8)351 RET64 $xmm0352...353---354name: stack_psv355tracksRegLiveness: true356frameInfo:357 stackSize: 24358 maxAlignment: 16359 adjustsStack: true360 hasCalls: true361 maxCallFrameSize: 16362fixedStack:363 - { id: 0, offset: 0, size: 10, alignment: 16, isImmutable: true, isAliased: false }364body: |365 bb.0.entry:366 $rsp = frame-setup SUB64ri8 $rsp, 24, implicit-def dead $eflags367 CFI_INSTRUCTION def_cfa_offset 32368 LD_F80m $rsp, 1, $noreg, 32, $noreg, implicit-def dead $fpsw, implicit $fpcw369 ; CHECK: name: stack_psv370 ; CHECK: ST_FP80m $rsp, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (store (s80) into stack, align 16)371 ST_FP80m $rsp, 1, _, 0, _, implicit-def dead $fpsw, implicit $fpcw :: (store (s80) into stack, align 16)372 CALL64pcrel32 &cosl, csr_64, implicit $rsp, implicit-def $rsp, implicit-def $fp0373 $rsp = ADD64ri8 $rsp, 24, implicit-def dead $eflags374 RET64375...376---377name: got_psv378tracksRegLiveness: true379body: |380 bb.0.entry:381 ; CHECK: name: got_psv382 ; CHECK: $rax = MOV64rm $rip, 1, $noreg, @G, $noreg :: (load (s64) from got)383 $rax = MOV64rm $rip, 1, _, @G, _ :: (load (s64) from got)384 $eax = MOV32rm killed $rax, 1, _, 0, _385 $eax = INC32r killed $eax, implicit-def dead $eflags386 RET64 $eax387...388---389name: global_value390tracksRegLiveness: true391body: |392 bb.0.entry:393 $rax = MOV64rm $rip, 1, _, @G, _394 ; CHECK-LABEL: name: global_value395 ; CHECK: $eax = MOV32rm killed $rax, 1, $noreg, 0, $noreg, implicit-def $rax :: (load (s32) from @G)396 ; CHECK: $ecx = MOV32rm killed $rcx, 1, $noreg, 0, $noreg, implicit-def $rcx :: (load (s32) from @0)397 $eax = MOV32rm killed $rax, 1, _, 0, _, implicit-def $rax :: (load (s32) from @G)398 $rcx = MOV64rm $rip, 1, _, @0, _399 $ecx = MOV32rm killed $rcx, 1, _, 0, _, implicit-def $rcx :: (load (s32) from @0)400 $eax = LEA64_32r killed $rax, 1, killed $rcx, 1, _401 RET64 $eax402...403---404name: jumptable_psv405tracksRegLiveness: true406liveins:407 - { reg: '$edi' }408jumpTable:409 kind: label-difference32410 entries:411 - id: 0412 blocks: [ '%bb.3.lbl1', '%bb.4.lbl2', '%bb.5.lbl3', '%bb.6.lbl4' ]413body: |414 bb.0.entry:415 successors: %bb.2.def, %bb.1.entry416 liveins: $edi417 418 $eax = MOV32rr $edi, implicit-def $rax419 CMP32ri8 killed $edi, 3, implicit-def $eflags420 JCC_1 %bb.2.def, 7, implicit killed $eflags421 422 bb.1.entry:423 successors: %bb.3.lbl1, %bb.4.lbl2, %bb.5.lbl3, %bb.6.lbl4424 liveins: $rax425 426 $rcx = LEA64r $rip, 1, _, %jump-table.0, _427 ; CHECK: name: jumptable_psv428 ; CHECK: $rax = MOVSX64rm32 $rcx, 4, killed $rax, 0, $noreg :: (load (s32) from jump-table, align 8)429 $rax = MOVSX64rm32 $rcx, 4, killed $rax, 0, _ :: (load (s32) from jump-table, align 8)430 $rax = ADD64rr killed $rax, killed $rcx, implicit-def dead $eflags431 JMP64r killed $rax432 433 bb.2.def:434 $eax = MOV32r0 implicit-def dead $eflags435 RET64 $eax436 437 bb.3.lbl1:438 $eax = MOV32ri 1439 RET64 $eax440 441 bb.4.lbl2:442 $eax = MOV32ri 2443 RET64 $eax444 445 bb.5.lbl3:446 $eax = MOV32ri 4447 RET64 $eax448 449 bb.6.lbl4:450 $eax = MOV32ri 8451 RET64 $eax452...453---454name: tbaa_metadata455tracksRegLiveness: true456body: |457 bb.0.entry:458 $rax = MOV64rm $rip, 1, _, @a, _ :: (load (s64) from got)459 ; CHECK-LABEL: name: tbaa_metadata460 ; CHECK: $eax = MOV32rm killed $rax, 1, $noreg, 0, $noreg, implicit-def $rax :: (load (s32) from @a, !tbaa !2)461 ; CHECK-NEXT: $eax = MOV32rm killed $rax, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1, !tbaa !6)462 $eax = MOV32rm killed $rax, 1, _, 0, _, implicit-def $rax :: (load (s32) from @a, !tbaa !2)463 $eax = MOV32rm killed $rax, 1, _, 0, _ :: (load (s32) from %ir.1, !tbaa !6)464 RET64 $eax465...466---467name: aa_scope468tracksRegLiveness: true469liveins:470 - { reg: '$rdi' }471 - { reg: '$rsi' }472body: |473 bb.0.entry:474 liveins: $rdi, $rsi475 ; CHECK-LABEL: name: aa_scope476 ; CHECK: $xmm0 = MOVSSrm_alt $rsi, 1, $noreg, 0, $noreg :: (load (s32) from %ir.c, !alias.scope !9)477 $xmm0 = MOVSSrm_alt $rsi, 1, _, 0, _ :: (load (s32) from %ir.c, !alias.scope !9)478 ; CHECK-NEXT: MOVSSmr $rdi, 1, $noreg, 20, $noreg, killed $xmm0 :: (store (s32) into %ir.arrayidx.i, !noalias !9)479 MOVSSmr $rdi, 1, _, 20, _, killed $xmm0 :: (store (s32) into %ir.arrayidx.i, !noalias !9)480 $xmm0 = MOVSSrm_alt killed $rsi, 1, _, 0, _ :: (load (s32) from %ir.c)481 MOVSSmr killed $rdi, 1, _, 28, _, killed $xmm0 :: (store (s32) into %ir.arrayidx)482 RET64483...484---485name: range_metadata486tracksRegLiveness: true487liveins:488 - { reg: '$rdi' }489body: |490 bb.0.entry:491 liveins: $rdi492 ; CHECK-LABEL: name: range_metadata493 ; CHECK: $al = MOV8rm killed $rdi, 1, $noreg, 0, $noreg :: (load (s8) from %ir.x, !range !11)494 $al = MOV8rm killed $rdi, 1, _, 0, _ :: (load (s8) from %ir.x, !range !11)495 RET64 $al496...497---498name: gep_value499tracksRegLiveness: true500liveins:501 - { reg: '$rdi' }502body: |503 bb.0.entry:504 liveins: $rdi505 506 $rax = MOV64rm $rip, 1, _, @values, _ :: (load (s64) from got)507 ; CHECK-LABEL: gep_value508 ; CHECK: MOV32mr killed $rax, 1, $noreg, 0, $noreg, $edi, implicit killed $rdi :: (store (s32) into @values, align 16)509 MOV32mr killed $rax, 1, _, 0, _, $edi, implicit killed $rdi :: (store (s32) into @values, align 16)510 RET64511...512---513name: undef_value514tracksRegLiveness: true515body: |516 bb.0.entry:517 ; CHECK-LABEL: name: undef_value518 ; CHECK: $rax = MOV64rm undef $rax, 1, $noreg, 0, $noreg :: (load (s64) from `ptr poison`)519 $rax = MOV64rm undef $rax, 1, _, 0, _ :: (load (s64) from `ptr poison`)520 RET64 $rax521...522---523# Test memory operand without associated value.524# CHECK-LABEL: name: dummy0525# CHECK: $rax = MOV64rm undef $rax, 1, $noreg, 0, $noreg :: (load (s64))526name: dummy0527tracksRegLiveness: true528body: |529 bb.0:530 $rax = MOV64rm undef $rax, 1, _, 0, _ :: (load (s64))531 RET64 $rax532...533---534# Test parsing of stack references in machine memory operands.535# CHECK-LABEL: name: dummy1536# CHECK: $rax = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load (s64) from %stack.0)537name: dummy1538tracksRegLiveness: true539stack:540 - { id: 0, size: 4, alignment: 4 }541body: |542 bb.0:543 $rax = MOV64rm $rsp, 1, _, 0, _ :: (load (s64) from %stack.0)544 RET64 $rax545...546---547# Test parsing of unknown size in machine memory operands without alignment.548# CHECK-LABEL: name: dummy2549# CHECK: $rax = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load unknown-size from %stack.0, align 1)550name: dummy2551tracksRegLiveness: true552stack:553 - { id: 0, size: 4, alignment: 4 }554body: |555 bb.0:556 $rax = MOV64rm $rsp, 1, _, 0, _ :: (load unknown-size from %stack.0)557 RET64 $rax558...559---560# Test parsing of unknown size in machine memory operands with alignment.561# CHECK-LABEL: name: dummy3562# CHECK: $rax = MOV64rm $rsp, 1, $noreg, 0, $noreg :: (load unknown-size from %stack.0, align 4)563name: dummy3564tracksRegLiveness: true565stack:566 - { id: 0, size: 4, alignment: 4 }567body: |568 bb.0:569 $rax = MOV64rm $rsp, 1, _, 0, _ :: (load unknown-size from %stack.0, align 4)570 RET64 $rax571...572