535 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; Tests to make sure elimination of casts is working correctly3; RUN: opt < %s -passes=instcombine -S | FileCheck %s4 5target datalayout = "p:32:32-p1:32:32-p2:16:16-p3:32:32:32:16"6 7@global = global i8 08 9; This shouldn't convert to getelementptr because the relationship10; between the arithmetic and the layout of allocated memory is11; entirely unknown.12 13define ptr @test1(ptr %t) {14; CHECK-LABEL: @test1(15; CHECK-NEXT: [[TC:%.*]] = ptrtoint ptr [[T:%.*]] to i3216; CHECK-NEXT: [[TA:%.*]] = add i32 [[TC]], 3217; CHECK-NEXT: [[TV:%.*]] = inttoptr i32 [[TA]] to ptr18; CHECK-NEXT: ret ptr [[TV]]19;20 %tc = ptrtoint ptr %t to i3221 %ta = add i32 %tc, 3222 %tv = inttoptr i32 %ta to ptr23 ret ptr %tv24}25 26; These casts should be folded away.27 28define i1 @test2(ptr %a, ptr %b) {29; CHECK-LABEL: @test2(30; CHECK-NEXT: [[R:%.*]] = icmp eq ptr [[A:%.*]], [[B:%.*]]31; CHECK-NEXT: ret i1 [[R]]32;33 %ta = ptrtoint ptr %a to i3234 %tb = ptrtoint ptr %b to i3235 %r = icmp eq i32 %ta, %tb36 ret i1 %r37}38 39; These casts should be folded away.40 41define i1 @test2_as2_same_int(ptr addrspace(2) %a, ptr addrspace(2) %b) {42; CHECK-LABEL: @test2_as2_same_int(43; CHECK-NEXT: [[R:%.*]] = icmp eq ptr addrspace(2) [[A:%.*]], [[B:%.*]]44; CHECK-NEXT: ret i1 [[R]]45;46 %ta = ptrtoint ptr addrspace(2) %a to i1647 %tb = ptrtoint ptr addrspace(2) %b to i1648 %r = icmp eq i16 %ta, %tb49 ret i1 %r50}51 52; These casts should be folded away.53 54define i1 @test2_as2_larger(ptr addrspace(2) %a, ptr addrspace(2) %b) {55; CHECK-LABEL: @test2_as2_larger(56; CHECK-NEXT: [[R:%.*]] = icmp eq ptr addrspace(2) [[A:%.*]], [[B:%.*]]57; CHECK-NEXT: ret i1 [[R]]58;59 %ta = ptrtoint ptr addrspace(2) %a to i3260 %tb = ptrtoint ptr addrspace(2) %b to i3261 %r = icmp eq i32 %ta, %tb62 ret i1 %r63}64 65; These casts should not be folded away.66 67define i1 @test2_diff_as(ptr %p, ptr addrspace(1) %q) {68; CHECK-LABEL: @test2_diff_as(69; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P:%.*]] to i3270; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr addrspace(1) [[Q:%.*]] to i3271; CHECK-NEXT: [[R0:%.*]] = icmp sge i32 [[I0]], [[I1]]72; CHECK-NEXT: ret i1 [[R0]]73;74 %i0 = ptrtoint ptr %p to i3275 %i1 = ptrtoint ptr addrspace(1) %q to i3276 %r0 = icmp sge i32 %i0, %i177 ret i1 %r078}79 80; These casts should not be folded away.81 82define i1 @test2_diff_as_global(ptr addrspace(1) %q) {83; CHECK-LABEL: @test2_diff_as_global(84; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr addrspace(1) [[Q:%.*]] to i3285; CHECK-NEXT: [[R0:%.*]] = icmp sge i32 [[I1]], ptrtoint (ptr @global to i32)86; CHECK-NEXT: ret i1 [[R0]]87;88 %i0 = ptrtoint ptr @global to i3289 %i1 = ptrtoint ptr addrspace(1) %q to i3290 %r0 = icmp sge i32 %i1, %i091 ret i1 %r092}93 94; These casts should also be folded away.95 96define i1 @test3(ptr %a) {97; CHECK-LABEL: @test3(98; CHECK-NEXT: [[R:%.*]] = icmp eq ptr [[A:%.*]], @global99; CHECK-NEXT: ret i1 [[R]]100;101 %ta = ptrtoint ptr %a to i32102 %r = icmp eq i32 %ta, ptrtoint (ptr @global to i32)103 ret i1 %r104}105 106define i1 @test4(i32 %A) {107; CHECK-LABEL: @test4(108; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A:%.*]], 0109; CHECK-NEXT: ret i1 [[C]]110;111 %B = inttoptr i32 %A to ptr112 %C = icmp eq ptr %B, null113 ret i1 %C114}115 116define i1 @test4_as2(i16 %A) {117; CHECK-LABEL: @test4_as2(118; CHECK-NEXT: [[C:%.*]] = icmp eq i16 [[A:%.*]], 0119; CHECK-NEXT: ret i1 [[C]]120;121 %B = inttoptr i16 %A to ptr addrspace(2)122 %C = icmp eq ptr addrspace(2) %B, null123 ret i1 %C124}125 126 127; Pulling the cast out of the load allows us to eliminate the load, and then128; the whole array.129 130 %op = type { float }131 %unop = type { i32 }132@Array = internal constant [1 x ptr] [ ptr @foo ]133 134declare ptr @foo(ptr %X)135 136define ptr @test5(ptr %O) {137; CHECK-LABEL: @test5(138; CHECK-NEXT: [[T_2:%.*]] = call ptr @foo(ptr [[O:%.*]])139; CHECK-NEXT: ret ptr [[T_2]]140;141 %t = load ptr, ptr @Array; <ptr> [#uses=1]142 %t.2 = call ptr %t( ptr %O )143 ret ptr %t.2144}145 146 147 148; InstCombine can not 'load (cast P)' -> cast (load P)' if the cast changes149; the address space.150 151define i8 @test6(ptr addrspace(1) %source) {152; CHECK-LABEL: @test6(153; CHECK-NEXT: entry:154; CHECK-NEXT: [[ARRAYIDX223:%.*]] = addrspacecast ptr addrspace(1) [[SOURCE:%.*]] to ptr155; CHECK-NEXT: [[T4:%.*]] = load i8, ptr [[ARRAYIDX223]], align 1156; CHECK-NEXT: ret i8 [[T4]]157;158entry:159 %arrayidx223 = addrspacecast ptr addrspace(1) %source to ptr160 %t4 = load i8, ptr %arrayidx223161 ret i8 %t4162}163 164define <2 x i32> @insertelt(<2 x i32> %x, ptr %p, i133 %index) {165; CHECK-LABEL: @insertelt(166; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P:%.*]] to i32167; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i32> [[X:%.*]], i32 [[TMP1]], i133 [[INDEX:%.*]]168; CHECK-NEXT: ret <2 x i32> [[R]]169;170 %v = inttoptr <2 x i32> %x to <2 x ptr>171 %i = insertelement <2 x ptr> %v, ptr %p, i133 %index172 %r = ptrtoint <2 x ptr> %i to <2 x i32>173 ret <2 x i32> %r174}175 176define <2 x i32> @insertelt_intptr_trunc(<2 x i64> %x, ptr %p) {177; CHECK-LABEL: @insertelt_intptr_trunc(178; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i64> [[X:%.*]] to <2 x i32>179; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[P:%.*]] to i32180; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP2]], i64 0181; CHECK-NEXT: ret <2 x i32> [[R]]182;183 %v = inttoptr <2 x i64> %x to <2 x ptr>184 %i = insertelement <2 x ptr> %v, ptr %p, i32 0185 %r = ptrtoint <2 x ptr> %i to <2 x i32>186 ret <2 x i32> %r187}188 189define <2 x i32> @insertelt_intptr_zext(<2 x i8> %x, ptr %p) {190; CHECK-LABEL: @insertelt_intptr_zext(191; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>192; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[P:%.*]] to i32193; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP2]], i64 1194; CHECK-NEXT: ret <2 x i32> [[R]]195;196 %v = inttoptr <2 x i8> %x to <2 x ptr>197 %i = insertelement <2 x ptr> %v, ptr %p, i32 1198 %r = ptrtoint <2 x ptr> %i to <2 x i32>199 ret <2 x i32> %r200}201 202define <2 x i64> @insertelt_intptr_zext_zext(<2 x i8> %x, ptr %p) {203; CHECK-LABEL: @insertelt_intptr_zext_zext(204; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>205; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[P:%.*]] to i32206; CHECK-NEXT: [[TMP3:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[TMP2]], i64 0207; CHECK-NEXT: [[R:%.*]] = zext <2 x i32> [[TMP3]] to <2 x i64>208; CHECK-NEXT: ret <2 x i64> [[R]]209;210 %v = inttoptr <2 x i8> %x to <2 x ptr>211 %i = insertelement <2 x ptr> %v, ptr %p, i32 0212 %r = ptrtoint <2 x ptr> %i to <2 x i64>213 ret <2 x i64> %r214}215 216declare void @use(<2 x ptr>)217 218define <2 x i32> @insertelt_extra_use1(<2 x i32> %x, ptr %p) {219; CHECK-LABEL: @insertelt_extra_use1(220; CHECK-NEXT: [[V:%.*]] = inttoptr <2 x i32> [[X:%.*]] to <2 x ptr>221; CHECK-NEXT: call void @use(<2 x ptr> [[V]])222; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P:%.*]] to i32223; CHECK-NEXT: [[R:%.*]] = insertelement <2 x i32> [[X]], i32 [[TMP1]], i64 0224; CHECK-NEXT: ret <2 x i32> [[R]]225;226 %v = inttoptr <2 x i32> %x to <2 x ptr>227 call void @use(<2 x ptr> %v)228 %i = insertelement <2 x ptr> %v, ptr %p, i32 0229 %r = ptrtoint <2 x ptr> %i to <2 x i32>230 ret <2 x i32> %r231}232 233define <2 x i32> @insertelt_extra_use2(<2 x i32> %x, ptr %p) {234; CHECK-LABEL: @insertelt_extra_use2(235; CHECK-NEXT: [[V:%.*]] = inttoptr <2 x i32> [[X:%.*]] to <2 x ptr>236; CHECK-NEXT: [[I:%.*]] = insertelement <2 x ptr> [[V]], ptr [[P:%.*]], i64 0237; CHECK-NEXT: call void @use(<2 x ptr> [[I]])238; CHECK-NEXT: [[R:%.*]] = ptrtoint <2 x ptr> [[I]] to <2 x i32>239; CHECK-NEXT: ret <2 x i32> [[R]]240;241 %v = inttoptr <2 x i32> %x to <2 x ptr>242 %i = insertelement <2 x ptr> %v, ptr %p, i32 0243 call void @use(<2 x ptr> %i)244 %r = ptrtoint <2 x ptr> %i to <2 x i32>245 ret <2 x i32> %r246}247 248define i32 @ptr_add_in_int(i32 %x, i32 %y) {249; CHECK-LABEL: @ptr_add_in_int(250; CHECK-NEXT: [[R:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]251; CHECK-NEXT: ret i32 [[R]]252;253 %ptr = inttoptr i32 %x to ptr254 %p2 = getelementptr inbounds i8, ptr %ptr, i32 %y255 %r = ptrtoint ptr %p2 to i32256 ret i32 %r257}258 259define i32 @ptr_add_in_int_2(i32 %x, i32 %y) {260; CHECK-LABEL: @ptr_add_in_int_2(261; CHECK-NEXT: [[P2_IDX:%.*]] = shl nsw i32 [[Y:%.*]], 2262; CHECK-NEXT: [[R:%.*]] = add i32 [[X:%.*]], [[P2_IDX]]263; CHECK-NEXT: ret i32 [[R]]264;265 %ptr = inttoptr i32 %x to ptr266 %p2 = getelementptr inbounds i32, ptr %ptr, i32 %y267 %r = ptrtoint ptr %p2 to i32268 ret i32 %r269}270 271define i32 @ptr_add_in_int_nneg(i32 %x, i32 %y) {272; CHECK-LABEL: @ptr_add_in_int_nneg(273; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 true)274; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], [[Z]]275; CHECK-NEXT: ret i32 [[R]]276;277 %z = call i32 @llvm.abs.i32(i32 %y, i1 true)278 %ptr = inttoptr i32 %x to ptr279 %p2 = getelementptr inbounds i8, ptr %ptr, i32 %z280 %r = ptrtoint ptr %p2 to i32281 ret i32 %r282}283 284define i64 @ptr_add_in_int_different_type_1(i32 %x, i32 %y) {285; CHECK-LABEL: @ptr_add_in_int_different_type_1(286; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]287; CHECK-NEXT: [[R:%.*]] = zext i32 [[TMP1]] to i64288; CHECK-NEXT: ret i64 [[R]]289;290 %ptr = inttoptr i32 %x to ptr291 %p2 = getelementptr i8, ptr %ptr, i32 %y292 %r = ptrtoint ptr %p2 to i64293 ret i64 %r294}295 296define i16 @ptr_add_in_int_different_type_2(i32 %x, i32 %y) {297; CHECK-LABEL: @ptr_add_in_int_different_type_2(298; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]299; CHECK-NEXT: [[R:%.*]] = trunc i32 [[TMP1]] to i16300; CHECK-NEXT: ret i16 [[R]]301;302 %ptr = inttoptr i32 %x to ptr303 %p2 = getelementptr i8, ptr %ptr, i32 %y304 %r = ptrtoint ptr %p2 to i16305 ret i16 %r306}307 308define i32 @ptr_add_in_int_different_type_3(i16 %x, i32 %y) {309; CHECK-LABEL: @ptr_add_in_int_different_type_3(310; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32311; CHECK-NEXT: [[R:%.*]] = add i32 [[Y:%.*]], [[TMP1]]312; CHECK-NEXT: ret i32 [[R]]313;314 %ptr = inttoptr i16 %x to ptr315 %p2 = getelementptr i8, ptr %ptr, i32 %y316 %r = ptrtoint ptr %p2 to i32317 ret i32 %r318}319 320define i32 @ptr_add_in_int_different_type_4(i64 %x, i32 %y) {321; CHECK-LABEL: @ptr_add_in_int_different_type_4(322; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32323; CHECK-NEXT: [[R:%.*]] = add i32 [[Y:%.*]], [[TMP1]]324; CHECK-NEXT: ret i32 [[R]]325;326 %ptr = inttoptr i64 %x to ptr327 %p2 = getelementptr i8, ptr %ptr, i32 %y328 %r = ptrtoint ptr %p2 to i32329 ret i32 %r330}331 332define i32 @ptr_add_in_int_not_inbounds(i32 %x, i32 %y) {333; CHECK-LABEL: @ptr_add_in_int_not_inbounds(334; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 true)335; CHECK-NEXT: [[R:%.*]] = add i32 [[X:%.*]], [[Z]]336; CHECK-NEXT: ret i32 [[R]]337;338 %z = call i32 @llvm.abs.i32(i32 %y, i1 true)339 %ptr = inttoptr i32 %x to ptr340 %p2 = getelementptr i8, ptr %ptr, i32 %z341 %r = ptrtoint ptr %p2 to i32342 ret i32 %r343}344 345define i32 @ptr_add_in_int_nuw(i32 %x, i32 %y) {346; CHECK-LABEL: @ptr_add_in_int_nuw(347; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]]348; CHECK-NEXT: ret i32 [[R]]349;350 %ptr = inttoptr i32 %x to ptr351 %p2 = getelementptr nuw i8, ptr %ptr, i32 %y352 %r = ptrtoint ptr %p2 to i32353 ret i32 %r354}355 356define i32 @ptr_add_in_int_nusw(i32 %x, i32 %y) {357; CHECK-LABEL: @ptr_add_in_int_nusw(358; CHECK-NEXT: [[R:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]359; CHECK-NEXT: ret i32 [[R]]360;361 %ptr = inttoptr i32 %x to ptr362 %p2 = getelementptr nusw i8, ptr %ptr, i32 %y363 %r = ptrtoint ptr %p2 to i32364 ret i32 %r365}366 367define i32 @ptr_add_in_int_nusw_nneg(i32 %x, i32 %y) {368; CHECK-LABEL: @ptr_add_in_int_nusw_nneg(369; CHECK-NEXT: [[NNEG:%.*]] = icmp sgt i32 [[Y:%.*]], -1370; CHECK-NEXT: call void @llvm.assume(i1 [[NNEG]])371; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], [[Y]]372; CHECK-NEXT: ret i32 [[R]]373;374 %nneg = icmp sge i32 %y, 0375 call void @llvm.assume(i1 %nneg)376 %ptr = inttoptr i32 %x to ptr377 %p2 = getelementptr nusw i8, ptr %ptr, i32 %y378 %r = ptrtoint ptr %p2 to i32379 ret i32 %r380}381 382define i32 @ptr_add_in_int_const(i32 %x) {383; CHECK-LABEL: @ptr_add_in_int_const(384; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], 4096385; CHECK-NEXT: ret i32 [[R]]386;387 %ptr = inttoptr i32 %x to ptr388 %p2 = getelementptr inbounds i8, ptr %ptr, i32 4096389 %r = ptrtoint ptr %p2 to i32390 ret i32 %r391}392 393define i32 @ptr_add_in_int_const_negative(i32 %x) {394; CHECK-LABEL: @ptr_add_in_int_const_negative(395; CHECK-NEXT: [[R:%.*]] = add i32 [[X:%.*]], -4096396; CHECK-NEXT: ret i32 [[R]]397;398 %ptr = inttoptr i32 %x to ptr399 %p2 = getelementptr inbounds i8, ptr %ptr, i32 -4096400 %r = ptrtoint ptr %p2 to i32401 ret i32 %r402}403 404declare void @use_ptr(ptr)405 406define i32 @ptr_add_in_int_extra_use1(i32 %x) {407; CHECK-LABEL: @ptr_add_in_int_extra_use1(408; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr409; CHECK-NEXT: call void @use_ptr(ptr [[PTR]])410; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i32 4096411; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[P2]] to i32412; CHECK-NEXT: ret i32 [[R]]413;414 %ptr = inttoptr i32 %x to ptr415 call void @use_ptr(ptr %ptr)416 %p2 = getelementptr inbounds i8, ptr %ptr, i32 4096417 %r = ptrtoint ptr %p2 to i32418 ret i32 %r419}420 421define i32 @ptr_add_in_int_extra_use2(i32 %x) {422; CHECK-LABEL: @ptr_add_in_int_extra_use2(423; CHECK-NEXT: [[PTR:%.*]] = inttoptr i32 [[X:%.*]] to ptr424; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i32 4096425; CHECK-NEXT: call void @use_ptr(ptr nonnull [[P2]])426; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[P2]] to i32427; CHECK-NEXT: ret i32 [[R]]428;429 %ptr = inttoptr i32 %x to ptr430 %p2 = getelementptr inbounds i8, ptr %ptr, i32 4096431 call void @use_ptr(ptr %p2)432 %r = ptrtoint ptr %p2 to i32433 ret i32 %r434}435 436define 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:%.*]], 1439; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[X:%.*]], [[PTR2_IDX]]440; CHECK-NEXT: [[PTR3_IDX:%.*]] = shl i32 [[Z:%.*]], 2441; CHECK-NEXT: [[R:%.*]] = add i32 [[TMP1]], [[PTR3_IDX]]442; CHECK-NEXT: ret i32 [[R]]443;444 %ptr = inttoptr i32 %x to ptr445 %ptr2 = getelementptr nuw i16, ptr %ptr, i32 %y446 %ptr3 = getelementptr i32, ptr %ptr2, i32 %z447 %r = ptrtoint ptr %ptr3 to i32448 ret i32 %r449}450 451define 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 ptr454; 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 i32458; CHECK-NEXT: ret i32 [[R]]459;460 %ptr = inttoptr i32 %x to ptr461 %ptr2 = getelementptr i16, ptr %ptr, i32 %y462 call void @use_ptr(ptr %ptr2)463 %ptr3 = getelementptr i32, ptr %ptr2, i32 %z464 %r = ptrtoint ptr %ptr3 to i32465 ret i32 %r466}467 468define 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 i32473; CHECK-NEXT: ret i32 [[R]]474;475 %ptr = inttoptr i32 %x to ptr addrspace(3)476 %ptr2 = getelementptr i16, ptr addrspace(3) %ptr, i16 %y477 %r = ptrtoint ptr addrspace(3) %ptr2 to i32478 ret i32 %r479}480 481define 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:%.*]], 1484; CHECK-NEXT: [[PTR3_IDX:%.*]] = shl nuw i32 [[Y:%.*]], 2485; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[PTR2_IDX]], [[PTR3_IDX]]486; CHECK-NEXT: [[PTR4_IDX:%.*]] = shl i32 [[Z:%.*]], 3487; CHECK-NEXT: [[R:%.*]] = add i32 [[TMP1]], [[PTR4_IDX]]488; CHECK-NEXT: ret i32 [[R]]489;490 %ptr2 = getelementptr i16, ptr null, i32 %x491 %ptr3 = getelementptr nuw i32, ptr %ptr2, i32 %y492 %ptr4 = getelementptr i64, ptr %ptr3, i32 %z493 %r = ptrtoint ptr %ptr4 to i32494 ret i32 %r495}496 497define 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 i32504; CHECK-NEXT: ret i32 [[R]]505;506 %ptr2 = getelementptr i16, ptr null, i32 %x507 call void @use_ptr(ptr %ptr2)508 %ptr3 = getelementptr nuw i32, ptr %ptr2, i32 %y509 %ptr4 = getelementptr i64, ptr %ptr3, i32 %z510 %r = ptrtoint ptr %ptr4 to i32511 ret i32 %r512}513 514define i32 @ptrtoint_of_null_index_type(i16 %x) {515; CHECK-LABEL: @ptrtoint_of_null_index_type(516; CHECK-NEXT: [[PTR_IDX:%.*]] = shl i16 [[X:%.*]], 1517; CHECK-NEXT: [[R:%.*]] = zext i16 [[PTR_IDX]] to i32518; CHECK-NEXT: ret i32 [[R]]519;520 %ptr = getelementptr i16, ptr addrspace(3) null, i16 %x521 %r = ptrtoint ptr addrspace(3) %ptr to i32522 ret i32 %r523}524 525define <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> %x532 %r = ptrtoint <2 x ptr addrspace(3)> %ptr to <2 x i32>533 ret <2 x i32> %r534}535