1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S -disable-i2p-p2i-opt < %s | FileCheck %s 3 4target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64" 5target triple = "x86_64-unknown-linux-gnu" 6 7; convert ptrtoint [ phi[ inttoptr (ptrtoint (x) ) ] ---> ptrtoint (phi[x]) 8 9define i64 @func(ptr %X, ptr %Y, i1 %cond) { 10; CHECK-LABEL: @func( 11; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 12; CHECK: bb1: 13; CHECK-NEXT: br label [[EXIT:%.*]] 14; CHECK: bb2: 15; CHECK-NEXT: br label [[EXIT]] 16; CHECK: exit: 17; CHECK-NEXT: [[PHI_IN:%.*]] = phi ptr [ [[X:%.*]], [[BB1]] ], [ [[Y:%.*]], [[BB2]] ] 18; CHECK-NEXT: [[X_P_I:%.*]] = ptrtoint ptr [[PHI_IN]] to i64 19; CHECK-NEXT: ret i64 [[X_P_I]] 20; 21 br i1 %cond, label %bb1, label %bb2 22 23bb1: 24 %X.i = ptrtoint ptr %X to i64 25 %X.p = inttoptr i64 %X.i to ptr 26 br label %exit 27 28bb2: 29 %Y.i = ptrtoint ptr %Y to i64 30 %Y.p = inttoptr i64 %Y.i to ptr 31 br label %exit 32 33exit: 34 %phi = phi ptr [%X.p, %bb1], [%Y.p, %bb2] 35 %X.p.i = ptrtoint ptr %phi to i64 36 ret i64 %X.p.i 37} 38 39define i64 @func_single_operand(ptr %X, ptr %Y, i1 %cond) { 40; CHECK-LABEL: @func_single_operand( 41; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]] 42; CHECK: bb1: 43; CHECK-NEXT: br label [[EXIT]] 44; CHECK: exit: 45; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[X:%.*]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ] 46; CHECK-NEXT: [[X_P_I:%.*]] = ptrtoint ptr [[PHI]] to i64 47; CHECK-NEXT: ret i64 [[X_P_I]] 48; 49 br i1 %cond, label %bb1, label %exit 50 51bb1: 52 %X.i = ptrtoint ptr %X to i64 53 %X.p = inttoptr i64 %X.i to ptr 54 br label %exit 55 56exit: 57 %phi = phi ptr [%X.p, %bb1], [%Y, %0] 58 %X.p.i = ptrtoint ptr %phi to i64 59 ret i64 %X.p.i 60} 61 62define i64 @func_pointer_different_types(ptr %X, ptr %Y, i1 %cond) { 63; CHECK-LABEL: @func_pointer_different_types( 64; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]] 65; CHECK: bb1: 66; CHECK-NEXT: br label [[EXIT]] 67; CHECK: exit: 68; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[X:%.*]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ] 69; CHECK-NEXT: [[X_P_I:%.*]] = ptrtoint ptr [[PHI]] to i64 70; CHECK-NEXT: ret i64 [[X_P_I]] 71; 72 br i1 %cond, label %bb1, label %exit 73 74bb1: 75 %X.i = ptrtoint ptr %X to i64 76 %X.p = inttoptr i64 %X.i to ptr 77 br label %exit 78 79exit: 80 %phi = phi ptr [%X.p, %bb1], [%Y, %0] 81 %X.p.i = ptrtoint ptr %phi to i64 82 ret i64 %X.p.i 83} 84 85; Negative test - Wrong Integer type 86 87define i64 @func_integer_type_too_small(ptr %X, ptr %Y, i1 %cond) { 88; CHECK-LABEL: @func_integer_type_too_small( 89; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]] 90; CHECK: bb1: 91; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[X:%.*]] to i64 92; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], 4294967295 93; CHECK-NEXT: [[X_P:%.*]] = inttoptr i64 [[TMP2]] to ptr 94; CHECK-NEXT: br label [[EXIT]] 95; CHECK: exit: 96; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[X_P]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ] 97; CHECK-NEXT: [[X_P_I:%.*]] = ptrtoint ptr [[PHI]] to i64 98; CHECK-NEXT: ret i64 [[X_P_I]] 99; 100 br i1 %cond, label %bb1, label %exit 101 102bb1: 103 %X.i = ptrtoint ptr %X to i32 104 %X.p = inttoptr i32 %X.i to ptr 105 br label %exit 106 107exit: 108 %phi = phi ptr [%X.p, %bb1], [%Y, %0] 109 %X.p.i = ptrtoint ptr %phi to i64 110 ret i64 %X.p.i 111} 112 113; Negative test - phi not used in ptrtoint 114 115define ptr @func_phi_not_use_in_ptr2int(ptr %X, ptr %Y, i1 %cond) { 116; CHECK-LABEL: @func_phi_not_use_in_ptr2int( 117; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]] 118; CHECK: bb1: 119; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[X:%.*]] to i64 120; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], 4294967295 121; CHECK-NEXT: [[X_P:%.*]] = inttoptr i64 [[TMP2]] to ptr 122; CHECK-NEXT: br label [[EXIT]] 123; CHECK: exit: 124; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[X_P]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ] 125; CHECK-NEXT: ret ptr [[PHI]] 126; 127 br i1 %cond, label %bb1, label %exit 128 129bb1: 130 %X.i = ptrtoint ptr %X to i32 131 %X.p = inttoptr i32 %X.i to ptr 132 br label %exit 133 134exit: 135 %phi = phi ptr [%X.p, %bb1], [%Y, %0] 136 ret ptr %phi 137} 138 139; Negative test - Pointers in different address spaces 140 141define i64 @func_ptr_different_addrspace(ptr addrspace(2) %X, ptr %Y, i1 %cond) { 142; CHECK-LABEL: @func_ptr_different_addrspace( 143; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[EXIT:%.*]] 144; CHECK: bb1: 145; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(2) [[X:%.*]] to i32 146; CHECK-NEXT: [[X_I:%.*]] = zext i32 [[TMP1]] to i64 147; CHECK-NEXT: [[X_P:%.*]] = inttoptr i64 [[X_I]] to ptr 148; CHECK-NEXT: br label [[EXIT]] 149; CHECK: exit: 150; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[X_P]], [[BB1]] ], [ [[Y:%.*]], [[TMP0:%.*]] ] 151; CHECK-NEXT: [[X_P_I:%.*]] = ptrtoint ptr [[PHI]] to i64 152; CHECK-NEXT: ret i64 [[X_P_I]] 153; 154 br i1 %cond, label %bb1, label %exit 155 156bb1: 157 %X.i = ptrtoint ptr addrspace(2) %X to i64 158 %X.p = inttoptr i64 %X.i to ptr 159 br label %exit 160 161exit: 162 %phi = phi ptr [%X.p, %bb1], [%Y, %0] 163 %X.p.i = ptrtoint ptr %phi to i64 164 ret i64 %X.p.i 165} 166