diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -861,12 +861,19 @@ for (auto *U : LI->getPointerOperand()->users()) if (U != LI && (isa(U) || isa(U)) && DT->dominates(cast(U), LI)) { - // FIXME: for now give up if there are multiple memory accesses that - // dominate the load. We need further analysis to decide which one is - // that we're forwarding from. - if (OtherAccess) - OtherAccess = nullptr; - else + // Use the most immediately dominating value + if (OtherAccess) { + if (DT->dominates(cast(OtherAccess), + cast(U))) { + OtherAccess = U; + } else if (!DT->dominates(cast(U), + cast(OtherAccess))) { + // No strict domination relationship implies partial redundancy + // and we don't know which one + OtherAccess = nullptr; + break; + } // else: the current access is more immediate to LI, so keep it + } else OtherAccess = U; }