|
2 | 2 | ; Tests to make sure elimination of casts is working correctly
|
3 | 3 | ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
4 | 4 |
|
5 |
| -target datalayout = "p:32:32-p1:32:32-p2:16:16" |
| 5 | +target datalayout = "p:32:32-p1:32:32-p2:16:16-p3:32:32:32:16" |
6 | 6 |
|
7 | 7 | @global = global i8 0
|
8 | 8 |
|
@@ -432,3 +432,103 @@ define i32 @ptr_add_in_int_extra_use2(i32 %x) {
|
432 | 432 | %r = ptrtoint ptr %p2 to i32
|
433 | 433 | ret i32 %r
|
434 | 434 | }
|
| 435 | + |
| 436 | +define i32 @ptrtoint_of_inttoptr_multiple_gep(i32 %x, i32 %y, i32 %z) { |
| 437 | +; CHECK-LABEL: @ptrtoint_of_inttoptr_multiple_gep( |
| 438 | +; CHECK-NEXT: [[PTR2_IDX:%.*]] = shl nuw i32 [[Y:%.*]], 1 |
| 439 | +; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[X:%.*]], [[PTR2_IDX]] |
| 440 | +; CHECK-NEXT: [[PTR3_IDX:%.*]] = shl i32 [[Z:%.*]], 2 |
| 441 | +; CHECK-NEXT: [[R:%.*]] = add i32 [[TMP1]], [[PTR3_IDX]] |
| 442 | +; CHECK-NEXT: ret i32 [[R]] |
| 443 | +; |
| 444 | + %ptr = inttoptr i32 %x to ptr |
| 445 | + %ptr2 = getelementptr nuw i16, ptr %ptr, i32 %y |
| 446 | + %ptr3 = getelementptr i32, ptr %ptr2, i32 %z |
| 447 | + %r = ptrtoint ptr %ptr3 to i32 |
| 448 | + ret i32 %r |
| 449 | +} |
| 450 | + |
| 451 | +define i32 @ptrtoint_of_inttoptr_multiple_gep_extra_use(i32 %x, i32 %y, i32 %z) { |
| 452 | +; CHECK-LABEL: @ptrtoint_of_inttoptr_multiple_gep_extra_use( |
| 453 | +; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr |
| 454 | +; CHECK-NEXT: [[PTR2:%.*]] = getelementptr i16, ptr [[PTR]], i32 [[Y:%.*]] |
| 455 | +; CHECK-NEXT: call void @use_ptr(ptr [[PTR2]]) |
| 456 | +; CHECK-NEXT: [[PTR3:%.*]] = getelementptr i32, ptr [[PTR2]], i32 [[Z:%.*]] |
| 457 | +; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[PTR3]] to i32 |
| 458 | +; CHECK-NEXT: ret i32 [[R]] |
| 459 | +; |
| 460 | + %ptr = inttoptr i32 %x to ptr |
| 461 | + %ptr2 = getelementptr i16, ptr %ptr, i32 %y |
| 462 | + call void @use_ptr(ptr %ptr2) |
| 463 | + %ptr3 = getelementptr i32, ptr %ptr2, i32 %z |
| 464 | + %r = ptrtoint ptr %ptr3 to i32 |
| 465 | + ret i32 %r |
| 466 | +} |
| 467 | + |
| 468 | +define i32 @ptrtoint_of_inttoptr_index_type(i32 %x, i16 %y) { |
| 469 | +; CHECK-LABEL: @ptrtoint_of_inttoptr_index_type( |
| 470 | +; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr addrspace(3) |
| 471 | +; CHECK-NEXT: [[PTR2:%.*]] = getelementptr i16, ptr addrspace(3) [[PTR]], i16 [[Y:%.*]] |
| 472 | +; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr addrspace(3) [[PTR2]] to i32 |
| 473 | +; CHECK-NEXT: ret i32 [[R]] |
| 474 | +; |
| 475 | + %ptr = inttoptr i32 %x to ptr addrspace(3) |
| 476 | + %ptr2 = getelementptr i16, ptr addrspace(3) %ptr, i16 %y |
| 477 | + %r = ptrtoint ptr addrspace(3) %ptr2 to i32 |
| 478 | + ret i32 %r |
| 479 | +} |
| 480 | + |
| 481 | +define i32 @ptrtoint_of_null_multiple_gep(i32 %x, i32 %y, i32 %z) { |
| 482 | +; CHECK-LABEL: @ptrtoint_of_null_multiple_gep( |
| 483 | +; CHECK-NEXT: [[PTR2_IDX:%.*]] = shl i32 [[X:%.*]], 1 |
| 484 | +; CHECK-NEXT: [[PTR3_IDX:%.*]] = shl nuw i32 [[Y:%.*]], 2 |
| 485 | +; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[PTR2_IDX]], [[PTR3_IDX]] |
| 486 | +; CHECK-NEXT: [[PTR4_IDX:%.*]] = shl i32 [[Z:%.*]], 3 |
| 487 | +; CHECK-NEXT: [[R:%.*]] = add i32 [[TMP1]], [[PTR4_IDX]] |
| 488 | +; CHECK-NEXT: ret i32 [[R]] |
| 489 | +; |
| 490 | + %ptr2 = getelementptr i16, ptr null, i32 %x |
| 491 | + %ptr3 = getelementptr nuw i32, ptr %ptr2, i32 %y |
| 492 | + %ptr4 = getelementptr i64, ptr %ptr3, i32 %z |
| 493 | + %r = ptrtoint ptr %ptr4 to i32 |
| 494 | + ret i32 %r |
| 495 | +} |
| 496 | + |
| 497 | +define i32 @ptrtoint_of_null_multiple_gep_extra_use(i32 %x, i32 %y, i32 %z) { |
| 498 | +; CHECK-LABEL: @ptrtoint_of_null_multiple_gep_extra_use( |
| 499 | +; CHECK-NEXT: [[PTR2:%.*]] = getelementptr i16, ptr null, i32 [[X:%.*]] |
| 500 | +; CHECK-NEXT: call void @use_ptr(ptr [[PTR2]]) |
| 501 | +; CHECK-NEXT: [[PTR3:%.*]] = getelementptr nuw i32, ptr [[PTR2]], i32 [[Y:%.*]] |
| 502 | +; CHECK-NEXT: [[PTR4:%.*]] = getelementptr i64, ptr [[PTR3]], i32 [[Z:%.*]] |
| 503 | +; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[PTR4]] to i32 |
| 504 | +; CHECK-NEXT: ret i32 [[R]] |
| 505 | +; |
| 506 | + %ptr2 = getelementptr i16, ptr null, i32 %x |
| 507 | + call void @use_ptr(ptr %ptr2) |
| 508 | + %ptr3 = getelementptr nuw i32, ptr %ptr2, i32 %y |
| 509 | + %ptr4 = getelementptr i64, ptr %ptr3, i32 %z |
| 510 | + %r = ptrtoint ptr %ptr4 to i32 |
| 511 | + ret i32 %r |
| 512 | +} |
| 513 | + |
| 514 | +define i32 @ptrtoint_of_null_index_type(i16 %x) { |
| 515 | +; CHECK-LABEL: @ptrtoint_of_null_index_type( |
| 516 | +; CHECK-NEXT: [[PTR_IDX:%.*]] = shl i16 [[X:%.*]], 1 |
| 517 | +; CHECK-NEXT: [[R:%.*]] = zext i16 [[PTR_IDX]] to i32 |
| 518 | +; CHECK-NEXT: ret i32 [[R]] |
| 519 | +; |
| 520 | + %ptr = getelementptr i16, ptr addrspace(3) null, i16 %x |
| 521 | + %r = ptrtoint ptr addrspace(3) %ptr to i32 |
| 522 | + ret i32 %r |
| 523 | +} |
| 524 | + |
| 525 | +define <2 x i32> @ptrtoint_of_null_splat(<2 x i16> %x) { |
| 526 | +; CHECK-LABEL: @ptrtoint_of_null_splat( |
| 527 | +; CHECK-NEXT: [[PTR:%.*]] = getelementptr i16, ptr addrspace(3) null, <2 x i16> [[X:%.*]] |
| 528 | +; CHECK-NEXT: [[R:%.*]] = ptrtoint <2 x ptr addrspace(3)> [[PTR]] to <2 x i32> |
| 529 | +; CHECK-NEXT: ret <2 x i32> [[R]] |
| 530 | +; |
| 531 | + %ptr = getelementptr i16, ptr addrspace(3) null, <2 x i16> %x |
| 532 | + %r = ptrtoint <2 x ptr addrspace(3)> %ptr to <2 x i32> |
| 533 | + ret <2 x i32> %r |
| 534 | +} |
0 commit comments