diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1929,6 +1929,21 @@ return &CI; break; } + case Intrinsic::ptrmask: { + Value *InnerPtr, *InnerMask; + if (match(II->getArgOperand(0), + m_OneUse(m_Intrinsic(m_Value(InnerPtr), + m_Value(InnerMask))))) { + if (II->getArgOperand(1)->getType() == InnerMask->getType()) { + Value *NewMask = Builder.CreateAnd(II->getArgOperand(1), InnerMask); + return replaceInstUsesWith( + *II, + Builder.CreateIntrinsic(InnerPtr->getType(), Intrinsic::ptrmask, + {InnerPtr, NewMask})); + } + } + break; + } case Intrinsic::uadd_with_overflow: case Intrinsic::sadd_with_overflow: { if (Instruction *I = foldIntrinsicWithOverflowCommon(II)) diff --git a/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll b/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll --- a/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll +++ b/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll @@ -7,8 +7,8 @@ define ptr @fold_2x(ptr %p, i64 %m0, i64 %m1) { ; CHECK-LABEL: define ptr @fold_2x ; CHECK-SAME: (ptr [[P:%.*]], i64 [[M0:%.*]], i64 [[M1:%.*]]) { -; CHECK-NEXT: [[P0:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 [[M0]]) -; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[M1]]) +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[M1]], [[M0]] +; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 [[TMP1]]) ; CHECK-NEXT: ret ptr [[P1]] ; %p0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m0) @@ -19,8 +19,8 @@ define ptr @fold_2x_i32(ptr %p, i32 %m0, i32 %m1) { ; CHECK-LABEL: define ptr @fold_2x_i32 ; CHECK-SAME: (ptr [[P:%.*]], i32 [[M0:%.*]], i32 [[M1:%.*]]) { -; CHECK-NEXT: [[P0:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 [[M0]]) -; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 [[M1]]) +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[M1]], [[M0]] +; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 [[TMP1]]) ; CHECK-NEXT: ret ptr [[P1]] ; %p0 = call ptr @llvm.ptrmask.p0.i32(ptr %p, i32 %m0)