Index: llvm/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/lib/Transforms/Utils/Local.cpp +++ llvm/lib/Transforms/Utils/Local.cpp @@ -2694,8 +2694,19 @@ DominatorTree &DT, const BasicBlock *BB) { auto ProperlyDominates = [&DT](const BasicBlock *BB, const Use &U) { - auto *I = cast(U.getUser())->getParent(); - return DT.properlyDominates(BB, I); + Instruction *UserInst = cast(U.getUser()); + PHINode *PN = dyn_cast(UserInst); + // A phi use using a value from a block is dominated by the end of that + // block. Note that the phi's parent block may not be. + if (PN && PN->getIncomingBlock(U) == BB) + return true; + + const BasicBlock *UseBB; + if (PN) + UseBB = PN->getIncomingBlock(U); + else + UseBB = UserInst->getParent(); + return DT.properlyDominates(BB, UseBB); }; return ::replaceDominatedUsesWith(From, To, BB, ProperlyDominates); } Index: llvm/test/Transforms/GVN/phi.ll =================================================================== --- llvm/test/Transforms/GVN/phi.ll +++ llvm/test/Transforms/GVN/phi.ll @@ -39,7 +39,7 @@ ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: -; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ [[A]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] +; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ 0, [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] ; CHECK-NEXT: [[PHI2:%.*]] = phi i64 [ 0, [[TAKEN]] ], [ [[B]], [[UNTAKEN]] ] ; CHECK-NEXT: [[RET:%.*]] = sub i64 [[PHI1]], [[PHI2]] ; CHECK-NEXT: ret i64 [[RET]] @@ -142,8 +142,7 @@ ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: -; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[A]], [[TAKEN]] ], [ 0, [[UNTAKEN]] ] -; CHECK-NEXT: ret i64 [[PHI]] +; CHECK-NEXT: ret i64 0 ; br i1 %c, label %taken, label %untaken taken: @@ -167,8 +166,7 @@ ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: -; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[A]], [[TAKEN]] ], [ 0, [[UNTAKEN]] ] -; CHECK-NEXT: ret i64 [[PHI]] +; CHECK-NEXT: ret i64 0 ; br i1 %c, label %taken, label %untaken taken: