diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -481,7 +481,7 @@ // because it should be in sync with CaptureTracking. Not using it may // cause weird miscompilations where 2 aliasing pointers are assumed to // noalias. - if (auto *RP = getArgumentAliasingToReturnedPointer(Call, true)) { + if (auto *RP = getArgumentAliasingToReturnedPointer(Call, false)) { V = RP; continue; } 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 @@ -3700,7 +3700,9 @@ bool llvm::isIntrinsicReturningPointerAliasingArgumentWithoutCapturing( const CallBase *Call, bool MustPreserveNullness) { return Call->getIntrinsicID() == Intrinsic::launder_invariant_group || - Call->getIntrinsicID() == Intrinsic::strip_invariant_group; + Call->getIntrinsicID() == Intrinsic::strip_invariant_group || + (!MustPreserveNullness && + Call->getIntrinsicID() == Intrinsic::ptrmask); } /// \p PN defines a loop-variant pointer to an object. Check if the @@ -3758,7 +3760,7 @@ // because it should be in sync with CaptureTracking. Not using it may // cause weird miscompilations where 2 aliasing pointers are assumed to // noalias. - if (auto *RP = getArgumentAliasingToReturnedPointer(Call, true)) { + if (auto *RP = getArgumentAliasingToReturnedPointer(Call, false)) { V = RP; continue; } 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,29 @@ +; RUN: opt -basicaa -aa-eval -print-no-aliases -disable-output %s 2>&1 | FileCheck %s + +%struct = type <{ [20 x i64] }> + +; CHECK-LABEL: Function: test_noalias: 4 pointers, 1 call sites +; CHECK-NEXT: NoAlias: %struct* %ptr1, i64* %ptr2 +; CHECK-NEXT: NoAlias: %struct* %addr.ptr, i64* %ptr2 +; CHECK-NEXT: NoAlias: i64* %gep, i64* %ptr2 +define void @test_noalias(%struct* noalias %ptr1, i64* %ptr2, i64 %offset) { +entry: + %addr.ptr = call %struct* @llvm.ptrmask.p0s_struct.p0s.struct.i64(%struct* %ptr1, i64 72057594037927928) + store i64 10, i64* %ptr2 + %gep = getelementptr inbounds %struct, %struct* %addr.ptr, i64 0, i32 0, i64 %offset + store i64 1, i64* %gep, align 8 + ret void +} + +; CHECK-NEXT: Function: test_alias: 4 pointers, 1 call sites +; CHECK-NOT: NoAlias +define void @test_alias(%struct* %ptr1, i64* %ptr2, i64 %offset) { +entry: + %addr.ptr = call %struct* @llvm.ptrmask.p0s_struct.p0s.struct.i64(%struct* %ptr1, i64 72057594037927928) + store i64 10, i64* %ptr2 + %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)