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