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(ptr %x, i32 %val, i1 %arg) { 9 entry: 10 br i1 %arg, label %is_null, label %not_null, !make.implicit !0 11 12 is_null: 13 ret i32 42 14 15 not_null: 16 br i1 %arg, 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(ptr %x, i32 %val, ptr %ptr, i1 %arg) { 28 entry: 29 br i1 %arg, label %is_null, label %not_null, !make.implicit !0 30 31 is_null: 32 ret i32 undef 33 34 not_null: 35 br i1 %arg, 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(ptr %x, i32 %val, i1 %arg) { 47 entry: 48 br i1 %arg, label %is_null, label %not_null, !make.implicit !0 49 50 is_null: 51 ret i32 42 52 53 not_null: 54 br i1 %arg, 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(ptr %x, i32 %val, i1 %arg) { 66 entry: 67 br i1 %arg, label %is_null, label %not_null, !make.implicit !0 68 69 is_null: 70 ret i32 42 71 72 not_null: 73 br i1 %arg, 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(ptr %x, i32 %val, i1 %arg) { 84 entry: 85 br i1 %arg, label %is_null, label %not_null, !make.implicit !0 86 87 is_null: 88 ret i32 42 89 90 not_null: 91 br i1 %arg, 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(ptr %ptr) { 103 entry: 104 %is_null = icmp eq ptr %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, ptr %ptr 110 ret i32 %val 111 112 leave: 113 ret i32 0 114 } 115 116 define i32 @dependency_live_in_hazard(ptr %ptr, ptr %ptr2, ptr %ptr3) #0 { 117 entry: 118 %val = load ptr, ptr %ptr2 119 %ptr_is_null = icmp eq ptr %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, ptr %val 124 %result = load i32, ptr %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(ptr %ptr, ptr %ptr2) { 135 entry: 136 %ptr_is_null = icmp eq ptr %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(ptr %x, i32 %a) { 147 entry: 148 %c = icmp eq ptr %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, ptr %x, i32 1 156 %y = ptrtoint ptr %x.loc to i32 157 %b = add i32 %a, %y 158 %t = load i32, ptr %x 159 %z = add i32 %t, %b 160 ret i32 %z 161 } 162 163 define i32 @imp_null_check_load_with_base_sep(ptr %x, i32 %a) { 164 entry: 165 %c = icmp eq ptr %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(ptr %ptr, i32 %val) { 176 entry: 177 %ptr_is_null = icmp eq ptr %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(ptr %ptr, i32 %val) { 188 entry: 189 %ptr_is_null = icmp eq ptr %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(ptr %ptr, i32 %val) { 200 entry: 201 %ptr_is_null = icmp eq ptr %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(ptr %ptr, i32 %val) { 212 entry: 213 %ptr_is_null = icmp eq ptr %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(ptr %ptr, i32 %val) { 224 entry: 225 %ptr_is_null = icmp eq ptr %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(ptr %ptr, i32 %val) { 236 entry: 237 %ptr_is_null = icmp eq ptr %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(ptr %ptr, i32 %val) { 248 entry: 249 %ptr_is_null = icmp eq ptr %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(ptr %ptr, i32 %val) { 260 entry: 261 %ptr_is_null = icmp eq ptr %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(ptr %ptr) { 272 entry: 273 %ptr_is_null = icmp eq ptr %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(ptr %ptr, i32 %val) { 285 entry: 286 %ptr_is_null = icmp eq ptr %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(ptr %ptr, ptr %ptr2) { 297 entry: 298 %ptr_is_null = icmp eq ptr %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(ptr %ptr, ptr %ptr2) { 309 entry: 310 %ptr_is_null = icmp eq ptr %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(ptr %ptr, ptr %ptr2) { 321 entry: 322 %ptr_is_null = icmp eq ptr %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(ptr %ptr, ptr %ptr2) { 333 entry: 334 %ptr_is_null = icmp eq ptr %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(ptr noalias %ptr, ptr noalias %ptr2) { 345 entry: 346 %ptr_is_null = icmp eq ptr %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(ptr %ptr, ptr %ptr2) { 357 entry: 358 %ptr_is_null = icmp eq ptr %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(ptr %ptr, i32 %val) { 369 entry: 370 %ptr_is_null = icmp eq ptr %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 define i32 @imp_null_check_address_mul_overflow(ptr %x, i32 %a) { 381 entry: 382 %c = icmp eq ptr %x, null 383 br i1 %c, label %is_null, label %not_null, !make.implicit !0 384 385 is_null: ; preds = %entry 386 ret i32 42 387 388 not_null: ; preds = %entry 389 %y = ptrtoint ptr %x to i32 390 %y64 = zext i32 %y to i64 391 %b = mul i64 %y64, 9223372036854775807 ; 0X0FFFF.. i.e. 2^63 - 1 392 %z = trunc i64 %b to i32 393 ret i32 %z 394 } 395 396 attributes #0 = { "target-features"="+bmi,+bmi2" } 397 398 !0 = !{} 399... 400--- 401name: imp_null_check_with_bitwise_op_0 402# CHECK-LABEL: name: imp_null_check_with_bitwise_op_0 403alignment: 16 404tracksRegLiveness: true 405liveins: 406 - { reg: '$rdi' } 407 - { reg: '$esi' } 408# CHECK: bb.0.entry: 409# CHECK: $eax = MOV32ri 2200000 410# CHECK-NEXT: $eax = FAULTING_OP 1, %bb.3, {{[0-9]+}}, $eax, $rdi, 1, $noreg, 0, $noreg, implicit-def $eflags :: (load (s32) from %ir.x) 411# CHECK-NEXT: JMP_1 %bb.1 412 413body: | 414 bb.0.entry: 415 liveins: $esi, $rdi 416 417 TEST64rr $rdi, $rdi, implicit-def $eflags 418 JCC_1 %bb.3, 4, implicit $eflags 419 420 bb.1.not_null: 421 liveins: $esi, $rdi 422 423 $eax = MOV32ri 2200000 424 $eax = AND32rm killed $eax, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x) 425 CMP32rr killed $eax, killed $esi, implicit-def $eflags 426 JCC_1 %bb.4, 4, implicit $eflags 427 428 bb.2.ret_200: 429 $eax = MOV32ri 200 430 RET64 $eax 431 432 bb.3.is_null: 433 $eax = MOV32ri 42 434 RET64 $eax 435 436 bb.4.ret_100: 437 $eax = MOV32ri 100 438 RET64 $eax 439 440... 441--- 442name: imp_null_check_with_bitwise_op_1 443alignment: 16 444tracksRegLiveness: true 445liveins: 446 - { reg: '$rdi' } 447 - { reg: '$esi' } 448 - { reg: '$rdx' } 449# CHECK: bb.0.entry: 450# CHECK: $eax = MOV32rm killed $rdx, 1, $noreg, 0, $noreg :: (volatile load (s32) from %ir.ptr) 451# CHECK-NEXT: TEST64rr $rdi, $rdi, implicit-def $eflags 452# CHECK-NEXT: JCC_1 %bb.3, 4, implicit $eflags 453 454body: | 455 bb.0.entry: 456 liveins: $esi, $rdi, $rdx 457 458 $eax = MOV32rm killed $rdx, 1, $noreg, 0, $noreg :: (volatile load (s32) from %ir.ptr) 459 TEST64rr $rdi, $rdi, implicit-def $eflags 460 JCC_1 %bb.3, 4, implicit $eflags 461 462 bb.1.not_null: 463 liveins: $esi, $rdi 464 465 $eax = MOV32ri 2200000 466 $eax = AND32rm killed $eax, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x) 467 CMP32rr killed $eax, killed $esi, implicit-def $eflags 468 JCC_1 %bb.4, 4, implicit $eflags 469 470 bb.2.ret_200: 471 472 $eax = MOV32ri 200 473 474 bb.3.is_null: 475 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 476 477 RET64 $eax 478 479 bb.4.ret_100: 480 $eax = MOV32ri 100 481 RET64 $eax 482 483... 484--- 485name: imp_null_check_with_bitwise_op_2 486# CHECK-LABEL: name: imp_null_check_with_bitwise_op_2 487alignment: 16 488tracksRegLiveness: true 489liveins: 490 - { reg: '$rdi' } 491 - { reg: '$esi' } 492# CHECK: bb.0.entry: 493# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 494# CHECK-NEXT: JCC_1 %bb.3, 4, implicit $eflags 495 496body: | 497 bb.0.entry: 498 liveins: $esi, $rdi 499 500 TEST64rr $rdi, $rdi, implicit-def $eflags 501 JCC_1 %bb.3, 4, implicit $eflags 502 503 bb.1.not_null: 504 liveins: $esi, $rdi 505 506 $eax = MOV32ri 2200000 507 $eax = ADD32ri killed $eax, 100, implicit-def dead $eflags 508 $eax = AND32rm killed $eax, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x) 509 CMP32rr killed $eax, killed $esi, implicit-def $eflags 510 JCC_1 %bb.4, 4, implicit $eflags 511 512 bb.2.ret_200: 513 $eax = MOV32ri 200 514 RET64 $eax 515 516 bb.3.is_null: 517 $eax = MOV32ri 42 518 RET64 $eax 519 520 bb.4.ret_100: 521 $eax = MOV32ri 100 522 RET64 $eax 523 524... 525--- 526name: imp_null_check_with_bitwise_op_3 527# CHECK-LABEL: name: imp_null_check_with_bitwise_op_3 528alignment: 16 529tracksRegLiveness: true 530liveins: 531 - { reg: '$rdi' } 532 - { reg: '$rsi' } 533# CHECK: bb.0.entry: 534# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 535# CHECK-NEXT: JCC_1 %bb.3, 4, implicit $eflags 536 537body: | 538 bb.0.entry: 539 liveins: $rsi, $rdi 540 541 TEST64rr $rdi, $rdi, implicit-def $eflags 542 JCC_1 %bb.3, 4, implicit $eflags 543 544 bb.1.not_null: 545 liveins: $rsi, $rdi 546 547 $rdi = MOV64ri 5000 548 $rdi = AND64rm killed $rdi, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x) 549 CMP64rr killed $rdi, killed $rsi, implicit-def $eflags 550 JCC_1 %bb.4, 4, implicit $eflags 551 552 bb.2.ret_200: 553 $eax = MOV32ri 200 554 RET64 $eax 555 556 bb.3.is_null: 557 $eax = MOV32ri 42 558 RET64 $eax 559 560 bb.4.ret_100: 561 $eax = MOV32ri 100 562 RET64 $eax 563 564... 565--- 566name: imp_null_check_with_bitwise_op_4 567# CHECK-LABEL: name: imp_null_check_with_bitwise_op_4 568alignment: 16 569tracksRegLiveness: true 570liveins: 571 - { reg: '$rdi' } 572 - { reg: '$rsi' } 573# CHECK: bb.0.entry: 574# CHECK: $rbx = MOV64rr $rdx 575# CHECK-NEXT: $rbx = FAULTING_OP 1, %bb.3, {{[0-9]+}}, $rbx, $rdi, 1, $noreg, 0, $noreg, implicit-def $eflags :: (load (s32) from %ir.x) 576 577body: | 578 bb.0.entry: 579 liveins: $rsi, $rdi, $rdx 580 581 TEST64rr $rdi, $rdi, implicit-def $eflags 582 JCC_1 %bb.3, 4, implicit $eflags 583 584 bb.1.not_null: 585 liveins: $rsi, $rdi, $rdx 586 587 $rbx = MOV64rr $rdx 588 $rbx = AND64rm killed $rbx, killed $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.x) 589 $rdx = MOV64ri 0 590 CMP64rr killed $rbx, killed $rsi, implicit-def $eflags 591 JCC_1 %bb.4, 4, implicit $eflags 592 593 bb.2.ret_200: 594 $eax = MOV32ri 200 595 RET64 $eax 596 597 bb.3.is_null: 598 $eax = MOV32ri 42 599 RET64 $eax 600 601 bb.4.ret_100: 602 $eax = MOV32ri 100 603 RET64 $eax 604 605... 606--- 607name: no_hoist_across_call 608# CHECK-LABEL: name: no_hoist_across_call 609alignment: 16 610tracksRegLiveness: true 611liveins: 612 - { reg: '$rdi' } 613calleeSavedRegisters: [ '$bh', '$bl', '$bp', '$bpl', '$bx', '$ebp', '$ebx', 614 '$rbp', '$rbx', '$r12', '$r13', '$r14', '$r15', 615 '$r12b', '$r13b', '$r14b', '$r15b', '$r12d', '$r13d', 616 '$r14d', '$r15d', '$r12w', '$r13w', '$r14w', '$r15w' ] 617# CHECK: body: 618# CHECK-NOT: FAULTING_OP 619# CHECK: bb.1.stay: 620# CHECK: CALL64pcrel32 621body: | 622 bb.0.entry: 623 liveins: $rdi, $rbx 624 625 frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp 626 CFI_INSTRUCTION def_cfa_offset 16 627 CFI_INSTRUCTION offset $rbx, -16 628 $rbx = MOV64rr $rdi 629 TEST64rr $rbx, $rbx, implicit-def $eflags 630 JCC_1 %bb.2, 4, implicit killed $eflags 631 632 bb.1.stay: 633 liveins: $rbx 634 635 CALL64pcrel32 @f, csr_64, implicit $rsp, implicit-def $rsp 636 $eax = MOV32rm killed $rbx, 1, $noreg, 0, $noreg :: (load (s32) from %ir.ptr) 637 $rbx = POP64r implicit-def $rsp, implicit $rsp 638 RET64 $eax 639 640 bb.2.leave: 641 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 642 $rbx = POP64r implicit-def $rsp, implicit $rsp 643 RET64 $eax 644 645... 646--- 647name: dependency_live_in_hazard 648# CHECK-LABEL: name: dependency_live_in_hazard 649# CHECK: bb.0.entry: 650# CHECK-NOT: FAULTING_OP 651# CHECK: bb.1.not_null: 652 653# Make sure that the BEXTR32rm instruction below is not used to emit 654# an implicit null check -- hoisting it will require hosting the move 655# to $esi and we cannot do that without clobbering the use of $rsi in 656# the first instruction in bb.1.not_null. 657alignment: 16 658tracksRegLiveness: true 659liveins: 660 - { reg: '$rdi' } 661 - { reg: '$rsi' } 662body: | 663 bb.0.entry: 664 liveins: $rdi, $rsi 665 666 TEST64rr $rdi, $rdi, implicit-def $eflags 667 JCC_1 %bb.2, 4, implicit killed $eflags 668 669 bb.1.not_null: 670 liveins: $rdi, $rsi 671 672 $rcx = MOV64rm killed $rsi, 1, $noreg, 0, $noreg :: (load (s64) from %ir.ptr2) 673 $esi = MOV32ri 3076 674 $eax = BEXTR32rm killed $rdi, 1, $noreg, 0, $noreg, killed $esi, implicit-def dead $eflags :: (load (s32) from %ir.ptr) 675 $eax = ADD32rm killed $eax, killed $rcx, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load (s32) from %ir.val) 676 RET64 $eax 677 678 bb.2.is_null: 679 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 680 RET64 $eax 681 682... 683--- 684name: use_alternate_load_op 685# CHECK-LABEL: name: use_alternate_load_op 686# CHECK: bb.0.entry: 687# CHECK: $rax = FAULTING_OP 1, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg 688# CHECK-NEXT: JMP_1 %bb.1 689# CHECK: bb.1.not_null 690 691alignment: 16 692tracksRegLiveness: true 693liveins: 694 - { reg: '$rdi' } 695 - { reg: '$rsi' } 696body: | 697 bb.0.entry: 698 liveins: $rdi, $rsi 699 700 TEST64rr $rdi, $rdi, implicit-def $eflags 701 JCC_1 %bb.2, 4, implicit killed $eflags 702 703 bb.1.not_null: 704 liveins: $rdi, $rsi 705 706 $rcx = MOV64rm killed $rsi, 1, $noreg, 0, $noreg 707 $rcx = AND64rm killed $rcx, $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags 708 $rax = MOV64rm killed $rdi, 1, $noreg, 0, $noreg 709 RET64 $eax 710 711 bb.2.is_null: 712 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 713 RET64 $eax 714 715... 716--- 717name: imp_null_check_gep_load_with_use_dep 718# CHECK-LABEL: name: imp_null_check_gep_load_with_use_dep 719# CHECK: bb.0.entry: 720# CHECK: $eax = FAULTING_OP 1, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg, implicit-def $rax :: (load (s32) from %ir.x) 721# CHECK-NEXT: JMP_1 %bb.1 722alignment: 16 723tracksRegLiveness: true 724liveins: 725 - { reg: '$rdi' } 726 - { reg: '$rsi' } 727body: | 728 bb.0.entry: 729 liveins: $rsi, $rdi 730 731 TEST64rr $rdi, $rdi, implicit-def $eflags 732 JCC_1 %bb.1, 4, implicit $eflags 733 734 bb.2.not_null: 735 liveins: $rdi, $rsi 736 737 $rsi = ADD64rr $rsi, $rdi, implicit-def dead $eflags 738 $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg, implicit-def $rax :: (load (s32) from %ir.x) 739 $eax = LEA64_32r killed $rax, 1, killed $rsi, 4, $noreg 740 RET64 $eax 741 742 bb.1.is_null: 743 $eax = MOV32ri 42 744 RET64 $eax 745 746... 747--- 748name: imp_null_check_load_with_base_sep 749# CHECK-LABEL: name: imp_null_check_load_with_base_sep 750# CHECK: bb.0.entry: 751# CHECK: $rsi = ADD64rr $rsi, $rdi, implicit-def dead $eflags 752# CHECK-NEXT: $esi = FAULTING_OP 1, %bb.2, {{[0-9]+}}, $esi, $rdi, 1, $noreg, 0, $noreg, implicit-def $eflags 753# CHECK-NEXT: JMP_1 %bb.1 754alignment: 16 755tracksRegLiveness: true 756liveins: 757 - { reg: '$rdi' } 758 - { reg: '$rsi' } 759body: | 760 bb.0.entry: 761 liveins: $rsi, $rdi 762 763 TEST64rr $rdi, $rdi, implicit-def $eflags 764 JCC_1 %bb.1, 4, implicit $eflags 765 766 bb.2.not_null: 767 liveins: $rdi, $rsi 768 769 $rsi = ADD64rr $rsi, $rdi, implicit-def dead $eflags 770 $esi = AND32rm killed $esi, $rdi, 1, $noreg, 0, $noreg, implicit-def dead $eflags 771 $eax = MOV32rr $esi 772 RET64 $eax 773 774 bb.1.is_null: 775 $eax = MOV32ri 42 776 RET64 $eax 777 778... 779--- 780name: inc_store 781# CHECK-LABEL: name: inc_store 782# CHECK: bb.0.entry: 783# CHECK: $noreg = FAULTING_OP 3, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg, $rsi 784# CHECK-NEXT: JMP_1 %bb.1 785# CHECK: bb.1.not_null 786 787alignment: 16 788tracksRegLiveness: true 789liveins: 790 - { reg: '$rdi' } 791 - { reg: '$rsi' } 792body: | 793 bb.0.entry: 794 liveins: $rdi, $rsi 795 796 TEST64rr $rdi, $rdi, implicit-def $eflags 797 JCC_1 %bb.2, 4, implicit killed $eflags 798 799 bb.1.not_null: 800 liveins: $rdi, $rsi 801 802 MOV64mr killed $rdi, 1, $noreg, 0, $noreg, killed $rsi 803 RET64 804 805 bb.2.is_null: 806 RET64 807 808... 809--- 810name: inc_store_plus_offset 811# CHECK-LABEL: inc_store_plus_offset 812# CHECK: bb.0.entry: 813# CHECK: $noreg = FAULTING_OP 3, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 16, $noreg, $rsi 814# CHECK-NEXT: JMP_1 %bb.1 815# CHECK: bb.1.not_null 816 817alignment: 16 818tracksRegLiveness: true 819liveins: 820 - { reg: '$rdi' } 821 - { reg: '$rsi' } 822body: | 823 bb.0.entry: 824 liveins: $rdi, $rsi 825 826 TEST64rr $rdi, $rdi, implicit-def $eflags 827 JCC_1 %bb.2, 4, implicit killed $eflags 828 829 bb.1.not_null: 830 liveins: $rdi, $rsi 831 832 MOV64mr killed $rdi, 1, $noreg, 16, $noreg, killed $rsi 833 RET64 834 835 bb.2.is_null: 836 RET64 837 838... 839--- 840name: inc_store_with_dep 841# CHECK-LABEL: inc_store_with_dep 842# CHECK: bb.0.entry: 843# CHECK: $esi = ADD32rr killed $esi, killed $esi, implicit-def dead $eflags 844# CHECK-NEXT: $noreg = FAULTING_OP 3, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 16, $noreg, $esi 845# CHECK-NEXT: JMP_1 %bb.1 846# CHECK: bb.1.not_null 847# CHECK-NOT: liveins: {{.*}} $eflags 848 849alignment: 16 850tracksRegLiveness: true 851liveins: 852 - { reg: '$rdi' } 853 - { reg: '$rsi' } 854body: | 855 bb.0.entry: 856 liveins: $rdi, $rsi 857 858 TEST64rr $rdi, $rdi, implicit-def $eflags 859 JCC_1 %bb.2, 4, implicit killed $eflags 860 861 bb.1.not_null: 862 liveins: $rdi, $rsi 863 864 $esi = ADD32rr killed $esi, killed $esi, implicit-def dead $eflags 865 MOV32mr killed $rdi, 1, $noreg, 16, $noreg, killed $esi 866 RET64 867 868 bb.2.is_null: 869 RET64 870 871... 872--- 873name: inc_store_with_dep_in_null 874# CHECK-LABEL: inc_store_with_dep_in_null 875# CHECK: bb.0.entry: 876# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 877# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 878# CHECK: bb.1.not_null 879 880alignment: 16 881tracksRegLiveness: true 882liveins: 883 - { reg: '$rdi' } 884 - { reg: '$rsi' } 885body: | 886 bb.0.entry: 887 liveins: $rdi, $rsi 888 889 TEST64rr $rdi, $rdi, implicit-def $eflags 890 JCC_1 %bb.2, 4, implicit killed $eflags 891 892 bb.1.not_null: 893 liveins: $rdi, $rsi 894 895 $esi = ADD32rr $esi, $esi, implicit-def dead $eflags 896 MOV32mr killed $rdi, 1, $noreg, 0, $noreg, $esi 897 $eax = MOV32rr killed $esi 898 RET64 $eax 899 900 bb.2.is_null: 901 liveins: $rsi 902 903 $eax = MOV32rr killed $esi 904 RET64 $eax 905 906... 907--- 908name: inc_store_with_volatile 909# CHECK-LABEL: inc_store_with_volatile 910# CHECK: bb.0.entry: 911# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 912# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 913# CHECK: bb.1.not_null 914 915alignment: 16 916tracksRegLiveness: true 917liveins: 918 - { reg: '$rdi' } 919 - { reg: '$rsi' } 920body: | 921 bb.0.entry: 922 liveins: $rdi, $rsi 923 924 TEST64rr $rdi, $rdi, implicit-def $eflags 925 JCC_1 %bb.2, 4, implicit killed $eflags 926 927 bb.1.not_null: 928 liveins: $rdi, $rsi 929 930 MOV32mr killed $rdi, 1, $noreg, 0, $noreg, killed $esi :: (volatile store (s32) into %ir.ptr) 931 RET64 932 933 bb.2.is_null: 934 RET64 935 936... 937--- 938name: inc_store_with_two_dep 939# CHECK-LABEL: inc_store_with_two_dep 940# CHECK: bb.0.entry: 941# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 942# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 943# CHECK: bb.1.not_null 944 945alignment: 16 946tracksRegLiveness: true 947liveins: 948 - { reg: '$rdi' } 949 - { reg: '$rsi' } 950body: | 951 bb.0.entry: 952 liveins: $rdi, $rsi 953 954 TEST64rr $rdi, $rdi, implicit-def $eflags 955 JCC_1 %bb.2, 4, implicit killed $eflags 956 957 bb.1.not_null: 958 liveins: $rdi, $rsi 959 960 $esi = ADD32rr killed $esi, killed $esi, implicit-def dead $eflags 961 $esi = ADD32ri killed $esi, 15, implicit-def dead $eflags 962 MOV32mr killed $rdi, 1, $noreg, 16, $noreg, killed $esi 963 RET64 964 965 bb.2.is_null: 966 RET64 967 968... 969--- 970name: inc_store_with_redefined_base 971# CHECK-LABEL: inc_store_with_redefined_base 972# CHECK: bb.0.entry: 973# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 974# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 975# CHECK: bb.1.not_null 976 977alignment: 16 978tracksRegLiveness: true 979liveins: 980 - { reg: '$rdi' } 981 - { reg: '$rsi' } 982body: | 983 bb.0.entry: 984 liveins: $rdi, $rsi 985 986 TEST64rr $rdi, $rdi, implicit-def $eflags 987 JCC_1 %bb.2, 4, implicit killed $eflags 988 989 bb.1.not_null: 990 liveins: $rdi, $rsi 991 992 $rdi = ADD64rr killed $rdi, killed $rdi, implicit-def dead $eflags 993 MOV32mr killed $rdi, 1, $noreg, 16, $noreg, killed $esi 994 RET64 995 996 bb.2.is_null: 997 RET64 998 999... 1000--- 1001name: inc_store_with_reused_base 1002# CHECK-LABEL: inc_store_with_reused_base 1003# CHECK: bb.0.entry: 1004# CHECK: $noreg = FAULTING_OP 3, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 16, $noreg, $esi 1005# CHECK-NEXT: JMP_1 %bb.1 1006# CHECK: bb.1.not_null 1007 1008alignment: 16 1009tracksRegLiveness: true 1010liveins: 1011 - { reg: '$rdi' } 1012 - { reg: '$rsi' } 1013body: | 1014 bb.0.entry: 1015 liveins: $rdi, $rsi 1016 1017 TEST64rr $rdi, $rdi, implicit-def $eflags 1018 JCC_1 %bb.2, 4, implicit killed $eflags 1019 1020 bb.1.not_null: 1021 liveins: $rdi, $rsi 1022 1023 $rax = MOV64rr $rdi 1024 MOV32mr killed $rdi, 1, $noreg, 16, $noreg, killed $esi 1025 RET64 $eax 1026 1027 bb.2.is_null: 1028 $rax = XOR64rr undef $rax, undef $rax, implicit-def dead $eflags 1029 RET64 $eax 1030 1031... 1032--- 1033name: inc_store_across_call 1034# CHECK-LABEL: inc_store_across_call 1035# CHECK: bb.0.entry: 1036# CHECK: TEST64rr $rbx, $rbx, implicit-def $eflags 1037# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 1038# CHECK: bb.1.not_null 1039 1040alignment: 16 1041tracksRegLiveness: true 1042liveins: 1043 - { reg: '$rdi' } 1044calleeSavedRegisters: [ '$bh', '$bl', '$bp', '$bpl', '$bx', '$ebp', '$ebx', 1045 '$rbp', '$rbx', '$r12', '$r13', '$r14', '$r15', 1046 '$r12b', '$r13b', '$r14b', '$r15b', '$r12d', '$r13d', 1047 '$r14d', '$r15d', '$r12w', '$r13w', '$r14w', '$r15w' ] 1048body: | 1049 bb.0.entry: 1050 liveins: $rdi, $rbx 1051 1052 frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp 1053 CFI_INSTRUCTION def_cfa_offset 16 1054 CFI_INSTRUCTION offset $rbx, -16 1055 $rbx = MOV64rr killed $rdi 1056 TEST64rr $rbx, $rbx, implicit-def $eflags 1057 JCC_1 %bb.2, 4, implicit killed $eflags 1058 1059 bb.1.not_null: 1060 liveins: $rbx 1061 1062 CALL64pcrel32 @f, csr_64, implicit $rsp, implicit-def $rsp 1063 MOV32mi $rbx, 1, $noreg, 0, $noreg, 20 1064 $rax = MOV64rr killed $rbx 1065 $rbx = POP64r implicit-def $rsp, implicit $rsp 1066 RET64 $eax 1067 1068 bb.2.is_null: 1069 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 1070 $rbx = POP64r implicit-def $rsp, implicit $rsp 1071 RET64 $eax 1072 1073... 1074--- 1075name: inc_store_with_dep_in_dep 1076# CHECK-LABEL: inc_store_with_dep_in_dep 1077# CHECK: bb.0.entry: 1078# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 1079# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 1080# CHECK: bb.1.not_null 1081 1082alignment: 16 1083tracksRegLiveness: true 1084liveins: 1085 - { reg: '$rdi' } 1086 - { reg: '$rsi' } 1087body: | 1088 bb.0.entry: 1089 liveins: $rdi, $rsi 1090 1091 TEST64rr $rdi, $rdi, implicit-def $eflags 1092 JCC_1 %bb.2, 4, implicit killed $eflags 1093 1094 bb.1.not_null: 1095 liveins: $rdi, $rsi 1096 1097 $eax = MOV32rr $esi 1098 $esi = ADD32ri killed $esi, 15, implicit-def dead $eflags 1099 MOV32mr killed $rdi, 1, $noreg, 0, $noreg, killed $esi 1100 RET64 $eax 1101 1102 bb.2.is_null: 1103 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 1104 RET64 $eax 1105 1106... 1107--- 1108name: inc_store_with_load_over_store 1109# CHECK-LABEL: inc_store_with_load_over_store 1110# CHECK: bb.0.entry: 1111# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 1112# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 1113# CHECK: bb.1.not_null 1114 1115alignment: 16 1116tracksRegLiveness: true 1117liveins: 1118 - { reg: '$rdi' } 1119 - { reg: '$rsi' } 1120body: | 1121 bb.0.entry: 1122 liveins: $rdi, $rsi 1123 1124 TEST64rr $rdi, $rdi, implicit-def $eflags 1125 JCC_1 %bb.2, 4, implicit killed $eflags 1126 1127 bb.1.not_null: 1128 liveins: $rdi, $rsi 1129 1130 MOV32mi killed $rsi, 1, $noreg, 0, $noreg, 2 1131 $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg 1132 RET64 $eax 1133 1134 bb.2.is_null: 1135 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 1136 RET64 $eax 1137 1138... 1139--- 1140name: inc_store_with_store_over_load 1141# CHECK-LABEL: inc_store_with_store_over_load 1142# CHECK: bb.0.entry: 1143# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 1144# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 1145# CHECK: bb.1.not_null 1146 1147alignment: 16 1148tracksRegLiveness: true 1149liveins: 1150 - { reg: '$rdi' } 1151 - { reg: '$rsi' } 1152body: | 1153 bb.0.entry: 1154 liveins: $rdi, $rsi 1155 1156 TEST64rr $rdi, $rdi, implicit-def $eflags 1157 JCC_1 %bb.2, 4, implicit killed $eflags 1158 1159 bb.1.not_null: 1160 liveins: $rdi, $rsi 1161 1162 $eax = MOV32rm killed $rsi, 1, $noreg, 0, $noreg 1163 MOV32mi killed $rdi, 1, $noreg, 0, $noreg, 2 1164 RET64 $eax 1165 1166 bb.2.is_null: 1167 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 1168 RET64 $eax 1169 1170... 1171--- 1172name: inc_store_with_store_over_store 1173# CHECK-LABEL: inc_store_with_store_over_store 1174# CHECK: bb.0.entry: 1175# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 1176# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 1177# CHECK: bb.1.not_null 1178 1179alignment: 16 1180tracksRegLiveness: true 1181liveins: 1182 - { reg: '$rdi' } 1183 - { reg: '$rsi' } 1184body: | 1185 bb.0.entry: 1186 liveins: $rdi, $rsi 1187 1188 TEST64rr $rdi, $rdi, implicit-def $eflags 1189 JCC_1 %bb.2, 4, implicit killed $eflags 1190 1191 bb.1.not_null: 1192 liveins: $rdi, $rsi 1193 1194 MOV32mi killed $rsi, 1, $noreg, 0, $noreg, 3 1195 MOV32mi killed $rdi, 1, $noreg, 0, $noreg, 2 1196 RET64 1197 1198 bb.2.is_null: 1199 RET64 1200 1201... 1202--- 1203name: inc_store_with_load_and_store 1204# CHECK-LABEL: inc_store_with_load_and_store 1205# CHECK: bb.0.entry: 1206# CHECK: $noreg = FAULTING_OP 2, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg, $esi, implicit-def $eflags 1207# CHECK-NEXT: JMP_1 %bb.1 1208# CHECK: bb.1.not_null 1209 1210alignment: 16 1211tracksRegLiveness: true 1212liveins: 1213 - { reg: '$rdi' } 1214 - { reg: '$rsi' } 1215body: | 1216 bb.0.entry: 1217 liveins: $rdi, $rsi 1218 1219 TEST64rr $rdi, $rdi, implicit-def $eflags 1220 JCC_1 %bb.2, 4, implicit killed $eflags 1221 1222 bb.1.not_null: 1223 liveins: $rdi, $rsi 1224 1225 $esi = ADD32rr $esi, $esi, implicit-def dead $eflags 1226 ADD32mr killed $rdi, 1, $noreg, 0, $noreg, killed $esi, implicit-def dead $eflags 1227 RET64 1228 1229 bb.2.is_null: 1230 RET64 1231 1232... 1233--- 1234name: inc_store_and_load_no_alias 1235# CHECK-LABEL: inc_store_and_load_no_alias 1236# CHECK: bb.0.entry: 1237# CHECK: $eax = FAULTING_OP 1, %bb.2, {{[0-9]+}}, $rdi, 1, $noreg, 0, $noreg :: (load (s32) from %ir.ptr) 1238# CHECK-NEXT: JMP_1 %bb.1 1239# CHECK: bb.1.not_null 1240 1241alignment: 16 1242tracksRegLiveness: true 1243liveins: 1244 - { reg: '$rdi' } 1245 - { reg: '$rsi' } 1246body: | 1247 bb.0.entry: 1248 liveins: $rdi, $rsi 1249 1250 TEST64rr $rdi, $rdi, implicit-def $eflags 1251 JCC_1 %bb.2, 4, implicit killed $eflags 1252 1253 bb.1.not_null: 1254 liveins: $rdi, $rsi 1255 1256 MOV32mi killed $rsi, 1, $noreg, 0, $noreg, 3 :: (store (s32) into %ir.ptr2) 1257 $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg :: (load (s32) from %ir.ptr) 1258 RET64 $eax 1259 1260 bb.2.is_null: 1261 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 1262 RET64 $eax 1263 1264... 1265--- 1266name: inc_store_and_load_alias 1267# CHECK-LABEL: inc_store_and_load_alias 1268# CHECK: bb.0.entry: 1269# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 1270# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 1271# CHECK: bb.1.not_null 1272 1273alignment: 16 1274tracksRegLiveness: true 1275liveins: 1276 - { reg: '$rdi' } 1277 - { reg: '$rsi' } 1278body: | 1279 bb.0.entry: 1280 liveins: $rdi, $rsi 1281 1282 TEST64rr $rdi, $rdi, implicit-def $eflags 1283 JCC_1 %bb.2, 4, implicit killed $eflags 1284 1285 bb.1.not_null: 1286 liveins: $rdi, $rsi 1287 1288 MOV32mi killed $rsi, 1, $noreg, 0, $noreg, 3 :: (store (s32) into %ir.ptr2) 1289 $eax = MOV32rm killed $rdi, 1, $noreg, 0, $noreg :: (load (s32) from %ir.ptr) 1290 RET64 $eax 1291 1292 bb.2.is_null: 1293 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 1294 RET64 $eax 1295 1296... 1297--- 1298name: inc_spill_dep 1299# CHECK-LABEL: inc_spill_dep 1300# CHECK: bb.0.entry: 1301# CHECK: TEST64rr $rdi, $rdi, implicit-def $eflags 1302# CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags 1303# CHECK: bb.1.not_null 1304 1305alignment: 16 1306tracksRegLiveness: true 1307stack: 1308 - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8} 1309liveins: 1310 - { reg: '$rdi' } 1311 - { reg: '$rsi' } 1312body: | 1313 bb.0.entry: 1314 liveins: $rdi, $rsi 1315 1316 $rsp = frame-setup SUB64ri8 $rsp, 8, implicit-def dead $eflags 1317 MOV32mr $rsp, 1, $noreg, 0, $noreg, $esi :: (store (s32) into %stack.0) 1318 TEST64rr $rdi, $rdi, implicit-def $eflags 1319 JCC_1 %bb.2, 4, implicit killed $eflags 1320 1321 bb.1.not_null: 1322 liveins: $rdi, $rsi 1323 1324 $r14d = MOV32rm $rsp, 1, $noreg, 0, $noreg :: (load (s32) from %stack.0) 1325 MOV64mr $rsp, 1, $noreg, 0, $noreg, $rdi :: (store (s64) into %stack.0) 1326 $edi = MOV32rm $rdi, 1, $noreg, 8, $noreg :: (load (s32) from %ir.ptr) 1327 $eax = MOV32rr $edi 1328 RET64 $eax 1329 1330 bb.2.is_null: 1331 $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags 1332 RET64 $eax 1333 1334... 1335--- 1336name: imp_null_check_address_mul_overflow 1337# CHECK-LABEL: name: imp_null_check_address_mul_overflow 1338# CHECK: bb.0.entry: 1339# CHECK-NOT: FAULTING_OP 1340alignment: 16 1341tracksRegLiveness: true 1342liveins: 1343 - { reg: '$rdi' } 1344 - { reg: '$rsi' } 1345body: | 1346 bb.0.entry: 1347 liveins: $rsi, $rdi 1348 1349 TEST64rr $rdi, $rdi, implicit-def $eflags 1350 JCC_1 %bb.1, 4, implicit $eflags 1351 1352 bb.2.not_null: 1353 liveins: $rdi, $rsi 1354 1355 $rcx = MOV64ri -9223372036854775808 1356 $eax = MOV32rm killed $rdi, 2, $rcx, 0, $noreg, implicit-def $rax 1357 RET64 $eax 1358 1359 bb.1.is_null: 1360 $eax = MOV32ri 42 1361 RET64 $eax 1362 1363... 1364