Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -625,6 +625,12 @@ break; V = GA->getAliasee(); } else { + if (IntrinsicInst *I = dyn_cast(V)) + if (I->getIntrinsicID() == Intrinsic::noalias) { + V = I->getOperand(0); + continue; + } + break; } assert(V->getType()->getScalarType()->isPointerTy() && @@ -1949,8 +1955,8 @@ CmpInst::Predicate Pred, Value *LHS, Value *RHS) { // First, skip past any trivial no-ops. - LHS = LHS->stripPointerCasts(); - RHS = RHS->stripPointerCasts(); + LHS = LHS->stripPointerCasts(/*LookThroughNoAlias*/true); + RHS = RHS->stripPointerCasts(/*LookThroughNoAlias*/true); // A non-null pointer is not equal to a null pointer. if (llvm::isKnownNonNull(LHS, TLI) && isa(RHS) && Index: test/Transforms/InstSimplify/noalias.ll =================================================================== --- test/Transforms/InstSimplify/noalias.ll +++ test/Transforms/InstSimplify/noalias.ll @@ -18,7 +18,33 @@ ; CHECK: ret i8* undef } +define i1 @bitcast() { +; CHECK-LABEL: @bitcast( + %a = alloca i32 + %b = alloca i64 + %x = bitcast i32* %a to i8* + %z = bitcast i64* %b to i8* + %y = call i8* @llvm.noalias.p0i8(i8* %z, metadata !1) + %cmp = icmp eq i8* %x, %y + ret i1 %cmp +; CHECK-NEXT: ret i1 false +} + +%gept = type { i32, i32 } + +define i1 @gep3() { +; CHECK-LABEL: @gep3( + %x = alloca %gept, align 8 + %a = getelementptr %gept, %gept* %x, i64 0, i32 0 + %y = call %gept* @llvm.noalias.p0gept(%gept* %x, metadata !1) + %b = getelementptr %gept, %gept* %y, i64 0, i32 1 + %equal = icmp eq i32* %a, %b + ret i1 %equal +; CHECK-NEXT: ret i1 false +} + declare i8* @llvm.noalias.p0i8(i8*, metadata) nounwind +declare %gept* @llvm.noalias.p0gept(%gept*, metadata) nounwind !0 = !{!0, !"some domain"} !1 = !{!1, !0, !"some scope"}