1; RUN: llc -verify-machineinstrs -O3 -mtriple=x86_64-apple-macosx -enable-implicit-null-checks < %s | FileCheck %s 2 3define i32 @imp_null_check_load(ptr %x) { 4; CHECK-LABEL: imp_null_check_load: 5; CHECK: ## %bb.0: ## %entry 6; CHECK-NEXT: Ltmp0: 7; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB0_1 8; CHECK-NEXT: ## %bb.2: ## %not_null 9; CHECK-NEXT: retq 10; CHECK-NEXT: LBB0_1: ## %is_null 11; CHECK-NEXT: movl $42, %eax 12; CHECK-NEXT: retq 13 14 entry: 15 %c = icmp eq ptr %x, null 16 br i1 %c, label %is_null, label %not_null, !make.implicit !0 17 18 is_null: 19 ret i32 42 20 21 not_null: 22 %t = load i32, ptr %x 23 ret i32 %t 24} 25 26; TODO: can make implicit 27define i32 @imp_null_check_unordered_load(ptr %x) { 28; CHECK-LABEL: imp_null_check_unordered_load: 29; CHECK: ## %bb.0: ## %entry 30; CHECK-NEXT: Ltmp1: 31; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB1_1 32; CHECK-NEXT: ## %bb.2: ## %not_null 33; CHECK-NEXT: retq 34; CHECK-NEXT: LBB1_1: ## %is_null 35; CHECK-NEXT: movl $42, %eax 36; CHECK-NEXT: retq 37 38 entry: 39 %c = icmp eq ptr %x, null 40 br i1 %c, label %is_null, label %not_null, !make.implicit !0 41 42 is_null: 43 ret i32 42 44 45 not_null: 46 %t = load atomic i32, ptr %x unordered, align 4 47 ret i32 %t 48} 49 50 51; TODO: Can be converted into implicit check. 52;; Probably could be implicit, but we're conservative for now 53define i32 @imp_null_check_seq_cst_load(ptr %x) { 54; CHECK-LABEL: imp_null_check_seq_cst_load: 55; CHECK: ## %bb.0: ## %entry 56; CHECK-NEXT: testq %rdi, %rdi 57; CHECK-NEXT: je LBB2_1 58; CHECK-NEXT: ## %bb.2: ## %not_null 59; CHECK-NEXT: movl (%rdi), %eax 60; CHECK-NEXT: retq 61; CHECK-NEXT: LBB2_1: ## %is_null 62; CHECK-NEXT: movl $42, %eax 63; CHECK-NEXT: retq 64 65 entry: 66 %c = icmp eq ptr %x, null 67 br i1 %c, label %is_null, label %not_null, !make.implicit !0 68 69 is_null: 70 ret i32 42 71 72 not_null: 73 %t = load atomic i32, ptr %x seq_cst, align 4 74 ret i32 %t 75} 76 77;; Might be memory mapped IO, so can't rely on fault behavior 78define i32 @imp_null_check_volatile_load(ptr %x) { 79; CHECK-LABEL: imp_null_check_volatile_load: 80; CHECK: ## %bb.0: ## %entry 81; CHECK-NEXT: testq %rdi, %rdi 82; CHECK-NEXT: je LBB3_1 83; CHECK-NEXT: ## %bb.2: ## %not_null 84; CHECK-NEXT: movl (%rdi), %eax 85; CHECK-NEXT: retq 86; CHECK-NEXT: LBB3_1: ## %is_null 87; CHECK-NEXT: movl $42, %eax 88; CHECK-NEXT: retq 89 90 entry: 91 %c = icmp eq ptr %x, null 92 br i1 %c, label %is_null, label %not_null, !make.implicit !0 93 94 is_null: 95 ret i32 42 96 97 not_null: 98 %t = load volatile i32, ptr %x, align 4 99 ret i32 %t 100} 101 102 103define i8 @imp_null_check_load_i8(ptr %x) { 104; CHECK-LABEL: imp_null_check_load_i8: 105; CHECK: ## %bb.0: ## %entry 106; CHECK-NEXT: Ltmp2: 107; CHECK-NEXT: movb (%rdi), %al ## on-fault: LBB4_1 108; CHECK-NEXT: ## %bb.2: ## %not_null 109; CHECK-NEXT: retq 110; CHECK-NEXT: LBB4_1: ## %is_null 111; CHECK-NEXT: movb $42, %al 112; CHECK-NEXT: retq 113 114 entry: 115 %c = icmp eq ptr %x, null 116 br i1 %c, label %is_null, label %not_null, !make.implicit !0 117 118 is_null: 119 ret i8 42 120 121 not_null: 122 %t = load i8, ptr %x 123 ret i8 %t 124} 125 126define i256 @imp_null_check_load_i256(ptr %x) { 127; CHECK-LABEL: imp_null_check_load_i256: 128; CHECK: ## %bb.0: ## %entry 129; CHECK-NEXT: movq %rdi, %rax 130; CHECK-NEXT: Ltmp3: 131; CHECK-NEXT: movaps (%rsi), %xmm0 ## on-fault: LBB5_1 132; CHECK-NEXT: ## %bb.2: ## %not_null 133; CHECK-NEXT: movaps 16(%rsi), %xmm1 134; CHECK-NEXT: movaps %xmm1, 16(%rax) 135; CHECK-NEXT: movaps %xmm0, (%rax) 136; CHECK-NEXT: retq 137; CHECK-NEXT: LBB5_1: ## %is_null 138; CHECK-NEXT: xorps %xmm0, %xmm0 139; CHECK-NEXT: movaps %xmm0, 16(%rax) 140; CHECK-NEXT: movq $0, 8(%rax) 141; CHECK-NEXT: movq $42, (%rax) 142; CHECK-NEXT: retq 143 144 entry: 145 %c = icmp eq ptr %x, null 146 br i1 %c, label %is_null, label %not_null, !make.implicit !0 147 148 is_null: 149 ret i256 42 150 151 not_null: 152 %t = load i256, ptr %x 153 ret i256 %t 154} 155 156 157 158define i32 @imp_null_check_gep_load(ptr %x) { 159; CHECK-LABEL: imp_null_check_gep_load: 160; CHECK: ## %bb.0: ## %entry 161; CHECK-NEXT: Ltmp4: 162; CHECK-NEXT: movl 128(%rdi), %eax ## on-fault: LBB6_1 163; CHECK-NEXT: ## %bb.2: ## %not_null 164; CHECK-NEXT: retq 165; CHECK-NEXT: LBB6_1: ## %is_null 166; CHECK-NEXT: movl $42, %eax 167; CHECK-NEXT: retq 168 169 entry: 170 %c = icmp eq ptr %x, null 171 br i1 %c, label %is_null, label %not_null, !make.implicit !0 172 173 is_null: 174 ret i32 42 175 176 not_null: 177 %x.gep = getelementptr i32, ptr %x, i32 32 178 %t = load i32, ptr %x.gep 179 ret i32 %t 180} 181 182define i32 @imp_null_check_add_result(ptr %x, i32 %p) { 183; CHECK-LABEL: imp_null_check_add_result: 184; CHECK: ## %bb.0: ## %entry 185; CHECK-NEXT: Ltmp5: 186; CHECK-NEXT: addl (%rdi), %esi ## on-fault: LBB7_1 187; CHECK-NEXT: ## %bb.2: ## %not_null 188; CHECK-NEXT: movl %esi, %eax 189; CHECK-NEXT: retq 190; CHECK-NEXT: LBB7_1: ## %is_null 191; CHECK-NEXT: movl $42, %eax 192; CHECK-NEXT: retq 193 194 entry: 195 %c = icmp eq ptr %x, null 196 br i1 %c, label %is_null, label %not_null, !make.implicit !0 197 198 is_null: 199 ret i32 42 200 201 not_null: 202 %t = load i32, ptr %x 203 %p1 = add i32 %t, %p 204 ret i32 %p1 205} 206 207define i32 @imp_null_check_sub_result(ptr %x, i32 %p) { 208; CHECK-LABEL: imp_null_check_sub_result: 209; CHECK: ## %bb.0: ## %entry 210; CHECK-NEXT: Ltmp6: 211; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB8_1 212; CHECK-NEXT: ## %bb.2: ## %not_null 213; CHECK-NEXT: subl %esi, %eax 214; CHECK-NEXT: retq 215; CHECK-NEXT: LBB8_1: ## %is_null 216; CHECK-NEXT: movl $42, %eax 217; CHECK-NEXT: retq 218 219 entry: 220 %c = icmp eq ptr %x, null 221 br i1 %c, label %is_null, label %not_null, !make.implicit !0 222 223 is_null: 224 ret i32 42 225 226 not_null: 227 %t = load i32, ptr %x 228 %p1 = sub i32 %t, %p 229 ret i32 %p1 230} 231 232define i32 @imp_null_check_mul_result(ptr %x, i32 %p) { 233; CHECK-LABEL: imp_null_check_mul_result: 234; CHECK: ## %bb.0: ## %entry 235; CHECK-NEXT: Ltmp7: 236; CHECK-NEXT: imull (%rdi), %esi ## on-fault: LBB9_1 237; CHECK-NEXT: ## %bb.2: ## %not_null 238; CHECK-NEXT: movl %esi, %eax 239; CHECK-NEXT: retq 240; CHECK-NEXT: LBB9_1: ## %is_null 241; CHECK-NEXT: movl $42, %eax 242; CHECK-NEXT: retq 243 244 entry: 245 %c = icmp eq ptr %x, null 246 br i1 %c, label %is_null, label %not_null, !make.implicit !0 247 248 is_null: 249 ret i32 42 250 251 not_null: 252 %t = load i32, ptr %x 253 %p1 = mul i32 %t, %p 254 ret i32 %p1 255} 256 257define i32 @imp_null_check_udiv_result(ptr %x, i32 %p) { 258; CHECK-LABEL: imp_null_check_udiv_result: 259; CHECK: ## %bb.0: ## %entry 260; CHECK-NEXT: Ltmp8: 261; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB10_1 262; CHECK-NEXT: ## %bb.2: ## %not_null 263; CHECK-NEXT: xorl %edx, %edx 264; CHECK-NEXT: divl %esi 265; CHECK-NEXT: retq 266; CHECK-NEXT: LBB10_1: ## %is_null 267; CHECK-NEXT: movl $42, %eax 268; CHECK-NEXT: retq 269 270 entry: 271 %c = icmp eq ptr %x, null 272 br i1 %c, label %is_null, label %not_null, !make.implicit !0 273 274 is_null: 275 ret i32 42 276 277 not_null: 278 %t = load i32, ptr %x 279 %p1 = udiv i32 %t, %p 280 ret i32 %p1 281} 282 283define i32 @imp_null_check_shl_result(ptr %x, i32 %p) { 284; CHECK-LABEL: imp_null_check_shl_result: 285; CHECK: ## %bb.0: ## %entry 286; CHECK-NEXT: Ltmp9: 287; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB11_1 288; CHECK-NEXT: ## %bb.2: ## %not_null 289; CHECK-NEXT: movl %esi, %ecx 290; CHECK-NEXT: shll %cl, %eax 291; CHECK-NEXT: retq 292; CHECK-NEXT: LBB11_1: ## %is_null 293; CHECK-NEXT: movl $42, %eax 294; CHECK-NEXT: retq 295 296 entry: 297 %c = icmp eq ptr %x, null 298 br i1 %c, label %is_null, label %not_null, !make.implicit !0 299 300 is_null: 301 ret i32 42 302 303 not_null: 304 %t = load i32, ptr %x 305 %p1 = shl i32 %t, %p 306 ret i32 %p1 307} 308 309define i32 @imp_null_check_lshr_result(ptr %x, i32 %p) { 310; CHECK-LABEL: imp_null_check_lshr_result: 311; CHECK: ## %bb.0: ## %entry 312; CHECK-NEXT: Ltmp10: 313; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB12_1 314; CHECK-NEXT: ## %bb.2: ## %not_null 315; CHECK-NEXT: movl %esi, %ecx 316; CHECK-NEXT: shrl %cl, %eax 317; CHECK-NEXT: retq 318; CHECK-NEXT: LBB12_1: ## %is_null 319; CHECK-NEXT: movl $42, %eax 320; CHECK-NEXT: retq 321 322 entry: 323 %c = icmp eq ptr %x, null 324 br i1 %c, label %is_null, label %not_null, !make.implicit !0 325 326 is_null: 327 ret i32 42 328 329 not_null: 330 %t = load i32, ptr %x 331 %p1 = lshr i32 %t, %p 332 ret i32 %p1 333} 334 335 336 337 338define i32 @imp_null_check_hoist_over_unrelated_load(ptr %x, ptr %y, ptr %z) { 339; CHECK-LABEL: imp_null_check_hoist_over_unrelated_load: 340; CHECK: ## %bb.0: ## %entry 341; CHECK-NEXT: Ltmp11: 342; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB13_1 343; CHECK-NEXT: ## %bb.2: ## %not_null 344; CHECK-NEXT: movl (%rsi), %ecx 345; CHECK-NEXT: movl %ecx, (%rdx) 346; CHECK-NEXT: retq 347; CHECK-NEXT: LBB13_1: ## %is_null 348; CHECK-NEXT: movl $42, %eax 349; CHECK-NEXT: retq 350 351 entry: 352 %c = icmp eq ptr %x, null 353 br i1 %c, label %is_null, label %not_null, !make.implicit !0 354 355 is_null: 356 ret i32 42 357 358 not_null: 359 %t0 = load i32, ptr %y 360 %t1 = load i32, ptr %x 361 store i32 %t0, ptr %z 362 ret i32 %t1 363} 364 365define i32 @imp_null_check_via_mem_comparision(ptr %x, i32 %val) { 366; CHECK-LABEL: imp_null_check_via_mem_comparision: 367; CHECK: ## %bb.0: ## %entry 368; CHECK-NEXT: Ltmp12: 369; CHECK-NEXT: cmpl %esi, 4(%rdi) ## on-fault: LBB14_3 370; CHECK-NEXT: ## %bb.1: ## %not_null 371; CHECK-NEXT: jge LBB14_2 372; CHECK-NEXT: ## %bb.4: ## %ret_100 373; CHECK-NEXT: movl $100, %eax 374; CHECK-NEXT: retq 375; CHECK-NEXT: LBB14_3: ## %is_null 376; CHECK-NEXT: movl $42, %eax 377; CHECK-NEXT: retq 378; CHECK-NEXT: LBB14_2: ## %ret_200 379; CHECK-NEXT: movl $200, %eax 380; CHECK-NEXT: retq 381 382 entry: 383 %c = icmp eq ptr %x, null 384 br i1 %c, label %is_null, label %not_null, !make.implicit !0 385 386 is_null: 387 ret i32 42 388 389 not_null: 390 %x.loc = getelementptr i32, ptr %x, i32 1 391 %t = load i32, ptr %x.loc 392 %m = icmp slt i32 %t, %val 393 br i1 %m, label %ret_100, label %ret_200 394 395 ret_100: 396 ret i32 100 397 398 ret_200: 399 ret i32 200 400} 401 402define i32 @imp_null_check_gep_load_with_use_dep(ptr %x, i32 %a) { 403; CHECK-LABEL: imp_null_check_gep_load_with_use_dep: 404; CHECK: ## %bb.0: ## %entry 405; CHECK-NEXT: ## kill: def $esi killed $esi def $rsi 406; CHECK-NEXT: Ltmp13: 407; CHECK-NEXT: movl (%rdi), %eax ## on-fault: LBB15_1 408; CHECK-NEXT: ## %bb.2: ## %not_null 409; CHECK-NEXT: addl %edi, %esi 410; CHECK-NEXT: leal 4(%rax,%rsi), %eax 411; CHECK-NEXT: retq 412; CHECK-NEXT: LBB15_1: ## %is_null 413; CHECK-NEXT: movl $42, %eax 414; CHECK-NEXT: retq 415 416 entry: 417 %c = icmp eq ptr %x, null 418 br i1 %c, label %is_null, label %not_null, !make.implicit !0 419 420 is_null: 421 ret i32 42 422 423 not_null: 424 %x.loc = getelementptr i32, ptr %x, i32 1 425 %y = ptrtoint ptr %x.loc to i32 426 %b = add i32 %a, %y 427 %t = load i32, ptr %x 428 %z = add i32 %t, %b 429 ret i32 %z 430} 431 432;; TODO: We could handle this case as we can lift the fence into the 433;; previous block before the conditional without changing behavior. 434define i32 @imp_null_check_load_fence1(ptr %x) { 435; CHECK-LABEL: imp_null_check_load_fence1: 436; CHECK: ## %bb.0: ## %entry 437; CHECK-NEXT: testq %rdi, %rdi 438; CHECK-NEXT: je LBB16_1 439; CHECK-NEXT: ## %bb.2: ## %not_null 440; CHECK-NEXT: ##MEMBARRIER 441; CHECK-NEXT: movl (%rdi), %eax 442; CHECK-NEXT: retq 443; CHECK-NEXT: LBB16_1: ## %is_null 444; CHECK-NEXT: movl $42, %eax 445; CHECK-NEXT: retq 446 447entry: 448 %c = icmp eq ptr %x, null 449 br i1 %c, label %is_null, label %not_null, !make.implicit !0 450 451is_null: 452 ret i32 42 453 454not_null: 455 fence acquire 456 %t = load i32, ptr %x 457 ret i32 %t 458} 459 460;; TODO: We could handle this case as we can lift the fence into the 461;; previous block before the conditional without changing behavior. 462define i32 @imp_null_check_load_fence2(ptr %x) { 463; CHECK-LABEL: imp_null_check_load_fence2: 464; CHECK: ## %bb.0: ## %entry 465; CHECK-NEXT: testq %rdi, %rdi 466; CHECK-NEXT: je LBB17_1 467; CHECK-NEXT: ## %bb.2: ## %not_null 468; CHECK-NEXT: mfence 469; CHECK-NEXT: movl (%rdi), %eax 470; CHECK-NEXT: retq 471; CHECK-NEXT: LBB17_1: ## %is_null 472; CHECK-NEXT: movl $42, %eax 473; CHECK-NEXT: retq 474 475entry: 476 %c = icmp eq ptr %x, null 477 br i1 %c, label %is_null, label %not_null, !make.implicit !0 478 479is_null: 480 ret i32 42 481 482not_null: 483 fence seq_cst 484 %t = load i32, ptr %x 485 ret i32 %t 486} 487 488define void @imp_null_check_store(ptr %x) { 489; CHECK-LABEL: imp_null_check_store: 490; CHECK: ## %bb.0: ## %entry 491; CHECK-NEXT: Ltmp14: 492; CHECK-NEXT: movl $1, (%rdi) ## on-fault: LBB18_1 493; CHECK-NEXT: ## %bb.2: ## %not_null 494; CHECK-NEXT: retq 495; CHECK-NEXT: LBB18_1: ## %is_null 496; CHECK-NEXT: retq 497 498 entry: 499 %c = icmp eq ptr %x, null 500 br i1 %c, label %is_null, label %not_null, !make.implicit !0 501 502 is_null: 503 ret void 504 505 not_null: 506 store i32 1, ptr %x 507 ret void 508} 509 510;; TODO: can be implicit 511define void @imp_null_check_unordered_store(ptr %x) { 512; CHECK-LABEL: imp_null_check_unordered_store: 513; CHECK: ## %bb.0: ## %entry 514; CHECK-NEXT: Ltmp15: 515; CHECK-NEXT: movl $1, (%rdi) ## on-fault: LBB19_1 516; CHECK-NEXT: ## %bb.2: ## %not_null 517; CHECK-NEXT: retq 518; CHECK-NEXT: LBB19_1: ## %is_null 519; CHECK-NEXT: retq 520 521 entry: 522 %c = icmp eq ptr %x, null 523 br i1 %c, label %is_null, label %not_null, !make.implicit !0 524 525 is_null: 526 ret void 527 528 not_null: 529 store atomic i32 1, ptr %x unordered, align 4 530 ret void 531} 532 533define i32 @imp_null_check_neg_gep_load(ptr %x) { 534; CHECK-LABEL: imp_null_check_neg_gep_load: 535; CHECK: ## %bb.0: ## %entry 536; CHECK-NEXT: Ltmp16: 537; CHECK-NEXT: movl -128(%rdi), %eax ## on-fault: LBB20_1 538; CHECK-NEXT: ## %bb.2: ## %not_null 539; CHECK-NEXT: retq 540; CHECK-NEXT: LBB20_1: ## %is_null 541; CHECK-NEXT: movl $42, %eax 542; CHECK-NEXT: retq 543 544 entry: 545 %c = icmp eq ptr %x, null 546 br i1 %c, label %is_null, label %not_null, !make.implicit !0 547 548 is_null: 549 ret i32 42 550 551 not_null: 552 %x.gep = getelementptr i32, ptr %x, i32 -32 553 %t = load i32, ptr %x.gep 554 ret i32 %t 555} 556 557; This redefines the null check reg by doing a zero-extend and a shift on 558; itself. 559; Converted into implicit null check since both of these operations do not 560; change the nullness of %x (i.e. if it is null, it remains null). 561define i64 @imp_null_check_load_shift_addr(ptr %x) { 562; CHECK-LABEL: imp_null_check_load_shift_addr: 563; CHECK: ## %bb.0: ## %entry 564; CHECK-NEXT: shlq $6, %rdi 565; CHECK-NEXT: Ltmp17: 566; CHECK-NEXT: movq 8(%rdi), %rax ## on-fault: LBB21_1 567; CHECK-NEXT: ## %bb.2: ## %not_null 568; CHECK-NEXT: retq 569; CHECK-NEXT: LBB21_1: ## %is_null 570; CHECK-NEXT: movl $42, %eax 571; CHECK-NEXT: retq 572 573 entry: 574 %c = icmp eq ptr %x, null 575 br i1 %c, label %is_null, label %not_null, !make.implicit !0 576 577 is_null: 578 ret i64 42 579 580 not_null: 581 %y = ptrtoint ptr %x to i64 582 %shry = shl i64 %y, 6 583 %y.ptr = inttoptr i64 %shry to ptr 584 %x.loc = getelementptr i64, ptr %y.ptr, i64 1 585 %t = load i64, ptr %x.loc 586 ret i64 %t 587} 588 589; Same as imp_null_check_load_shift_addr but shift is by 3 and this is now 590; converted into complex addressing. 591define i64 @imp_null_check_load_shift_by_3_addr(ptr %x) { 592; CHECK-LABEL: imp_null_check_load_shift_by_3_addr: 593; CHECK: ## %bb.0: ## %entry 594; CHECK-NEXT: Ltmp18: 595; CHECK-NEXT: movq 8(,%rdi,8), %rax ## on-fault: LBB22_1 596; CHECK-NEXT: ## %bb.2: ## %not_null 597; CHECK-NEXT: retq 598; CHECK-NEXT: LBB22_1: ## %is_null 599; CHECK-NEXT: movl $42, %eax 600; CHECK-NEXT: retq 601 602 entry: 603 %c = icmp eq ptr %x, null 604 br i1 %c, label %is_null, label %not_null, !make.implicit !0 605 606 is_null: 607 ret i64 42 608 609 not_null: 610 %y = ptrtoint ptr %x to i64 611 %shry = shl i64 %y, 3 612 %y.ptr = inttoptr i64 %shry to ptr 613 %x.loc = getelementptr i64, ptr %y.ptr, i64 1 614 %t = load i64, ptr %x.loc 615 ret i64 %t 616} 617 618define i64 @imp_null_check_load_shift_add_addr(ptr %x) { 619; CHECK-LABEL: imp_null_check_load_shift_add_addr: 620; CHECK: ## %bb.0: ## %entry 621; CHECK-NEXT: Ltmp19: 622; CHECK-NEXT: movq 3526(,%rdi,8), %rax ## on-fault: LBB23_1 623; CHECK-NEXT: ## %bb.2: ## %not_null 624; CHECK-NEXT: retq 625; CHECK-NEXT: LBB23_1: ## %is_null 626; CHECK-NEXT: movl $42, %eax 627; CHECK-NEXT: retq 628 629 entry: 630 %c = icmp eq ptr %x, null 631 br i1 %c, label %is_null, label %not_null, !make.implicit !0 632 633 is_null: 634 ret i64 42 635 636 not_null: 637 %y = ptrtoint ptr %x to i64 638 %shry = shl i64 %y, 3 639 %shry.add = add i64 %shry, 3518 640 %y.ptr = inttoptr i64 %shry.add to ptr 641 %x.loc = getelementptr i64, ptr %y.ptr, i64 1 642 %t = load i64, ptr %x.loc 643 ret i64 %t 644} 645!0 = !{} 646