Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -2947,11 +2947,20 @@ } if (IsMatched) { // Replace all matched values and erase them. + DenseMap DoneMatched; for (auto MV : Matched) { + auto AlreadyMatched = DoneMatched.find(MV.first); + if (AlreadyMatched != DoneMatched.end()) { + // We have phi node which matches to different + // but identiacal phis. So make a simplification then. + MV.first = MV.second; + MV.second = AlreadyMatched->second; + } MV.first->replaceAllUsesWith(MV.second); PhiNodesToMatch.erase(MV.first); ST.Put(MV.first, MV.second); MV.first->eraseFromParent(); + DoneMatched.insert({ MV.first, MV.second }); } Matched.clear(); continue; Index: test/Transforms/CodeGenPrepare/X86/sink-addrmode-two-phi.ll =================================================================== --- /dev/null +++ test/Transforms/CodeGenPrepare/X86/sink-addrmode-two-phi.ll @@ -0,0 +1,27 @@ +; RUN: opt -S -codegenprepare -disable-complex-addr-modes=false %s | FileCheck %s --check-prefix=CHECK +target datalayout = +"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + +define void @test() { +entry: + %0 = getelementptr inbounds i64, i64 * null, i64 undef + br label %start + +start: + %val1 = phi i64 * [ %0, %entry ], [ %val4, %exit ] + %val2 = phi i64 * [ null, %entry ], [ %val5, %exit ] + br i1 false, label %slowpath, label %exit + +slowpath: + %elem1 = getelementptr inbounds i64, i64 * undef, i64 undef + br label %exit + +exit: +; CHECK: sunkaddr + %val3 = phi i64 * [ undef, %slowpath ], [ %val2, %start ] + %val4 = phi i64 * [ %elem1, %slowpath ], [ %val1, %start ] + %val5 = phi i64 * [ undef, %slowpath ], [ %val2, %start ] + %loadx = load i64, i64 * %val4, align 8 + br label %start +}