1# RUN: llc -run-pass implicit-null-checks -mtriple=x86_64-apple-macosx -o - %s | FileCheck %s 2 3--- | 4 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 5 target triple = "x86_64-apple-macosx" 6 7 ;; Positive test 8 define i32 @imp_null_check_with_bitwise_op_0(i32* %x, i32 %val) { 9 entry: 10 br i1 undef, label %is_null, label %not_null, !make.implicit !0 11 12 is_null: 13 ret i32 42 14 15 not_null: 16 br i1 undef, label %ret_100, label %ret_200 17 18 ret_100: 19 ret i32 100 20 21 ret_200: 22 ret i32 200 23 } 24 25 ;; Negative test. The regalloc is such that we cannot hoist the 26 ;; instruction materializing 2200000 into %eax 27 define i32 @imp_null_check_with_bitwise_op_1(i32* %x, i32 %val, i32* %ptr) { 28 entry: 29 br i1 undef, label %is_null, label %not_null, !make.implicit !0 30 31 is_null: 32 ret i32 undef 33 34 not_null: 35 br i1 undef, label %ret_100, label %ret_200 36 37 ret_100: 38 ret i32 100 39 40 ret_200: 41 ret i32 200 42 } 43 44 ;; Negative test: IR is identical to 45 ;; @imp_null_check_with_bitwise_op_0 but MIR differs. 46 define i32 @imp_null_check_with_bitwise_op_2(i32* %x, i32 %val) { 47 entry: 48 br i1 undef, label %is_null, label %not_null, !make.implicit !0 49 50 is_null: 51 ret i32 42 52 53 not_null: 54 br i1 undef, label %ret_100, label %ret_200 55 56 ret_100: 57 ret i32 100 58 59 ret_200: 60 ret i32 200 61 } 62 63 ;; Negative test: IR is identical to 64 ;; @imp_null_check_with_bitwise_op_0 but MIR differs. 65 define i32 @imp_null_check_with_bitwise_op_3(i32* %x, i32 %val) { 66 entry: 67 br i1 undef, label %is_null, label %not_null, !make.implicit !0 68 69 is_null: 70 ret i32 42 71 72 not_null: 73 br i1 undef, label %ret_100, label %ret_200 74 75 ret_100: 76 ret i32 100 77 78 ret_200: 79 ret i32 200 80 } 81 82 ;; Positive test 83 define i32 @imp_null_check_with_bitwise_op_4(i32* %x, i32 %val) { 84 entry: 85 br i1 undef, label %is_null, label %not_null, !make.implicit !0 86 87 is_null: 88 ret i32 42 89 90 not_null: 91 br i1 undef, label %ret_100, label %ret_200 92 93 ret_100: 94 ret i32 100 95 96 ret_200: 97 ret i32 200 98 } 99 100 declare void @f() readonly 101 102 define i32 @no_hoist_across_call(i32* %ptr) { 103 entry: 104 %is_null = icmp eq i32* %ptr, null 105 br i1 %is_null, label %leave, label %stay, !make.implicit !0 106 107 stay: 108 call void @f() 109 %val = load i32, i32* %ptr 110 ret i32 %val 111 112 leave: 113 ret i32 0 114 } 115 116 define i32 @dependency_live_in_hazard(i32* %ptr, i32** %ptr2, i32* %ptr3) #0 { 117 entry: 118 %val = load i32*, i32** %ptr2 119 %ptr_is_null = icmp eq i32* %ptr, null 120 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 121 122 not_null: ; preds = %entry 123 %addend = load i32, i32* %val 124 %result = load i32, i32* %ptr 125 %result.shr = lshr i32 %result, 4 126 %result.and = and i32 %result.shr, 4095 127 %result.add = add i32 %addend, %result.and 128 ret i32 %result.add 129 130 is_null: ; preds = %entry 131 ret i32 0 132 } 133 134 define i32 @use_alternate_load_op(i32* %ptr, i32* %ptr2) { 135 entry: 136 %ptr_is_null = icmp eq i32* %ptr, null 137 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 138 139 not_null: 140 ret i32 undef 141 142 is_null: 143 ret i32 0 144 } 145 146 define i32 @imp_null_check_gep_load_with_use_dep(i32* %x, i32 %a) { 147 entry: 148 %c = icmp eq i32* %x, null 149 br i1 %c, label %is_null, label %not_null, !make.implicit !0 150 151 is_null: ; preds = %entry 152 ret i32 42 153 154 not_null: ; preds = %entry 155 %x.loc = getelementptr i32, i32* %x, i32 1 156 %y = ptrtoint i32* %x.loc to i32 157 %b = add i32 %a, %y 158 %t = load i32, i32* %x 159 %z = add i32 %t, %b 160 ret i32 %z 161 } 162 163 define i32 @imp_null_check_load_with_base_sep(i32* %x, i32 %a) { 164 entry: 165 %c = icmp eq i32* %x, null 166 br i1 %c, label %is_null, label %not_null, !make.implicit !0 167 168 is_null: ; preds = %entry 169 ret i32 42 170 171 not_null: ; preds = %entry 172 ret i32 undef 173 } 174 175 define void @inc_store(i32* %ptr, i32 %val) { 176 entry: 177 %ptr_is_null = icmp eq i32* %ptr, null 178 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 179 180 not_null: 181 ret void 182 183 is_null: 184 ret void 185 } 186 187 define void @inc_store_plus_offset(i32* %ptr, i32 %val) { 188 entry: 189 %ptr_is_null = icmp eq i32* %ptr, null 190 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 191 192 not_null: 193 ret void 194 195 is_null: 196 ret void 197 } 198 199 define void @inc_store_with_dep(i32* %ptr, i32 %val) { 200 entry: 201 %ptr_is_null = icmp eq i32* %ptr, null 202 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 203 204 not_null: 205 ret void 206 207 is_null: 208 ret void 209 } 210 211 define i32 @inc_store_with_dep_in_null(i32* %ptr, i32 %val) { 212 entry: 213 %ptr_is_null = icmp eq i32* %ptr, null 214 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 215 216 not_null: 217 ret i32 undef 218 219 is_null: 220 ret i32 undef 221 } 222 223 define void @inc_store_with_volatile(i32* %ptr, i32 %val) { 224 entry: 225 %ptr_is_null = icmp eq i32* %ptr, null 226 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 227 228 not_null: 229 ret void 230 231 is_null: 232 ret void 233 } 234 235 define void @inc_store_with_two_dep(i32* %ptr, i32 %val) { 236 entry: 237 %ptr_is_null = icmp eq i32* %ptr, null 238 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 239 240 not_null: 241 ret void 242 243 is_null: 244 ret void 245 } 246 247 define void @inc_store_with_redefined_base(i32* %ptr, i32 %val) { 248 entry: 249 %ptr_is_null = icmp eq i32* %ptr, null 250 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 251 252 not_null: 253 ret void 254 255 is_null: 256 ret void 257 } 258 259 define i32 @inc_store_with_reused_base(i32* %ptr, i32 %val) { 260 entry: 261 %ptr_is_null = icmp eq i32* %ptr, null 262 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 263 264 not_null: 265 ret i32 undef 266 267 is_null: 268 ret i32 undef 269 } 270 271 define i32 @inc_store_across_call(i32* %ptr) { 272 entry: 273 %ptr_is_null = icmp eq i32* %ptr, null 274 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 275 276 not_null: 277 call void @f() 278 ret i32 undef 279 280 is_null: 281 ret i32 undef 282 } 283 284 define i32 @inc_store_with_dep_in_dep(i32* %ptr, i32 %val) { 285 entry: 286 %ptr_is_null = icmp eq i32* %ptr, null 287 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 288 289 not_null: 290 ret i32 undef 291 292 is_null: 293 ret i32 undef 294 } 295 296 define i32 @inc_store_with_load_over_store(i32* %ptr, i32* %ptr2) { 297 entry: 298 %ptr_is_null = icmp eq i32* %ptr, null 299 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 300 301 not_null: 302 ret i32 undef 303 304 is_null: 305 ret i32 undef 306 } 307 308 define i32 @inc_store_with_store_over_load(i32* %ptr, i32* %ptr2) { 309 entry: 310 %ptr_is_null = icmp eq i32* %ptr, null 311 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 312 313 not_null: 314 ret i32 undef 315 316 is_null: 317 ret i32 undef 318 } 319 320 define void @inc_store_with_store_over_store(i32* %ptr, i32* %ptr2) { 321 entry: 322 %ptr_is_null = icmp eq i32* %ptr, null 323 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 324 325 not_null: 326 ret void 327 328 is_null: 329 ret void 330 } 331 332 define void @inc_store_with_load_and_store(i32* %ptr, i32* %ptr2) { 333 entry: 334 %ptr_is_null = icmp eq i32* %ptr, null 335 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 336 337 not_null: 338 ret void 339 340 is_null: 341 ret void 342 } 343 344 define i32 @inc_store_and_load_no_alias(i32* noalias %ptr, i32* noalias %ptr2) { 345 entry: 346 %ptr_is_null = icmp eq i32* %ptr, null 347 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 348 349 not_null: 350 ret i32 undef 351 352 is_null: 353 ret i32 undef 354 } 355 356 define i32 @inc_store_and_load_alias(i32* %ptr, i32* %ptr2) { 357 entry: 358 %ptr_is_null = icmp eq i32* %ptr, null 359 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 360 361 not_null: 362 ret i32 undef 363 364 is_null: 365 ret i32 undef 366 } 367 368 define i32 @inc_spill_dep(i32* %ptr, i32 %val) { 369 entry: 370 %ptr_is_null = icmp eq i32* %ptr, null 371 br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 372 373 not_null: 374 ret i32 undef 375 376 is_null: 377 ret i32 undef 378 } 379 380 attributes #0 = { "target-features"="+bmi,+bmi2" } 381 382 !0 = !{} 383... 384--- 385name: imp_null_check_with_bitwise_op_0 386# CHECK-LABEL: name: imp_null_check_with_bitwise_op_0 387alignment: 4 388tracksRegLiveness: true 389liveins: 390 - { reg: '%rdi' } 391 - { reg: '%esi' } 392# CHECK: bb.0.entry: 393# CHECK: %eax = MOV32ri 2200000 394# CHECK-NEXT: %eax = FAULTING_OP 1, %bb.3.is_null, {{[0-9]+}}, %eax, %rdi, 1, _, 0, _, implicit-def %eflags :: (load 4 from %ir.x) 395# CHECK-NEXT: JMP_1 %bb.1.not_null 396 397body: | 398 bb.0.entry: 399 liveins: %esi, %rdi 400 401 TEST64rr %rdi, %rdi, implicit-def %eflags 402 JE_1 %bb.3.is_null, implicit %eflags 403 404 bb.1.not_null: 405 liveins: %esi, %rdi 406 407 %eax = MOV32ri 2200000 408 %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 409 CMP32rr killed %eax, killed %esi, implicit-def %eflags 410 JE_1 %bb.4.ret_100, implicit %eflags 411 412 bb.2.ret_200: 413 %eax = MOV32ri 200 414 RETQ %eax 415 416 bb.3.is_null: 417 %eax = MOV32ri 42 418 RETQ %eax 419 420 bb.4.ret_100: 421 %eax = MOV32ri 100 422 RETQ %eax 423 424... 425--- 426name: imp_null_check_with_bitwise_op_1 427alignment: 4 428tracksRegLiveness: true 429liveins: 430 - { reg: '%rdi' } 431 - { reg: '%esi' } 432 - { reg: '%rdx' } 433# CHECK: bb.0.entry: 434# CHECK: %eax = MOV32rm killed %rdx, 1, _, 0, _ :: (volatile load 4 from %ir.ptr) 435# CHECK-NEXT: TEST64rr %rdi, %rdi, implicit-def %eflags 436# CHECK-NEXT: JE_1 %bb.3.is_null, implicit %eflags 437 438body: | 439 bb.0.entry: 440 liveins: %esi, %rdi, %rdx 441 442 %eax = MOV32rm killed %rdx, 1, _, 0, _ :: (volatile load 4 from %ir.ptr) 443 TEST64rr %rdi, %rdi, implicit-def %eflags 444 JE_1 %bb.3.is_null, implicit %eflags 445 446 bb.1.not_null: 447 liveins: %esi, %rdi 448 449 %eax = MOV32ri 2200000 450 %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 451 CMP32rr killed %eax, killed %esi, implicit-def %eflags 452 JE_1 %bb.4.ret_100, implicit %eflags 453 454 bb.2.ret_200: 455 456 %eax = MOV32ri 200 457 458 bb.3.is_null: 459 liveins: %eax, %ah, %al, %ax, %bh, %bl, %bp, %bpl, %bx, %eax, %ebp, %ebx, %rax, %rbp, %rbx, %r12, %r13, %r14, %r15, %r12b, %r13b, %r14b, %r15b, %r12d, %r13d, %r14d, %r15d, %r12w, %r13w, %r14w, %r15w 460 461 RETQ %eax 462 463 bb.4.ret_100: 464 %eax = MOV32ri 100 465 RETQ %eax 466 467... 468--- 469name: imp_null_check_with_bitwise_op_2 470# CHECK-LABEL: name: imp_null_check_with_bitwise_op_2 471alignment: 4 472tracksRegLiveness: true 473liveins: 474 - { reg: '%rdi' } 475 - { reg: '%esi' } 476# CHECK: bb.0.entry: 477# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 478# CHECK-NEXT: JE_1 %bb.3.is_null, implicit %eflags 479 480body: | 481 bb.0.entry: 482 liveins: %esi, %rdi 483 484 TEST64rr %rdi, %rdi, implicit-def %eflags 485 JE_1 %bb.3.is_null, implicit %eflags 486 487 bb.1.not_null: 488 liveins: %esi, %rdi 489 490 %eax = MOV32ri 2200000 491 %eax = ADD32ri killed %eax, 100, implicit-def dead %eflags 492 %eax = AND32rm killed %eax, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 493 CMP32rr killed %eax, killed %esi, implicit-def %eflags 494 JE_1 %bb.4.ret_100, implicit %eflags 495 496 bb.2.ret_200: 497 %eax = MOV32ri 200 498 RETQ %eax 499 500 bb.3.is_null: 501 %eax = MOV32ri 42 502 RETQ %eax 503 504 bb.4.ret_100: 505 %eax = MOV32ri 100 506 RETQ %eax 507 508... 509--- 510name: imp_null_check_with_bitwise_op_3 511# CHECK-LABEL: name: imp_null_check_with_bitwise_op_3 512alignment: 4 513tracksRegLiveness: true 514liveins: 515 - { reg: '%rdi' } 516 - { reg: '%rsi' } 517# CHECK: bb.0.entry: 518# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 519# CHECK-NEXT: JE_1 %bb.3.is_null, implicit %eflags 520 521body: | 522 bb.0.entry: 523 liveins: %rsi, %rdi 524 525 TEST64rr %rdi, %rdi, implicit-def %eflags 526 JE_1 %bb.3.is_null, implicit %eflags 527 528 bb.1.not_null: 529 liveins: %rsi, %rdi 530 531 %rdi = MOV64ri 5000 532 %rdi = AND64rm killed %rdi, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 533 CMP64rr killed %rdi, killed %rsi, implicit-def %eflags 534 JE_1 %bb.4.ret_100, implicit %eflags 535 536 bb.2.ret_200: 537 %eax = MOV32ri 200 538 RETQ %eax 539 540 bb.3.is_null: 541 %eax = MOV32ri 42 542 RETQ %eax 543 544 bb.4.ret_100: 545 %eax = MOV32ri 100 546 RETQ %eax 547 548... 549--- 550name: imp_null_check_with_bitwise_op_4 551# CHECK-LABEL: name: imp_null_check_with_bitwise_op_4 552alignment: 4 553tracksRegLiveness: true 554liveins: 555 - { reg: '%rdi' } 556 - { reg: '%rsi' } 557# CHECK: bb.0.entry: 558# CHECK: %rbx = MOV64rr %rdx 559# CHECK-NEXT: %rbx = FAULTING_OP 1, %bb.3.is_null, {{[0-9]+}}, %rbx, %rdi, 1, _, 0, _, implicit-def %eflags :: (load 4 from %ir.x) 560 561body: | 562 bb.0.entry: 563 liveins: %rsi, %rdi, %rdx 564 565 TEST64rr %rdi, %rdi, implicit-def %eflags 566 JE_1 %bb.3.is_null, implicit %eflags 567 568 bb.1.not_null: 569 liveins: %rsi, %rdi, %rdx 570 571 %rbx = MOV64rr %rdx 572 %rbx = AND64rm killed %rbx, killed %rdi, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.x) 573 %rdx = MOV64ri 0 574 CMP64rr killed %rbx, killed %rsi, implicit-def %eflags 575 JE_1 %bb.4.ret_100, implicit %eflags 576 577 bb.2.ret_200: 578 %eax = MOV32ri 200 579 RETQ %eax 580 581 bb.3.is_null: 582 %eax = MOV32ri 42 583 RETQ %eax 584 585 bb.4.ret_100: 586 %eax = MOV32ri 100 587 RETQ %eax 588 589... 590--- 591name: no_hoist_across_call 592# CHECK-LABEL: name: no_hoist_across_call 593alignment: 4 594tracksRegLiveness: true 595liveins: 596 - { reg: '%rdi' } 597calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx', 598 '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15', 599 '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d', 600 '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ] 601# CHECK: body: 602# CHECK-NOT: FAULTING_OP 603# CHECK: bb.1.stay: 604# CHECK: CALL64pcrel32 605body: | 606 bb.0.entry: 607 liveins: %rdi, %rbx 608 609 frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp 610 CFI_INSTRUCTION def_cfa_offset 16 611 CFI_INSTRUCTION offset %rbx, -16 612 %rbx = MOV64rr %rdi 613 TEST64rr %rbx, %rbx, implicit-def %eflags 614 JE_1 %bb.2.leave, implicit killed %eflags 615 616 bb.1.stay: 617 liveins: %rbx 618 619 CALL64pcrel32 @f, csr_64, implicit %rsp, implicit-def %rsp 620 %eax = MOV32rm killed %rbx, 1, _, 0, _ :: (load 4 from %ir.ptr) 621 %rbx = POP64r implicit-def %rsp, implicit %rsp 622 RETQ %eax 623 624 bb.2.leave: 625 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 626 %rbx = POP64r implicit-def %rsp, implicit %rsp 627 RETQ %eax 628 629... 630--- 631name: dependency_live_in_hazard 632# CHECK-LABEL: name: dependency_live_in_hazard 633# CHECK: bb.0.entry: 634# CHECK-NOT: FAULTING_OP 635# CHECK: bb.1.not_null: 636 637# Make sure that the BEXTR32rm instruction below is not used to emit 638# an implicit null check -- hoisting it will require hosting the move 639# to %esi and we cannot do that without clobbering the use of %rsi in 640# the first instruction in bb.1.not_null. 641alignment: 4 642tracksRegLiveness: true 643liveins: 644 - { reg: '%rdi' } 645 - { reg: '%rsi' } 646body: | 647 bb.0.entry: 648 liveins: %rdi, %rsi 649 650 TEST64rr %rdi, %rdi, implicit-def %eflags 651 JE_1 %bb.2.is_null, implicit killed %eflags 652 653 bb.1.not_null: 654 liveins: %rdi, %rsi 655 656 %rcx = MOV64rm killed %rsi, 1, _, 0, _ :: (load 8 from %ir.ptr2) 657 %esi = MOV32ri 3076 658 %eax = BEXTR32rm killed %rdi, 1, _, 0, _, killed %esi, implicit-def dead %eflags :: (load 4 from %ir.ptr) 659 %eax = ADD32rm killed %eax, killed %rcx, 1, _, 0, _, implicit-def dead %eflags :: (load 4 from %ir.val) 660 RETQ %eax 661 662 bb.2.is_null: 663 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 664 RETQ %eax 665 666... 667--- 668name: use_alternate_load_op 669# CHECK-LABEL: name: use_alternate_load_op 670# CHECK: bb.0.entry: 671# CHECK: %rax = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _ 672# CHECK-NEXT: JMP_1 %bb.1.not_null 673# CHECK: bb.1.not_null 674 675alignment: 4 676tracksRegLiveness: true 677liveins: 678 - { reg: '%rdi' } 679 - { reg: '%rsi' } 680body: | 681 bb.0.entry: 682 liveins: %rdi, %rsi 683 684 TEST64rr %rdi, %rdi, implicit-def %eflags 685 JE_1 %bb.2.is_null, implicit killed %eflags 686 687 bb.1.not_null: 688 liveins: %rdi, %rsi 689 690 %rcx = MOV64rm killed %rsi, 1, _, 0, _ 691 %rcx = AND64rm killed %rcx, %rdi, 1, _, 0, _, implicit-def dead %eflags 692 %rax = MOV64rm killed %rdi, 1, _, 0, _ 693 RETQ %eax 694 695 bb.2.is_null: 696 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 697 RETQ %eax 698 699... 700--- 701name: imp_null_check_gep_load_with_use_dep 702# CHECK-LABEL: name: imp_null_check_gep_load_with_use_dep 703# CHECK: bb.0.entry: 704# CHECK: %eax = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.x) 705# CHECK-NEXT: JMP_1 %bb.1.not_null 706alignment: 4 707tracksRegLiveness: true 708liveins: 709 - { reg: '%rdi' } 710 - { reg: '%rsi' } 711body: | 712 bb.0.entry: 713 liveins: %rsi, %rdi 714 715 TEST64rr %rdi, %rdi, implicit-def %eflags 716 JE_1 %bb.1.is_null, implicit %eflags 717 718 bb.2.not_null: 719 liveins: %rdi, %rsi 720 721 %rsi = ADD64rr %rsi, %rdi, implicit-def dead %eflags 722 %eax = MOV32rm killed %rdi, 1, _, 0, _, implicit-def %rax :: (load 4 from %ir.x) 723 %eax = LEA64_32r killed %rax, 1, killed %rsi, 4, _ 724 RETQ %eax 725 726 bb.1.is_null: 727 %eax = MOV32ri 42 728 RETQ %eax 729 730... 731--- 732name: imp_null_check_load_with_base_sep 733# CHECK-LABEL: name: imp_null_check_load_with_base_sep 734# CHECK: bb.0.entry: 735# CHECK: %rsi = ADD64rr %rsi, %rdi, implicit-def dead %eflags 736# CHECK-NEXT: %esi = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, %esi, %rdi, 1, _, 0, _, implicit-def %eflags 737# CHECK-NEXT: JMP_1 %bb.1.not_null 738alignment: 4 739tracksRegLiveness: true 740liveins: 741 - { reg: '%rdi' } 742 - { reg: '%rsi' } 743body: | 744 bb.0.entry: 745 liveins: %rsi, %rdi 746 747 TEST64rr %rdi, %rdi, implicit-def %eflags 748 JE_1 %bb.1.is_null, implicit %eflags 749 750 bb.2.not_null: 751 liveins: %rdi, %rsi 752 753 %rsi = ADD64rr %rsi, %rdi, implicit-def dead %eflags 754 %esi = AND32rm killed %esi, %rdi, 1, _, 0, _, implicit-def dead %eflags 755 %eax = MOV32rr %esi 756 RETQ %eax 757 758 bb.1.is_null: 759 %eax = MOV32ri 42 760 RETQ %eax 761 762... 763--- 764name: inc_store 765# CHECK-LABEL: name: inc_store 766# CHECK: bb.0.entry: 767# CHECK: _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _, %rsi 768# CHECK-NEXT: JMP_1 %bb.1.not_null 769# CHECK: bb.1.not_null 770 771alignment: 4 772tracksRegLiveness: true 773liveins: 774 - { reg: '%rdi' } 775 - { reg: '%rsi' } 776body: | 777 bb.0.entry: 778 liveins: %rdi, %rsi 779 780 TEST64rr %rdi, %rdi, implicit-def %eflags 781 JE_1 %bb.2.is_null, implicit killed %eflags 782 783 bb.1.not_null: 784 liveins: %rdi, %rsi 785 786 MOV64mr killed %rdi, 1, _, 0, _, killed %rsi 787 RETQ 788 789 bb.2.is_null: 790 RETQ 791 792... 793--- 794name: inc_store_plus_offset 795# CHECK-LABEL: inc_store_plus_offset 796# CHECK: bb.0.entry: 797# CHECK: _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 16, _, %rsi 798# CHECK-NEXT: JMP_1 %bb.1.not_null 799# CHECK: bb.1.not_null 800 801alignment: 4 802tracksRegLiveness: true 803liveins: 804 - { reg: '%rdi' } 805 - { reg: '%rsi' } 806body: | 807 bb.0.entry: 808 liveins: %rdi, %rsi 809 810 TEST64rr %rdi, %rdi, implicit-def %eflags 811 JE_1 %bb.2.is_null, implicit killed %eflags 812 813 bb.1.not_null: 814 liveins: %rdi, %rsi 815 816 MOV64mr killed %rdi, 1, _, 16, _, killed %rsi 817 RETQ 818 819 bb.2.is_null: 820 RETQ 821 822... 823--- 824name: inc_store_with_dep 825# CHECK-LABEL: inc_store_with_dep 826# CHECK: bb.0.entry: 827# CHECK: %esi = ADD32rr killed %esi, killed %esi, implicit-def dead %eflags 828# CHECK-NEXT: _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 16, _, %esi 829# CHECK-NEXT: JMP_1 %bb.1.not_null 830# CHECK: bb.1.not_null 831 832alignment: 4 833tracksRegLiveness: true 834liveins: 835 - { reg: '%rdi' } 836 - { reg: '%rsi' } 837body: | 838 bb.0.entry: 839 liveins: %rdi, %rsi 840 841 TEST64rr %rdi, %rdi, implicit-def %eflags 842 JE_1 %bb.2.is_null, implicit killed %eflags 843 844 bb.1.not_null: 845 liveins: %rdi, %rsi 846 847 %esi = ADD32rr killed %esi, killed %esi, implicit-def dead %eflags 848 MOV32mr killed %rdi, 1, _, 16, _, killed %esi 849 RETQ 850 851 bb.2.is_null: 852 RETQ 853 854... 855--- 856name: inc_store_with_dep_in_null 857# CHECK-LABEL: inc_store_with_dep_in_null 858# CHECK: bb.0.entry: 859# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 860# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 861# CHECK: bb.1.not_null 862 863alignment: 4 864tracksRegLiveness: true 865liveins: 866 - { reg: '%rdi' } 867 - { reg: '%rsi' } 868body: | 869 bb.0.entry: 870 liveins: %rdi, %rsi 871 872 TEST64rr %rdi, %rdi, implicit-def %eflags 873 JE_1 %bb.2.is_null, implicit killed %eflags 874 875 bb.1.not_null: 876 liveins: %rdi, %rsi 877 878 %esi = ADD32rr %esi, %esi, implicit-def dead %eflags 879 MOV32mr killed %rdi, 1, _, 0, _, %esi 880 %eax = MOV32rr killed %esi 881 RETQ %eax 882 883 bb.2.is_null: 884 liveins: %rsi 885 886 %eax = MOV32rr killed %esi 887 RETQ %eax 888 889... 890--- 891name: inc_store_with_volatile 892# CHECK-LABEL: inc_store_with_volatile 893# CHECK: bb.0.entry: 894# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 895# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 896# CHECK: bb.1.not_null 897 898alignment: 4 899tracksRegLiveness: true 900liveins: 901 - { reg: '%rdi' } 902 - { reg: '%rsi' } 903body: | 904 bb.0.entry: 905 liveins: %rdi, %rsi 906 907 TEST64rr %rdi, %rdi, implicit-def %eflags 908 JE_1 %bb.2.is_null, implicit killed %eflags 909 910 bb.1.not_null: 911 liveins: %rdi, %rsi 912 913 MOV32mr killed %rdi, 1, _, 0, _, killed %esi :: (volatile store 4 into %ir.ptr) 914 RETQ 915 916 bb.2.is_null: 917 RETQ 918 919... 920--- 921name: inc_store_with_two_dep 922# CHECK-LABEL: inc_store_with_two_dep 923# CHECK: bb.0.entry: 924# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 925# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 926# CHECK: bb.1.not_null 927 928alignment: 4 929tracksRegLiveness: true 930liveins: 931 - { reg: '%rdi' } 932 - { reg: '%rsi' } 933body: | 934 bb.0.entry: 935 liveins: %rdi, %rsi 936 937 TEST64rr %rdi, %rdi, implicit-def %eflags 938 JE_1 %bb.2.is_null, implicit killed %eflags 939 940 bb.1.not_null: 941 liveins: %rdi, %rsi 942 943 %esi = ADD32rr killed %esi, killed %esi, implicit-def dead %eflags 944 %esi = ADD32ri killed %esi, 15, implicit-def dead %eflags 945 MOV32mr killed %rdi, 1, _, 16, _, killed %esi 946 RETQ 947 948 bb.2.is_null: 949 RETQ 950 951... 952--- 953name: inc_store_with_redefined_base 954# CHECK-LABEL: inc_store_with_redefined_base 955# CHECK: bb.0.entry: 956# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 957# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 958# CHECK: bb.1.not_null 959 960alignment: 4 961tracksRegLiveness: true 962liveins: 963 - { reg: '%rdi' } 964 - { reg: '%rsi' } 965body: | 966 bb.0.entry: 967 liveins: %rdi, %rsi 968 969 TEST64rr %rdi, %rdi, implicit-def %eflags 970 JE_1 %bb.2.is_null, implicit killed %eflags 971 972 bb.1.not_null: 973 liveins: %rdi, %rsi 974 975 %rdi = ADD64rr killed %rdi, killed %rdi, implicit-def dead %eflags 976 MOV32mr killed %rdi, 1, _, 16, _, killed %esi 977 RETQ 978 979 bb.2.is_null: 980 RETQ 981 982... 983--- 984name: inc_store_with_reused_base 985# CHECK-LABEL: inc_store_with_reused_base 986# CHECK: bb.0.entry: 987# CHECK: _ = FAULTING_OP 3, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 16, _, %esi 988# CHECK-NEXT: JMP_1 %bb.1.not_null 989# CHECK: bb.1.not_null 990 991alignment: 4 992tracksRegLiveness: true 993liveins: 994 - { reg: '%rdi' } 995 - { reg: '%rsi' } 996body: | 997 bb.0.entry: 998 liveins: %rdi, %rsi 999 1000 TEST64rr %rdi, %rdi, implicit-def %eflags 1001 JE_1 %bb.2.is_null, implicit killed %eflags 1002 1003 bb.1.not_null: 1004 liveins: %rdi, %rsi 1005 1006 %rax = MOV64rr %rdi 1007 MOV32mr killed %rdi, 1, _, 16, _, killed %esi 1008 RETQ %eax 1009 1010 bb.2.is_null: 1011 %rax = XOR64rr undef %rax, undef %rax, implicit-def dead %eflags 1012 RETQ %eax 1013 1014... 1015--- 1016name: inc_store_across_call 1017# CHECK-LABEL: inc_store_across_call 1018# CHECK: bb.0.entry: 1019# CHECK: TEST64rr %rbx, %rbx, implicit-def %eflags 1020# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 1021# CHECK: bb.1.not_null 1022 1023alignment: 4 1024tracksRegLiveness: true 1025liveins: 1026 - { reg: '%rdi' } 1027calleeSavedRegisters: [ '%bh', '%bl', '%bp', '%bpl', '%bx', '%ebp', '%ebx', 1028 '%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15', 1029 '%r12b', '%r13b', '%r14b', '%r15b', '%r12d', '%r13d', 1030 '%r14d', '%r15d', '%r12w', '%r13w', '%r14w', '%r15w' ] 1031body: | 1032 bb.0.entry: 1033 liveins: %rdi, %rbx 1034 1035 frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp 1036 CFI_INSTRUCTION def_cfa_offset 16 1037 CFI_INSTRUCTION offset %rbx, -16 1038 %rbx = MOV64rr killed %rdi 1039 TEST64rr %rbx, %rbx, implicit-def %eflags 1040 JE_1 %bb.2.is_null, implicit killed %eflags 1041 1042 bb.1.not_null: 1043 liveins: %rbx 1044 1045 CALL64pcrel32 @f, csr_64, implicit %rsp, implicit-def %rsp 1046 MOV32mi %rbx, 1, _, 0, _, 20 1047 %rax = MOV64rr killed %rbx 1048 %rbx = POP64r implicit-def %rsp, implicit %rsp 1049 RETQ %eax 1050 1051 bb.2.is_null: 1052 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 1053 %rbx = POP64r implicit-def %rsp, implicit %rsp 1054 RETQ %eax 1055 1056... 1057--- 1058name: inc_store_with_dep_in_dep 1059# CHECK-LABEL: inc_store_with_dep_in_dep 1060# CHECK: bb.0.entry: 1061# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 1062# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 1063# CHECK: bb.1.not_null 1064 1065alignment: 4 1066tracksRegLiveness: true 1067liveins: 1068 - { reg: '%rdi' } 1069 - { reg: '%rsi' } 1070body: | 1071 bb.0.entry: 1072 liveins: %rdi, %rsi 1073 1074 TEST64rr %rdi, %rdi, implicit-def %eflags 1075 JE_1 %bb.2.is_null, implicit killed %eflags 1076 1077 bb.1.not_null: 1078 liveins: %rdi, %rsi 1079 1080 %eax = MOV32rr %esi 1081 %esi = ADD32ri killed %esi, 15, implicit-def dead %eflags 1082 MOV32mr killed %rdi, 1, _, 0, _, killed %esi 1083 RETQ %eax 1084 1085 bb.2.is_null: 1086 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 1087 RETQ %eax 1088 1089... 1090--- 1091name: inc_store_with_load_over_store 1092# CHECK-LABEL: inc_store_with_load_over_store 1093# CHECK: bb.0.entry: 1094# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 1095# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 1096# CHECK: bb.1.not_null 1097 1098alignment: 4 1099tracksRegLiveness: true 1100liveins: 1101 - { reg: '%rdi' } 1102 - { reg: '%rsi' } 1103body: | 1104 bb.0.entry: 1105 liveins: %rdi, %rsi 1106 1107 TEST64rr %rdi, %rdi, implicit-def %eflags 1108 JE_1 %bb.2.is_null, implicit killed %eflags 1109 1110 bb.1.not_null: 1111 liveins: %rdi, %rsi 1112 1113 MOV32mi killed %rsi, 1, _, 0, _, 2 1114 %eax = MOV32rm killed %rdi, 1, _, 0, _ 1115 RETQ %eax 1116 1117 bb.2.is_null: 1118 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 1119 RETQ %eax 1120 1121... 1122--- 1123name: inc_store_with_store_over_load 1124# CHECK-LABEL: inc_store_with_store_over_load 1125# CHECK: bb.0.entry: 1126# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 1127# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 1128# CHECK: bb.1.not_null 1129 1130alignment: 4 1131tracksRegLiveness: true 1132liveins: 1133 - { reg: '%rdi' } 1134 - { reg: '%rsi' } 1135body: | 1136 bb.0.entry: 1137 liveins: %rdi, %rsi 1138 1139 TEST64rr %rdi, %rdi, implicit-def %eflags 1140 JE_1 %bb.2.is_null, implicit killed %eflags 1141 1142 bb.1.not_null: 1143 liveins: %rdi, %rsi 1144 1145 %eax = MOV32rm killed %rsi, 1, _, 0, _ 1146 MOV32mi killed %rdi, 1, _, 0, _, 2 1147 RETQ %eax 1148 1149 bb.2.is_null: 1150 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 1151 RETQ %eax 1152 1153... 1154--- 1155name: inc_store_with_store_over_store 1156# CHECK-LABEL: inc_store_with_store_over_store 1157# CHECK: bb.0.entry: 1158# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 1159# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 1160# CHECK: bb.1.not_null 1161 1162alignment: 4 1163tracksRegLiveness: true 1164liveins: 1165 - { reg: '%rdi' } 1166 - { reg: '%rsi' } 1167body: | 1168 bb.0.entry: 1169 liveins: %rdi, %rsi 1170 1171 TEST64rr %rdi, %rdi, implicit-def %eflags 1172 JE_1 %bb.2.is_null, implicit killed %eflags 1173 1174 bb.1.not_null: 1175 liveins: %rdi, %rsi 1176 1177 MOV32mi killed %rsi, 1, _, 0, _, 3 1178 MOV32mi killed %rdi, 1, _, 0, _, 2 1179 RETQ 1180 1181 bb.2.is_null: 1182 RETQ 1183 1184... 1185--- 1186name: inc_store_with_load_and_store 1187# CHECK-LABEL: inc_store_with_load_and_store 1188# CHECK: bb.0.entry: 1189# CHECK: _ = FAULTING_OP 2, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _, %esi, implicit-def %eflags 1190# CHECK-NEXT: JMP_1 %bb.1.not_null 1191# CHECK: bb.1.not_null 1192 1193alignment: 4 1194tracksRegLiveness: true 1195liveins: 1196 - { reg: '%rdi' } 1197 - { reg: '%rsi' } 1198body: | 1199 bb.0.entry: 1200 liveins: %rdi, %rsi 1201 1202 TEST64rr %rdi, %rdi, implicit-def %eflags 1203 JE_1 %bb.2.is_null, implicit killed %eflags 1204 1205 bb.1.not_null: 1206 liveins: %rdi, %rsi 1207 1208 %esi = ADD32rr %esi, %esi, implicit-def dead %eflags 1209 ADD32mr killed %rdi, 1, _, 0, _, killed %esi, implicit-def dead %eflags 1210 RETQ 1211 1212 bb.2.is_null: 1213 RETQ 1214 1215... 1216--- 1217name: inc_store_and_load_no_alias 1218# CHECK-LABEL: inc_store_and_load_no_alias 1219# CHECK: bb.0.entry: 1220# CHECK: %eax = FAULTING_OP 1, %bb.2.is_null, {{[0-9]+}}, %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr) 1221# CHECK-NEXT: JMP_1 %bb.1.not_null 1222# CHECK: bb.1.not_null 1223 1224alignment: 4 1225tracksRegLiveness: true 1226liveins: 1227 - { reg: '%rdi' } 1228 - { reg: '%rsi' } 1229body: | 1230 bb.0.entry: 1231 liveins: %rdi, %rsi 1232 1233 TEST64rr %rdi, %rdi, implicit-def %eflags 1234 JE_1 %bb.2.is_null, implicit killed %eflags 1235 1236 bb.1.not_null: 1237 liveins: %rdi, %rsi 1238 1239 MOV32mi killed %rsi, 1, _, 0, _, 3 :: (store 4 into %ir.ptr2) 1240 %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr) 1241 RETQ %eax 1242 1243 bb.2.is_null: 1244 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 1245 RETQ %eax 1246 1247... 1248--- 1249name: inc_store_and_load_alias 1250# CHECK-LABEL: inc_store_and_load_alias 1251# CHECK: bb.0.entry: 1252# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 1253# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 1254# CHECK: bb.1.not_null 1255 1256alignment: 4 1257tracksRegLiveness: true 1258liveins: 1259 - { reg: '%rdi' } 1260 - { reg: '%rsi' } 1261body: | 1262 bb.0.entry: 1263 liveins: %rdi, %rsi 1264 1265 TEST64rr %rdi, %rdi, implicit-def %eflags 1266 JE_1 %bb.2.is_null, implicit killed %eflags 1267 1268 bb.1.not_null: 1269 liveins: %rdi, %rsi 1270 1271 MOV32mi killed %rsi, 1, _, 0, _, 3 :: (store 4 into %ir.ptr2) 1272 %eax = MOV32rm killed %rdi, 1, _, 0, _ :: (load 4 from %ir.ptr) 1273 RETQ %eax 1274 1275 bb.2.is_null: 1276 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 1277 RETQ %eax 1278 1279... 1280--- 1281name: inc_spill_dep 1282# CHECK-LABEL: inc_spill_dep 1283# CHECK: bb.0.entry: 1284# CHECK: TEST64rr %rdi, %rdi, implicit-def %eflags 1285# CHECK-NEXT: JE_1 %bb.2.is_null, implicit killed %eflags 1286# CHECK: bb.1.not_null 1287 1288alignment: 4 1289tracksRegLiveness: true 1290stack: 1291 - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8} 1292liveins: 1293 - { reg: '%rdi' } 1294 - { reg: '%rsi' } 1295body: | 1296 bb.0.entry: 1297 liveins: %rdi, %rsi 1298 1299 %rsp = frame-setup SUB64ri8 %rsp, 8, implicit-def dead %eflags 1300 MOV32mr %rsp, 1, %noreg, 0, %noreg, %esi :: (store 4 into %stack.0) 1301 TEST64rr %rdi, %rdi, implicit-def %eflags 1302 JE_1 %bb.2.is_null, implicit killed %eflags 1303 1304 bb.1.not_null: 1305 liveins: %rdi, %rsi 1306 1307 %r14d = MOV32rm %rsp, 1, %noreg, 0, %noreg :: (load 4 from %stack.0) 1308 MOV64mr %rsp, 1, %noreg, 0, %noreg, %rdi :: (store 8 into %stack.0) 1309 %edi = MOV32rm %rdi, 1, %noreg, 8, %noreg :: (load 4 from %ir.ptr) 1310 %eax = MOV32rr %edi 1311 RETQ %eax 1312 1313 bb.2.is_null: 1314 %eax = XOR32rr undef %eax, undef %eax, implicit-def dead %eflags 1315 RETQ %eax 1316 1317... 1318