/// GetExpressionSCEV - Compute and return the SCEV for the specified
/// instruction.
SCEVHandle LoopStrengthReduce::GetExpressionSCEV(Instruction *Exp, Loop *L) {
+ // Pointer to pointer bitcast instructions return the same value as their
+ // operand.
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>(Exp)) {
+ if (SE->hasSCEV(BCI) || !isa<Instruction>(BCI->getOperand(0)))
+ return SE->getSCEV(BCI);
+ SCEVHandle R = GetExpressionSCEV(cast<Instruction>(BCI->getOperand(0)), L);
+ SE->setSCEV(BCI, R);
+ return R;
+ }
+
// Scalar Evolutions doesn't know how to compute SCEV's for GEP instructions.
// If this is a GEP that SE doesn't know about, compute it now and insert it.
// If this is not a GEP, or if we have already done this computation, just let
Imm = SC->getValue()->getSExtValue();
else
Imm = 0;
- if (!TLI->isLegalAddressScaleAndImm(Scale, Imm,
- UsersToProcess[i].Inst->getType()))
+
+ // If this is a load or other access, pass the type of the access in.
+ const Type *AccessTy = Type::VoidTy;
+ if (StoreInst *SI = dyn_cast<StoreInst>(UsersToProcess[i].Inst))
+ AccessTy = SI->getOperand(0)->getType();
+ else if (LoadInst *LI = dyn_cast<LoadInst>(UsersToProcess[i].Inst))
+ AccessTy = LI->getType();
+
+ if (!TLI->isLegalAddressScaleAndImm(Scale, Imm, AccessTy))
return false;
}
return true;
for (std::map<SCEVHandle, IVsOfOneStride>::iterator SI= IVsByStride.begin(),
SE = IVsByStride.end(); SI != SE; ++SI) {
int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
- if (unsigned(abs(SInt)) < SSInt || (SInt % SSInt) != 0)
+ if (SInt != -SSInt &&
+ (unsigned(abs(SInt)) < SSInt || (SInt % SSInt) != 0))
continue;
int64_t Scale = SInt / SSInt;
// Check that this stride is valid for all the types used for loads and
IncV = ReuseIV.IncV;
}
+ const Type *ReplacedTy = CommonExprs->getType();
+
// Now that we know what we need to do, insert the PHI node itself.
//
- DOUT << "INSERTING IV of STRIDE " << *Stride << " and BASE "
- << *CommonExprs << " :\n";
+ DOUT << "INSERTING IV of TYPE " << *ReplacedTy << " of STRIDE "
+ << *Stride << " and BASE " << *CommonExprs << " :\n";
SCEVExpander Rewriter(*SE, *LI);
SCEVExpander PreheaderRewriter(*SE, *LI);
BasicBlock *LatchBlock = L->getLoopLatch();
- const Type *ReplacedTy = CommonExprs->getType();
// Emit the initial base value into the loop preheader.
Value *CommonBaseV