From fb68c48a8201a5d6066994699e098b267d4e418c Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 12 Dec 2017 15:54:49 +0000 Subject: [InstCombine] Fix PR35618: Instcombine hangs on single minmax load bitcast. Summary: If we have pattern `store (load(bitcast(select (cmp(V1, V2), &V1, &V2)))), bitcast)`, but the load is used in other instructions, it leads to looping in InstCombiner. Patch adds additional check that all users of the load instructions are stores and then replaces all uses of load instruction by the new one with new type. Reviewers: RKSimon, spatel, majnemer Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D41072 llvm-svn: 320488 --- .../InstCombine/InstCombineLoadStoreAlloca.cpp | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'llvm/lib') diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 01fc1528681..27adcade8f1 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -1341,8 +1341,7 @@ static bool equivalentAddressValues(Value *A, Value *B) { /// select ((cmp load V1, load V2), V1, V2). bool removeBitcastsFromLoadStoreOnMinMax(InstCombiner &IC, StoreInst &SI) { // bitcast? - Value *StoreAddr; - if (!match(SI.getPointerOperand(), m_BitCast(m_Value(StoreAddr)))) + if (!match(SI.getPointerOperand(), m_BitCast(m_Value()))) return false; // load? integer? Value *LoadAddr; @@ -1354,9 +1353,26 @@ bool removeBitcastsFromLoadStoreOnMinMax(InstCombiner &IC, StoreInst &SI) { if (!isMinMaxWithLoads(LoadAddr)) return false; + if (!all_of(LI->users(), [LI, LoadAddr](User *U) { + auto *SI = dyn_cast(U); + return SI && SI->getPointerOperand() != LI && + peekThroughBitcast(SI->getPointerOperand()) != LoadAddr && + !SI->getPointerOperand()->isSwiftError(); + })) + return false; + + IC.Builder.SetInsertPoint(LI); LoadInst *NewLI = combineLoadToNewType( IC, *LI, LoadAddr->getType()->getPointerElementType()); - combineStoreToNewValue(IC, SI, NewLI); + // Replace all the stores with stores of the newly loaded value. + for (auto *UI : LI->users()) { + auto *SI = cast(UI); + IC.Builder.SetInsertPoint(SI); + combineStoreToNewValue(IC, *SI, NewLI); + IC.eraseInstFromFunction(*SI); + } + IC.replaceInstUsesWith(*LI, UndefValue::get(LI->getType())); + IC.eraseInstFromFunction(*LI); return true; } @@ -1385,7 +1401,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { return eraseInstFromFunction(SI); if (removeBitcastsFromLoadStoreOnMinMax(*this, SI)) - return eraseInstFromFunction(SI); + return nullptr; // Replace GEP indices if possible. if (Instruction *NewGEPI = replaceGEPIdxWithZero(*this, Ptr, SI)) { -- cgit v1.2.3