commit 24b1a5b926832f68fa0a008b2484d4b44f58ee8e Author: dim Date: Sat Sep 14 10:55:33 2019 +0000 Revert commit from upstream llvm trunk (by Hans Wennborg): Re-commit r357452 (take 3): "SimplifyCFG SinkCommonCodeFromPredecessors: Also sink function calls without used results (PR41259)" Third time's the charm. This was reverted in r363220 due to being suspected of an internal benchmark regression and a test failure, none of which turned out to be caused by this. As reported in https://bugs.llvm.org/show_bug.cgi?id=43269, this causes UNREACHABLE errors when compiling if_malo_pci.c for arm and aarch64. Notes: svn path=/projects/clang900-import/; revision=352318 diff --git lib/Transforms/Utils/SimplifyCFG.cpp lib/Transforms/Utils/SimplifyCFG.cpp index 11651d040dc0..6e2ef67408d9 100644 --- lib/Transforms/Utils/SimplifyCFG.cpp +++ lib/Transforms/Utils/SimplifyCFG.cpp @@ -1428,10 +1428,9 @@ static bool HoistThenElseCodeToIf(BranchInst *BI, static bool canSinkInstructions( ArrayRef Insts, DenseMap> &PHIOperands) { - // Prune out obviously bad instructions to move. Each instruction must have - // exactly zero or one use, and we check later that use is by a single, common - // PHI instruction in the successor. - bool HasUse = !Insts.front()->user_empty(); + // Prune out obviously bad instructions to move. Any non-store instruction + // must have exactly one use, and we check later that use is by a single, + // common PHI instruction in the successor. for (auto *I : Insts) { // These instructions may change or break semantics if moved. if (isa(I) || I->isEHPad() || isa(I) || @@ -1445,10 +1444,9 @@ static bool canSinkInstructions( if (C->isInlineAsm()) return false; - // Each instruction must have zero or one use. - if (HasUse && !I->hasOneUse()) - return false; - if (!HasUse && !I->user_empty()) + // Everything must have only one use too, apart from stores which + // have no uses. + if (!isa(I) && !I->hasOneUse()) return false; } @@ -1457,11 +1455,11 @@ static bool canSinkInstructions( if (!I->isSameOperationAs(I0)) return false; - // All instructions in Insts are known to be the same opcode. If they have a - // use, check that the only user is a PHI or in the same block as the - // instruction, because if a user is in the same block as an instruction we're - // contemplating sinking, it must already be determined to be sinkable. - if (HasUse) { + // All instructions in Insts are known to be the same opcode. If they aren't + // stores, check the only user of each is a PHI or in the same block as the + // instruction, because if a user is in the same block as an instruction + // we're contemplating sinking, it must already be determined to be sinkable. + if (!isa(I0)) { auto *PNUse = dyn_cast(*I0->user_begin()); auto *Succ = I0->getParent()->getTerminator()->getSuccessor(0); if (!all_of(Insts, [&PNUse,&Succ](const Instruction *I) -> bool { @@ -1539,7 +1537,7 @@ static bool sinkLastInstruction(ArrayRef Blocks) { // it is slightly over-aggressive - it gets confused by commutative instructions // so double-check it here. Instruction *I0 = Insts.front(); - if (!I0->user_empty()) { + if (!isa(I0)) { auto *PNUse = dyn_cast(*I0->user_begin()); if (!all_of(Insts, [&PNUse](const Instruction *I) -> bool { auto *U = cast(*I->user_begin()); @@ -1597,10 +1595,11 @@ static bool sinkLastInstruction(ArrayRef Blocks) { I0->andIRFlags(I); } - if (!I0->user_empty()) { + if (!isa(I0)) { // canSinkLastInstruction checked that all instructions were used by // one and only one PHI node. Find that now, RAUW it to our common // instruction and nuke it. + assert(I0->hasOneUse()); auto *PN = cast(*I0->user_begin()); PN->replaceAllUsesWith(I0); PN->eraseFromParent();