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 @@ -1912,6 +1912,22 @@ return &CI; break; } + case Intrinsic::ptrmask: { + if (match(II->getArgOperand(0), m_OneUse(m_Intrinsic( + m_Value(), m_Value())))) { + auto *InnerII = cast(II->getArgOperand(0)); + if (II->getArgOperand(1)->getType() == + InnerII->getArgOperand(1)->getType()) { + Value *NewMask = + Builder.CreateAnd(II->getArgOperand(1), InnerII->getArgOperand(1)); + return replaceInstUsesWith( + *II, Builder.CreateIntrinsic(InnerII->getArgOperand(0)->getType(), + Intrinsic::ptrmask, + {InnerII->getArgOperand(0), 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(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)