diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 1ec5c4e9f6b542..0a3855f2192755 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -2696,7 +2696,9 @@ computePointerICmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS, // Fold comparisons for non-escaping pointer even if the allocation call // cannot be elided. We cannot fold malloc comparison to null. Also, the - // dynamic allocation call could be either of the operands. + // dynamic allocation call could be either of the operands. Note that + // the other operand can not be based on the alloc - if it were, then + // the cmp itself would be a capture. Value *MI = nullptr; if (isAllocLikeFn(LHS, TLI) && llvm::isKnownNonZero(RHS, DL, 0, nullptr, CxtI, DT)) diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll index a4560f84b6c7bd..7aad90759d49d5 100644 --- a/llvm/test/Transforms/InstSimplify/call.ll +++ b/llvm/test/Transforms/InstSimplify/call.ll @@ -1546,4 +1546,20 @@ define <3 x i33> @ctlz_ashr_sign_bit_vec(<3 x i33> %x) { ret <3 x i33> %r } +declare i8* @llvm.ptrmask.p0i8.i64(i8* , i64) + +define i1 @capture_vs_recurse(i64 %mask) { +; CHECK-LABEL: @capture_vs_recurse( +; CHECK-NEXT: [[A:%.*]] = call noalias i8* @malloc(i64 8) +; CHECK-NEXT: [[B:%.*]] = call nonnull i8* @llvm.ptrmask.p0i8.i64(i8* [[A]], i64 [[MASK:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[A]], [[B]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %a = call noalias i8* @malloc(i64 8) + %b = call nonnull i8* @llvm.ptrmask.p0i8.i64(i8* %a, i64 %mask) + %cmp = icmp eq i8* %a, %b + ret i1 %cmp +} + + attributes #0 = { nobuiltin readnone }