diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3697,7 +3697,8 @@ bool llvm::isIntrinsicReturningPointerAliasingArgumentWithoutCapturing( const CallBase *Call) { return Call->getIntrinsicID() == Intrinsic::launder_invariant_group || - Call->getIntrinsicID() == Intrinsic::strip_invariant_group; + Call->getIntrinsicID() == Intrinsic::strip_invariant_group || + Call->getIntrinsicID() == Intrinsic::ptrmask; } /// \p PN defines a loop-variant pointer to an object. Check if the diff --git a/llvm/test/Analysis/BasicAA/ptrmask.ll b/llvm/test/Analysis/BasicAA/ptrmask.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/BasicAA/ptrmask.ll @@ -0,0 +1,25 @@ +; RUN: opt -basicaa -aa-eval -print-no-aliases -disable-output %s 2>&1 | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128-p0:48:64:128-p1:56:64:64" + +%struct = type <{ [20 x i64] }> + +; CHECK-LABEL: Function: test1: 5 pointers, 2 call sites +; CHECK-NEXT: NoAlias: %struct** %loc, i64* %offset.addr +; CHECK-NEXT: NoAlias: %struct* %addr, %struct** %loc +; CHECK-NEXT: NoAlias: %struct* %addr.ptr, %struct** %loc +; CHECK-NEXT: NoAlias: %struct** %loc, i64* %gep +define void @test1(i64* %offset.addr) { +entry: + %loc = alloca %struct*, align 8 + call void @init(i64 0, %struct** %loc) + %addr = load %struct*, %struct** %loc, align 8 + %addr.ptr = call %struct* @llvm.ptrmask.p0s_struct.p0s.struct.i64(%struct* %addr, i64 72057594037927928) + %offset = load i64, i64* %offset.addr, align 8 + %gep = getelementptr inbounds %struct, %struct* %addr.ptr, i64 0, i32 0, i64 %offset + store i64 1, i64* %gep, align 8 + ret void +} + +declare %struct* @llvm.ptrmask.p0s_struct.p0s.struct.i64(%struct*, i64) +declare void @init(i64, %struct**)