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