summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2017-12-12 20:28:46 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2017-12-12 20:28:46 +0000
commit83c15b136337ea3f23917e4294d12a695ff7c788 (patch)
treecdb03e2d6a15b13cc9cd8e240f5fb4cbd968534d /llvm/lib/Transforms
parent212bcf8370d43dcbaa4a787cca84259ec140546e (diff)
downloadbcm5719-llvm-83c15b136337ea3f23917e4294d12a695ff7c788.tar.gz
bcm5719-llvm-83c15b136337ea3f23917e4294d12a695ff7c788.zip
[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: 320525
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp24
1 files changed, 20 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index 01fc1528681..713d540079f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -1339,10 +1339,10 @@ static bool equivalentAddressValues(Value *A, Value *B) {
/// Converts store (bitcast (load (bitcast (select ...)))) to
/// store (load (select ...)), where select is minmax:
/// select ((cmp load V1, load V2), V1, V2).
-bool removeBitcastsFromLoadStoreOnMinMax(InstCombiner &IC, StoreInst &SI) {
+static 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 +1354,25 @@ bool removeBitcastsFromLoadStoreOnMinMax(InstCombiner &IC, StoreInst &SI) {
if (!isMinMaxWithLoads(LoadAddr))
return false;
+ if (!all_of(LI->users(), [LI, LoadAddr](User *U) {
+ auto *SI = dyn_cast<StoreInst>(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 *USI = cast<StoreInst>(UI);
+ IC.Builder.SetInsertPoint(USI);
+ combineStoreToNewValue(IC, *USI, NewLI);
+ }
+ IC.replaceInstUsesWith(*LI, UndefValue::get(LI->getType()));
+ IC.eraseInstFromFunction(*LI);
return true;
}
OpenPOWER on IntegriCloud