1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 11:42:57 +01:00

LoopVectorize: Only strip casts from integer types when replacing symbolic

strides

Fixes PR18480.

llvm-svn: 199291
This commit is contained in:
Arnold Schwaighofer 2014-01-15 03:35:46 +00:00
parent 136412ee8a
commit 9fb94754bd
2 changed files with 42 additions and 4 deletions

View File

@ -1072,8 +1072,9 @@ struct LoopVectorize : public LoopPass {
// LoopVectorizationCostModel.
//===----------------------------------------------------------------------===//
static Value *stripCast(Value *V) {
static Value *stripIntegerCast(Value *V) {
if (CastInst *CI = dyn_cast<CastInst>(V))
if (CI->getOperand(0)->getType()->isIntegerTy())
return CI->getOperand(0);
return V;
}
@ -1095,7 +1096,7 @@ static const SCEV *replaceSymbolicStrideSCEV(ScalarEvolution *SE,
Value *StrideVal = SI->second;
// Strip casts.
StrideVal = stripCast(StrideVal);
StrideVal = stripIntegerCast(StrideVal);
// Replace symbolic stride by one.
Value *One = ConstantInt::get(StrideVal->getType(), 1);
@ -1551,7 +1552,7 @@ InnerLoopVectorizer::addStrideCheck(Instruction *Loc) {
for (SmallPtrSet<Value *, 8>::iterator SI = Legal->strides_begin(),
SE = Legal->strides_end();
SI != SE; ++SI) {
Value *Ptr = stripCast(*SI);
Value *Ptr = stripIntegerCast(*SI);
Value *C = ChkBuilder.CreateICmpNE(Ptr, ConstantInt::get(Ptr->getType(), 1),
"stride.chk");
// Store the first instruction we create.

View File

@ -48,3 +48,40 @@ for.end.loopexit:
for.end:
ret void
}
; We used to crash on this function because we removed the fptosi cast when
; replacing the symbolic stride '%conv'.
; PR18480
; CHECK-LABEL: fn1
; CHECK: load <2 x double>
define void @fn1(double* noalias %x, double* noalias %c, double %a) {
entry:
%conv = fptosi double %a to i32
%cmp8 = icmp sgt i32 %conv, 0
br i1 %cmp8, label %for.body.preheader, label %for.end
for.body.preheader:
br label %for.body
for.body:
%indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ]
%0 = trunc i64 %indvars.iv to i32
%mul = mul nsw i32 %0, %conv
%idxprom = sext i32 %mul to i64
%arrayidx = getelementptr inbounds double* %x, i64 %idxprom
%1 = load double* %arrayidx, align 8
%arrayidx3 = getelementptr inbounds double* %c, i64 %indvars.iv
store double %1, double* %arrayidx3, align 8
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%lftr.wideiv = trunc i64 %indvars.iv.next to i32
%exitcond = icmp eq i32 %lftr.wideiv, %conv
br i1 %exitcond, label %for.end.loopexit, label %for.body
for.end.loopexit:
br label %for.end
for.end:
ret void
}