Loop predication expand both sides of the widened condition
This is a fix for a loop predication bug which resulted in malformed IR generation.
Loop invariant side of the widened condition is not guaranteed to be available in the preheader as is, so we need to expand it as well. See added unsigned_loop_0_to_n_hoist_length test for example.
Reviewed By: sanjoy, mkazantsev
Differential Revision: https://reviews.llvm.org/D30099
llvm-svn: 296345
diff --git a/llvm/lib/Transforms/Scalar/LoopPredication.cpp b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
index fac2b8a..0ce6044 100644
--- a/llvm/lib/Transforms/Scalar/LoopPredication.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPredication.cpp
@@ -141,10 +141,9 @@
std::swap(LHSS, RHSS);
Pred = ICmpInst::getSwappedPredicate(Pred);
}
- if (!SE->isLoopInvariant(RHSS, L))
+ if (!SE->isLoopInvariant(RHSS, L) || !isSafeToExpand(RHSS, *SE))
return None;
- Value *Bound = RHS;
const SCEVAddRecExpr *IndexAR = dyn_cast<SCEVAddRecExpr>(LHSS);
if (!IndexAR || IndexAR->getLoop() != L)
return None;
@@ -176,9 +175,12 @@
DEBUG(dbgs() << "NewLHSS is loop invariant and safe to expand. Expand!\n");
- Value *NewLHS = Expander.expandCodeFor(NewLHSS, Bound->getType(),
- Preheader->getTerminator());
- return Builder.CreateICmp(Pred, NewLHS, Bound);
+ Type *Ty = LHS->getType();
+ Instruction *InsertAt = Preheader->getTerminator();
+ assert(Ty == RHS->getType() && "icmp operands have different types?");
+ Value *NewLHS = Expander.expandCodeFor(NewLHSS, Ty, InsertAt);
+ Value *NewRHS = Expander.expandCodeFor(RHSS, Ty, InsertAt);
+ return Builder.CreateICmp(Pred, NewLHS, NewRHS);
}
bool LoopPredication::widenGuardConditions(IntrinsicInst *Guard,