Index: lib/Analysis/Loads.cpp =================================================================== --- lib/Analysis/Loads.cpp +++ lib/Analysis/Loads.cpp @@ -101,6 +101,11 @@ return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Align, Size, DL, CtxI, DT, Visited); + if (const IntrinsicInst *I = dyn_cast(V)) + if (I->getIntrinsicID() == Intrinsic::noalias) + return isDereferenceableAndAlignedPointer(I->getOperand(0), Align, Size, + DL, CtxI, DT, Visited); + // If we don't know, assume the worst. return false; } Index: test/Analysis/ValueTracking/memory-dereferenceable.ll =================================================================== --- test/Analysis/ValueTracking/memory-dereferenceable.ll +++ test/Analysis/ValueTracking/memory-dereferenceable.ll @@ -43,7 +43,8 @@ %load4 = load i32, i32 addrspace(1)* %relocate ; CHECK-NOT: %nparam - %nparam = getelementptr i32, i32 addrspace(1)* %dparam, i32 5 + %dpa = call i32 addrspace(1)* @llvm.noalias.p1i32(i32 addrspace(1)* %dparam, metadata !4) + %nparam = getelementptr i32, i32 addrspace(1)* %dpa, i32 5 %load5 = load i32, i32 addrspace(1)* %nparam ; Load from a non-dereferenceable load @@ -162,6 +163,12 @@ declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...) declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) +declare i32 addrspace(1)* @llvm.noalias.p1i32(i32 addrspace(1)*, metadata) nounwind argmemonly + !0 = !{i64 4} !1 = !{i64 2} !2 = !{} + +!3 = !{!3, !"some domain"} +!4 = !{!4, !3, !"some scope"} +