594 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4target datalayout = "p1:64:64:64:32"5 6declare ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1), i32)7declare ptr @llvm.ptrmask.p0.i64(ptr, i64)8declare <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) >, <2 x i32>)9declare <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr>, <2 x i64>)10 11define ptr @ptrmask_combine_consecutive_preserve_attrs(ptr %p0, i64 %m1) {12; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs13; CHECK-SAME: (ptr [[P0:%.*]], i64 [[M1:%.*]]) {14; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[M1]], 22415; CHECK-NEXT: [[R:%.*]] = call noalias align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[TMP1]])16; CHECK-NEXT: ret ptr [[R]]17;18 %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224)19 %r = call noalias ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 %m1)20 ret ptr %r21}22 23define <2 x ptr> @ptrmask_combine_consecutive_preserve_attrs_vecs(<2 x ptr> %p0, <2 x i64> %m1) {24; CHECK-LABEL: define <2 x ptr> @ptrmask_combine_consecutive_preserve_attrs_vecs25; CHECK-SAME: (<2 x ptr> [[P0:%.*]], <2 x i64> [[M1:%.*]]) {26; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i64> [[M1]], splat (i64 12345)27; CHECK-NEXT: [[R:%.*]] = call align 128 <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[P0]], <2 x i64> [[TMP1]])28; CHECK-NEXT: ret <2 x ptr> [[R]]29;30 %pm0 = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p0, <2 x i64> <i64 12345, i64 12345>)31 %r = call align 128 <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %pm0, <2 x i64> %m1)32 ret <2 x ptr> %r33}34 35define ptr @ptrmask_combine_consecutive_preserve_attrs_fail(ptr %p0, i64 %m0) {36; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_fail37; CHECK-SAME: (ptr [[P0:%.*]], i64 [[M0:%.*]]) {38; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[M0]], 19339; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[TMP1]])40; CHECK-NEXT: ret ptr [[R]]41;42 %pm0 = call noalias ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)43 %r = call ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 193)44 ret ptr %r45}46 47define ptr @ptrmask_combine_consecutive_preserve_attrs_todo0(ptr %p0) {48; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo049; CHECK-SAME: (ptr [[P0:%.*]]) {50; CHECK-NEXT: [[PM0:%.*]] = call noalias align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224)51; CHECK-NEXT: ret ptr [[PM0]]52;53 %pm0 = call noalias ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224)54 %r = call ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 224)55 ret ptr %r56}57 58define ptr @ptrmask_combine_consecutive_preserve_attrs_todo1(ptr %p0) {59; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo160; CHECK-SAME: (ptr [[P0:%.*]]) {61; CHECK-NEXT: [[PM0:%.*]] = call align 32 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224)62; CHECK-NEXT: ret ptr [[PM0]]63;64 %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224)65 %r = call noalias ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 224)66 ret ptr %r67}68 69define ptr addrspace(1) @ptrmask_combine_consecutive_preserve_attrs_todo2(ptr addrspace(1) %p0) {70; CHECK-LABEL: define ptr addrspace(1) @ptrmask_combine_consecutive_preserve_attrs_todo271; CHECK-SAME: (ptr addrspace(1) [[P0:%.*]]) {72; CHECK-NEXT: [[PM0:%.*]] = call noalias align 32 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P0]], i32 224)73; CHECK-NEXT: ret ptr addrspace(1) [[PM0]]74;75 %pm0 = call noalias ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p0, i32 224)76 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %pm0, i32 224)77 ret ptr addrspace(1) %r78}79 80define ptr @ptrmask_combine_add_nonnull(ptr %p) {81; CHECK-LABEL: define ptr @ptrmask_combine_add_nonnull82; CHECK-SAME: (ptr [[P:%.*]]) {83; CHECK-NEXT: [[PM0:%.*]] = call align 4 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -60)84; CHECK-NEXT: [[PGEP1:%.*]] = getelementptr i8, ptr [[PM0]], i64 3285; CHECK-NEXT: [[R:%.*]] = call nonnull align 32 ptr @llvm.ptrmask.p0.i64(ptr [[PGEP1]], i64 -32)86; CHECK-NEXT: ret ptr [[R]]87;88 %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -60)89 %pgep = getelementptr i8, ptr %pm0, i64 3390 %r = call ptr @llvm.ptrmask.p0.i64(ptr %pgep, i64 -16)91 ret ptr %r92}93 94define ptr @ptrmask_combine_add_alignment(ptr %p) {95; CHECK-LABEL: define ptr @ptrmask_combine_add_alignment96; CHECK-SAME: (ptr [[P:%.*]]) {97; CHECK-NEXT: [[R:%.*]] = call align 64 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -64)98; CHECK-NEXT: ret ptr [[R]]99;100 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -64)101 ret ptr %r102}103 104define ptr addrspace(1) @ptrmask_combine_add_alignment2(ptr addrspace(1) align 32 %p) {105; CHECK-LABEL: define ptr addrspace(1) @ptrmask_combine_add_alignment2106; CHECK-SAME: (ptr addrspace(1) align 32 [[P:%.*]]) {107; CHECK-NEXT: [[R:%.*]] = call align 64 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 -64)108; CHECK-NEXT: ret ptr addrspace(1) [[R]]109;110 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 -64)111 ret ptr addrspace(1) %r112}113 114define <2 x ptr> @ptrmask_combine_add_alignment_vec(<2 x ptr> %p) {115; CHECK-LABEL: define <2 x ptr> @ptrmask_combine_add_alignment_vec116; CHECK-SAME: (<2 x ptr> [[P:%.*]]) {117; CHECK-NEXT: [[R:%.*]] = call align 32 <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[P]], <2 x i64> splat (i64 -96))118; CHECK-NEXT: ret <2 x ptr> [[R]]119;120 %r = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p, <2 x i64> <i64 -96, i64 -96>)121 ret <2 x ptr> %r122}123 124define ptr addrspace(1) @ptrmask_combine_improve_alignment(ptr addrspace(1) %p) {125; CHECK-LABEL: define ptr addrspace(1) @ptrmask_combine_improve_alignment126; CHECK-SAME: (ptr addrspace(1) [[P:%.*]]) {127; CHECK-NEXT: [[R:%.*]] = call align 64 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 -64)128; CHECK-NEXT: ret ptr addrspace(1) [[R]]129;130 %r = call align 32 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 -64)131 ret ptr addrspace(1) %r132}133 134define <2 x ptr addrspace(1) > @ptrmask_combine_improve_alignment_vec(<2 x ptr addrspace(1) > %p) {135; CHECK-LABEL: define <2 x ptr addrspace(1)> @ptrmask_combine_improve_alignment_vec136; CHECK-SAME: (<2 x ptr addrspace(1)> [[P:%.*]]) {137; CHECK-NEXT: [[R:%.*]] = call align 64 <2 x ptr addrspace(1)> @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1)> [[P]], <2 x i32> <i32 -64, i32 -128>)138; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[R]]139;140 %r = call align 32 <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) > %p, <2 x i32> <i32 -64, i32 -128>)141 ret <2 x ptr addrspace(1) > %r142}143 144define ptr addrspace(1) @ptrmask_combine_improve_alignment_fail(ptr addrspace(1) %p) {145; CHECK-LABEL: define ptr addrspace(1) @ptrmask_combine_improve_alignment_fail146; CHECK-SAME: (ptr addrspace(1) [[P:%.*]]) {147; CHECK-NEXT: [[R:%.*]] = call align 128 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 -64)148; CHECK-NEXT: ret ptr addrspace(1) [[R]]149;150 %r = call align 128 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 -64)151 ret ptr addrspace(1) %r152}153 154define i64 @ptrtoint_of_ptrmask(ptr %p, i64 %m) {155; CHECK-LABEL: define i64 @ptrtoint_of_ptrmask156; CHECK-SAME: (ptr [[P:%.*]], i64 [[M:%.*]]) {157; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P]] to i64158; CHECK-NEXT: [[R:%.*]] = and i64 [[M]], [[TMP1]]159; CHECK-NEXT: ret i64 [[R]]160;161 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)162 %r = ptrtoint ptr %pm to i64163 ret i64 %r164}165 166; This succeeds because (ptrtoint i32) gets folded to (trunc i32 (ptrtoint i64))167define i32 @ptrtoint_of_ptrmask2(ptr %p, i64 %m) {168; CHECK-LABEL: define i32 @ptrtoint_of_ptrmask2169; CHECK-SAME: (ptr [[P:%.*]], i64 [[M:%.*]]) {170; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P]] to i64171; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[M]], [[TMP1]]172; CHECK-NEXT: [[R:%.*]] = trunc i64 [[TMP2]] to i32173; CHECK-NEXT: ret i32 [[R]]174;175 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)176 %r = ptrtoint ptr %pm to i32177 ret i32 %r178}179 180define <2 x i64> @ptrtoint_of_ptrmask_vec(<2 x ptr> %p, <2 x i64> %m) {181; CHECK-LABEL: define <2 x i64> @ptrtoint_of_ptrmask_vec182; CHECK-SAME: (<2 x ptr> [[P:%.*]], <2 x i64> [[M:%.*]]) {183; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint <2 x ptr> [[P]] to <2 x i64>184; CHECK-NEXT: [[R:%.*]] = and <2 x i64> [[M]], [[TMP1]]185; CHECK-NEXT: ret <2 x i64> [[R]]186;187 %pm = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p, <2 x i64> %m)188 %r = ptrtoint <2 x ptr> %pm to <2 x i64>189 ret <2 x i64> %r190}191 192define <2 x i32> @ptrtoint_of_ptrmask_vec2(<2 x ptr> %p, <2 x i64> %m) {193; CHECK-LABEL: define <2 x i32> @ptrtoint_of_ptrmask_vec2194; CHECK-SAME: (<2 x ptr> [[P:%.*]], <2 x i64> [[M:%.*]]) {195; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint <2 x ptr> [[P]] to <2 x i64>196; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i64> [[M]], [[TMP1]]197; CHECK-NEXT: [[R:%.*]] = trunc <2 x i64> [[TMP2]] to <2 x i32>198; CHECK-NEXT: ret <2 x i32> [[R]]199;200 %pm = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p, <2 x i64> %m)201 %r = ptrtoint <2 x ptr> %pm to <2 x i32>202 ret <2 x i32> %r203}204 205define i64 @ptrtoint_of_ptrmask_fail(ptr addrspace(1) %p, i32 %m) {206; CHECK-LABEL: define i64 @ptrtoint_of_ptrmask_fail207; CHECK-SAME: (ptr addrspace(1) [[P:%.*]], i32 [[M:%.*]]) {208; CHECK-NEXT: [[PM:%.*]] = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 [[M]])209; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr addrspace(1) [[PM]] to i64210; CHECK-NEXT: ret i64 [[R]]211;212 %pm = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 %m)213 %r = ptrtoint ptr addrspace(1) %pm to i64214 ret i64 %r215}216 217define <2 x i32> @ptrtoint_of_ptrmask_vec_fail(<2 x ptr addrspace(1) > %p, <2 x i32> %m) {218; CHECK-LABEL: define <2 x i32> @ptrtoint_of_ptrmask_vec_fail219; CHECK-SAME: (<2 x ptr addrspace(1)> [[P:%.*]], <2 x i32> [[M:%.*]]) {220; CHECK-NEXT: [[PM:%.*]] = call <2 x ptr addrspace(1)> @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1)> [[P]], <2 x i32> [[M]])221; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint <2 x ptr addrspace(1)> [[PM]] to <2 x i64>222; CHECK-NEXT: [[R:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i32>223; CHECK-NEXT: ret <2 x i32> [[R]]224;225 %pm = call <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) > %p, <2 x i32> %m)226 %r = ptrtoint <2 x ptr addrspace(1) > %pm to <2 x i32>227 ret <2 x i32> %r228}229 230define ptr addrspace(1) @ptrmask_is_null(ptr addrspace(1) align 32 %p) {231; CHECK-LABEL: define ptr addrspace(1) @ptrmask_is_null232; CHECK-SAME: (ptr addrspace(1) align 32 [[P:%.*]]) {233; CHECK-NEXT: [[R:%.*]] = call align 4294967296 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 0)234; CHECK-NEXT: ret ptr addrspace(1) [[R]]235;236 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 31)237 ret ptr addrspace(1) %r238}239 240define <2 x ptr addrspace(1) > @ptrmask_is_null_vec(<2 x ptr addrspace(1) > align 64 %p) {241; CHECK-LABEL: define <2 x ptr addrspace(1)> @ptrmask_is_null_vec242; CHECK-SAME: (<2 x ptr addrspace(1)> align 64 [[P:%.*]]) {243; CHECK-NEXT: [[R:%.*]] = call <2 x ptr addrspace(1)> @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1)> [[P]], <2 x i32> <i32 31, i32 63>)244; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[R]]245;246 %r = call <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) > %p, <2 x i32> <i32 31, i32 63>)247 ret <2 x ptr addrspace(1) > %r248}249 250define ptr addrspace(1) @ptrmask_is_null_fail(ptr addrspace(1) align 16 %p) {251; CHECK-LABEL: define ptr addrspace(1) @ptrmask_is_null_fail252; CHECK-SAME: (ptr addrspace(1) align 16 [[P:%.*]]) {253; CHECK-NEXT: [[R:%.*]] = call align 16 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P]], i32 16)254; CHECK-NEXT: ret ptr addrspace(1) [[R]]255;256 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p, i32 31)257 ret ptr addrspace(1) %r258}259 260define <2 x ptr addrspace(1) > @ptrmask_is_null_vec_fail(<2 x ptr addrspace(1) > align 32 %p) {261; CHECK-LABEL: define <2 x ptr addrspace(1)> @ptrmask_is_null_vec_fail262; CHECK-SAME: (<2 x ptr addrspace(1)> align 32 [[P:%.*]]) {263; CHECK-NEXT: [[R:%.*]] = call <2 x ptr addrspace(1)> @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1)> [[P]], <2 x i32> <i32 31, i32 63>)264; CHECK-NEXT: ret <2 x ptr addrspace(1)> [[R]]265;266 %r = call <2 x ptr addrspace(1) > @llvm.ptrmask.v2p1.v2i32(<2 x ptr addrspace(1) > %p, <2 x i32> <i32 31, i32 63>)267 ret <2 x ptr addrspace(1) > %r268}269 270define ptr @ptrmask_maintain_provenance_i64(ptr %p0) {271; CHECK-LABEL: define ptr @ptrmask_maintain_provenance_i64272; CHECK-SAME: (ptr [[P0:%.*]]) {273; CHECK-NEXT: [[R:%.*]] = call align 4294967296 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 0)274; CHECK-NEXT: ret ptr [[R]]275;276 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 0)277 ret ptr %r278}279 280define ptr addrspace(1) @ptrmask_maintain_provenance_i32(ptr addrspace(1) %p0) {281; CHECK-LABEL: define ptr addrspace(1) @ptrmask_maintain_provenance_i32282; CHECK-SAME: (ptr addrspace(1) [[P0:%.*]]) {283; CHECK-NEXT: [[R:%.*]] = call align 4294967296 ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) [[P0]], i32 0)284; CHECK-NEXT: ret ptr addrspace(1) [[R]]285;286 %r = call ptr addrspace(1) @llvm.ptrmask.p1.i32(ptr addrspace(1) %p0, i32 0)287 ret ptr addrspace(1) %r288}289 290define ptr @ptrmask_is_nop0(ptr align 8 %p) {291; CHECK-LABEL: define ptr @ptrmask_is_nop0292; CHECK-SAME: (ptr align 8 [[P:%.*]]) {293; CHECK-NEXT: ret ptr [[P]]294;295 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -8)296 ret ptr %pm297}298 299define ptr @ptrmask_is_nop1(ptr align 8 %p) {300; CHECK-LABEL: define ptr @ptrmask_is_nop1301; CHECK-SAME: (ptr align 8 [[P:%.*]]) {302; CHECK-NEXT: ret ptr [[P]]303;304 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -4)305 ret ptr %pm306}307 308define ptr @ptrmask_to_modified_gep0(ptr align 8 %p) {309; CHECK-LABEL: define ptr @ptrmask_to_modified_gep0310; CHECK-SAME: (ptr align 8 [[P:%.*]]) {311; CHECK-NEXT: [[PM:%.*]] = call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -16)312; CHECK-NEXT: ret ptr [[PM]]313;314 %gep = getelementptr i8, ptr %p, i32 5315 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -16)316 ret ptr %pm317}318 319define ptr @ptrmask_to_modified_gep1(ptr align 8 %p) {320; CHECK-LABEL: define ptr @ptrmask_to_modified_gep1321; CHECK-SAME: (ptr align 8 [[P:%.*]]) {322; CHECK-NEXT: ret ptr [[P]]323;324 %gep = getelementptr i8, ptr %p, i32 6325 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -8)326 ret ptr %pm327}328 329define ptr @ptrmask_to_modified_gep2(ptr align 16 %p) {330; CHECK-LABEL: define ptr @ptrmask_to_modified_gep2331; CHECK-SAME: (ptr align 16 [[P:%.*]]) {332; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 12333; CHECK-NEXT: ret ptr [[GEP1]]334;335 %gep = getelementptr i8, ptr %p, i32 15336 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -4)337 ret ptr %pm338}339 340define ptr @ptrmask_to_modified_gep4(ptr align 8 %p) {341; CHECK-LABEL: define ptr @ptrmask_to_modified_gep4342; CHECK-SAME: (ptr align 8 [[P:%.*]]) {343; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 24344; CHECK-NEXT: [[PM:%.*]] = call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[GEP1]], i64 -16)345; CHECK-NEXT: ret ptr [[PM]]346;347 %gep = getelementptr i8, ptr %p, i32 29348 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -16)349 ret ptr %pm350}351 352define ptr @ptrmask_to_modified_gep5(ptr align 8 %p) {353; CHECK-LABEL: define ptr @ptrmask_to_modified_gep5354; CHECK-SAME: (ptr align 8 [[P:%.*]]) {355; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 24356; CHECK-NEXT: ret ptr [[GEP1]]357;358 %gep = getelementptr i8, ptr %p, i32 30359 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -8)360 ret ptr %pm361}362 363define ptr @ptrmask_to_modified_gep6(ptr align 16 %p) {364; CHECK-LABEL: define ptr @ptrmask_to_modified_gep6365; CHECK-SAME: (ptr align 16 [[P:%.*]]) {366; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 28367; CHECK-NEXT: ret ptr [[GEP1]]368;369 %gep = getelementptr i8, ptr %p, i32 31370 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -4)371 ret ptr %pm372}373 374define ptr @ptrmask_to_modified_gep_indirect0(ptr align 16 %p) {375; CHECK-LABEL: define ptr @ptrmask_to_modified_gep_indirect0376; CHECK-SAME: (ptr align 16 [[P:%.*]]) {377; CHECK-NEXT: [[GEP11:%.*]] = getelementptr i8, ptr [[P]], i64 44378; CHECK-NEXT: ret ptr [[GEP11]]379;380; 44 from 4*sizeof(i32) + (31 & -4)381 %gep0 = getelementptr i32, ptr %p, i32 4382 %gep1 = getelementptr i8, ptr %gep0, i32 31383 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep1, i64 -4)384 ret ptr %pm385}386 387define ptr @ptrmask_to_modified_gep_indirect1(ptr %p) {388; CHECK-LABEL: define ptr @ptrmask_to_modified_gep_indirect1389; CHECK-SAME: (ptr [[P:%.*]]) {390; CHECK-NEXT: [[PM0:%.*]] = call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -16)391; CHECK-NEXT: [[PGEP1:%.*]] = getelementptr i8, ptr [[PM0]], i64 32392; CHECK-NEXT: ret ptr [[PGEP1]]393;394 395 %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -16)396 %pgep = getelementptr i8, ptr %pm0, i64 33397 %r = call ptr @llvm.ptrmask.p0.i64(ptr %pgep, i64 -16)398 ret ptr %r399}400 401define ptr @ptrmask_to_modified_gep_zero_argument() {402; CHECK-LABEL: define ptr @ptrmask_to_modified_gep_zero_argument() {403; CHECK-NEXT: [[P:%.*]] = call nonnull align 4 ptr @llvm.ptrmask.p0.i64(ptr nonnull inttoptr (i64 31 to ptr), i64 28)404; CHECK-NEXT: ret ptr [[P]]405;406 %gep = getelementptr inbounds i8, ptr null, i32 31407 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -4)408 ret ptr %pm409}410 411define ptr @ptrmask_to_preserves_inbounds(ptr align 16 %p) {412; CHECK-LABEL: define ptr @ptrmask_to_preserves_inbounds413; CHECK-SAME: (ptr align 16 [[P:%.*]]) {414; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 28415; CHECK-NEXT: ret ptr [[GEP1]]416;417 %gep = getelementptr inbounds i8, ptr %p, i32 31418 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -4)419 ret ptr %pm420}421 422define ptr @ptrmask_of_gep_requires_i8(ptr align 8 %p) {423; CHECK-LABEL: define ptr @ptrmask_of_gep_requires_i8424; CHECK-SAME: (ptr align 8 [[P:%.*]]) {425; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[P]], i64 8426; CHECK-NEXT: [[PM:%.*]] = call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[GEP1]], i64 -16)427; CHECK-NEXT: ret ptr [[PM]]428;429 %gep = getelementptr i16, ptr %p, i32 5430 %pm = call ptr @llvm.ptrmask.p0.i64(ptr %gep, i64 -16)431 ret ptr %pm432}433 434define <2 x ptr> @ptrmask_of_gep_vector_type_unimplemented(<2 x ptr> align 8 %p) {435; CHECK-LABEL: define <2 x ptr> @ptrmask_of_gep_vector_type_unimplemented436; CHECK-SAME: (<2 x ptr> align 8 [[P:%.*]]) {437; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, <2 x ptr> [[P]], i64 17438; CHECK-NEXT: [[PM:%.*]] = call align 32 <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[GEP]], <2 x i64> splat (i64 -96))439; CHECK-NEXT: ret <2 x ptr> [[PM]]440;441 %gep = getelementptr i8, <2 x ptr> %p, i32 17442 %pm = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %gep, <2 x i64> <i64 -96, i64 -96>)443 ret <2 x ptr> %pm444}445 446define ptr @ptrmask_is_useless0(i64 %i, i64 %m) {447; CHECK-LABEL: define ptr @ptrmask_is_useless0448; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {449; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], -4450; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr451; CHECK-NEXT: [[R:%.*]] = call align 4 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M]])452; CHECK-NEXT: ret ptr [[R]]453;454 %m0 = and i64 %m, -4455 %i0 = and i64 %i, -4456 %p0 = inttoptr i64 %i0 to ptr457 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)458 ret ptr %r459}460 461define ptr @ptrmask_is_useless1(i64 %i, i64 %m) {462; CHECK-LABEL: define ptr @ptrmask_is_useless1463; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {464; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], -8465; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr466; CHECK-NEXT: [[R:%.*]] = call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M]])467; CHECK-NEXT: ret ptr [[R]]468;469 %m0 = and i64 %m, -4470 %i0 = and i64 %i, -8471 %p0 = inttoptr i64 %i0 to ptr472 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)473 ret ptr %r474}475 476define ptr @ptrmask_is_useless2(i64 %i, i64 %m) {477; CHECK-LABEL: define ptr @ptrmask_is_useless2478; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {479; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], 31480; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr481; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M]])482; CHECK-NEXT: ret ptr [[R]]483;484 %m0 = and i64 %m, 127485 %i0 = and i64 %i, 31486 %p0 = inttoptr i64 %i0 to ptr487 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)488 ret ptr %r489}490 491define ptr @ptrmask_is_useless3(i64 %i, i64 %m) {492; CHECK-LABEL: define ptr @ptrmask_is_useless3493; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {494; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], 127495; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr496; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M]])497; CHECK-NEXT: ret ptr [[R]]498;499 %m0 = and i64 %m, 127500 %i0 = and i64 %i, 127501 %p0 = inttoptr i64 %i0 to ptr502 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)503 ret ptr %r504}505 506define ptr @ptrmask_is_useless4(i64 %i, i64 %m) {507; CHECK-LABEL: define ptr @ptrmask_is_useless4508; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {509; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], -4510; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr511; CHECK-NEXT: ret ptr [[P0]]512;513 %m0 = or i64 %m, -4514 %i0 = and i64 %i, -4515 %p0 = inttoptr i64 %i0 to ptr516 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)517 ret ptr %r518}519 520define <2 x ptr> @ptrmask_is_useless_vec(<2 x i64> %i, <2 x i64> %m) {521; CHECK-LABEL: define <2 x ptr> @ptrmask_is_useless_vec522; CHECK-SAME: (<2 x i64> [[I:%.*]], <2 x i64> [[M:%.*]]) {523; CHECK-NEXT: [[I0:%.*]] = and <2 x i64> [[I]], splat (i64 31)524; CHECK-NEXT: [[P0:%.*]] = inttoptr <2 x i64> [[I0]] to <2 x ptr>525; CHECK-NEXT: [[R:%.*]] = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[P0]], <2 x i64> [[M]])526; CHECK-NEXT: ret <2 x ptr> [[R]]527;528 %m0 = and <2 x i64> %m, <i64 127, i64 127>529 %i0 = and <2 x i64> %i, <i64 31, i64 31>530 %p0 = inttoptr <2 x i64> %i0 to <2 x ptr>531 %r = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p0, <2 x i64> %m0)532 ret <2 x ptr> %r533}534 535define <2 x ptr> @ptrmask_is_useless_vec_todo(<2 x i64> %i, <2 x i64> %m) {536; CHECK-LABEL: define <2 x ptr> @ptrmask_is_useless_vec_todo537; CHECK-SAME: (<2 x i64> [[I:%.*]], <2 x i64> [[M:%.*]]) {538; CHECK-NEXT: [[I0:%.*]] = and <2 x i64> [[I]], <i64 31, i64 127>539; CHECK-NEXT: [[P0:%.*]] = inttoptr <2 x i64> [[I0]] to <2 x ptr>540; CHECK-NEXT: [[R:%.*]] = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> [[P0]], <2 x i64> [[M]])541; CHECK-NEXT: ret <2 x ptr> [[R]]542;543 %m0 = and <2 x i64> %m, <i64 127, i64 127>544 %i0 = and <2 x i64> %i, <i64 31, i64 127>545 %p0 = inttoptr <2 x i64> %i0 to <2 x ptr>546 %r = call <2 x ptr> @llvm.ptrmask.v2p0.v2i64(<2 x ptr> %p0, <2 x i64> %m0)547 ret <2 x ptr> %r548}549 550define ptr @ptrmask_is_useless_fail0(i64 %i, i64 %m) {551; CHECK-LABEL: define ptr @ptrmask_is_useless_fail0552; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {553; CHECK-NEXT: [[M0:%.*]] = and i64 [[M]], -4554; CHECK-NEXT: [[I0:%.*]] = or i64 [[I]], -4555; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr556; CHECK-NEXT: [[R:%.*]] = call align 4 ptr @llvm.ptrmask.p0.i64(ptr nonnull [[P0]], i64 [[M0]])557; CHECK-NEXT: ret ptr [[R]]558;559 %m0 = and i64 %m, -4560 %i0 = or i64 %i, -4561 %p0 = inttoptr i64 %i0 to ptr562 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)563 ret ptr %r564}565 566define ptr @ptrmask_is_useless_fail1(i64 %i, i64 %m) {567; CHECK-LABEL: define ptr @ptrmask_is_useless_fail1568; CHECK-SAME: (i64 [[I:%.*]], i64 [[M:%.*]]) {569; CHECK-NEXT: [[M0:%.*]] = and i64 [[M]], 127570; CHECK-NEXT: [[I0:%.*]] = and i64 [[I]], 511571; CHECK-NEXT: [[P0:%.*]] = inttoptr i64 [[I0]] to ptr572; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M0]])573; CHECK-NEXT: ret ptr [[R]]574;575 %m0 = and i64 %m, 127576 %i0 = and i64 %i, 511577 %p0 = inttoptr i64 %i0 to ptr578 %r = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0)579 ret ptr %r580}581 582@GC_arrays = external global { i8, i8, i64 }583 584define ptr @ptrmask_demandedbits_constantexpr() {585; CHECK-LABEL: define ptr @ptrmask_demandedbits_constantexpr() {586; CHECK-NEXT: entry:587; CHECK-NEXT: [[ALIGNED_RESULT:%.*]] = call align 8 ptr @llvm.ptrmask.p0.i64(ptr nonnull @GC_arrays, i64 -8)588; CHECK-NEXT: ret ptr [[ALIGNED_RESULT]]589;590entry:591 %aligned_result = call ptr @llvm.ptrmask.p0.i64(ptr getelementptr inbounds (i8, ptr @GC_arrays, i64 1), i64 -8)592 ret ptr %aligned_result593}594