diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1913,6 +1913,21 @@ if (Instruction *I = commonCastTransforms(CI)) return I; + // Convert: + // (inttoptr (and (ptrtoint Ptr), Mask)) + // -> llvm.ptrmask(Ptr, Mask) + // IFF + // Ptr is noundef + // Non-vec type (ptrmask of vec is weird). + Value *Ptr, *Mask; + if (!CI.getType()->isVectorTy() && + match(CI.getOperand(0), + m_OneUse(m_c_And(m_PtrToInt(m_Value(Ptr)), m_Value(Mask)))) && + isGuaranteedNotToBeUndefOrPoison(Ptr)) + return replaceInstUsesWith(CI, Builder.CreateIntrinsic(Ptr->getType(), + Intrinsic::ptrmask, + {Ptr, Mask})); + return nullptr; } diff --git a/llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll b/llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll --- a/llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll +++ b/llvm/test/Transforms/InstCombine/callsite_nonnull_args_through_casts.ll @@ -121,9 +121,7 @@ ; CHECK-LABEL: define void @maybenullAfterPtr2Int() { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 -; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64 -; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4294967292 -; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP1]] to ptr +; CHECK-NEXT: [[I2P:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr nonnull [[A]], i64 4294967292) ; CHECK-NEXT: call void @foo(ptr [[I2P]]) ; CHECK-NEXT: ret void ; diff --git a/llvm/test/Transforms/InstCombine/to-ptrmask.ll b/llvm/test/Transforms/InstCombine/to-ptrmask.ll --- a/llvm/test/Transforms/InstCombine/to-ptrmask.ll +++ b/llvm/test/Transforms/InstCombine/to-ptrmask.ll @@ -7,9 +7,7 @@ define ptr @intoptr_mask(ptr noundef %p, i64 %m) { ; CHECK-LABEL: define ptr @intoptr_mask ; CHECK-SAME: (ptr noundef [[P:%.*]], i64 [[M:%.*]]) { -; CHECK-NEXT: [[PI:%.*]] = ptrtoint ptr [[P]] to i64 -; CHECK-NEXT: [[PI_MASKED:%.*]] = and i64 [[PI]], [[M]] -; CHECK-NEXT: [[PM:%.*]] = inttoptr i64 [[PI_MASKED]] to ptr +; CHECK-NEXT: [[PM:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 [[M]]) ; CHECK-NEXT: ret ptr [[PM]] ; %pi = ptrtoint ptr %p to i64