[SCEVValidator] Don't reorder multiplies in extractConstantFactor.

The existing code would add the operands in the wrong order, and eventually
crash because the SCEV expression doesn't exactly match the parameter SCEV
expression in SCEVAffinator::visit. (SCEV doesn't sort the operands to
getMulExpr in general.)

Differential Revision: https://reviews.llvm.org/D23592

llvm-svn: 279087
This commit is contained in:
Eli Friedman 2016-08-18 16:30:42 +00:00
parent 5195d3fc0e
commit 28671c83d6
2 changed files with 43 additions and 5 deletions

View File

@ -577,12 +577,10 @@ ParameterSetTy getParamsInAffineExpr(const Region *R, Loop *Scope,
std::pair<const SCEVConstant *, const SCEV *>
extractConstantFactor(const SCEV *S, ScalarEvolution &SE) {
auto *LeftOver = SE.getConstant(S->getType(), 1);
auto *ConstPart = cast<SCEVConstant>(SE.getConstant(S->getType(), 1));
if (auto *Constant = dyn_cast<SCEVConstant>(S))
return std::make_pair(Constant, LeftOver);
return std::make_pair(Constant, SE.getConstant(S->getType(), 1));
auto *AddRec = dyn_cast<SCEVAddRecExpr>(S);
if (AddRec) {
@ -627,12 +625,13 @@ extractConstantFactor(const SCEV *S, ScalarEvolution &SE) {
if (!Mul)
return std::make_pair(ConstPart, S);
SmallVector<const SCEV *, 4> LeftOvers;
for (auto *Op : Mul->operands())
if (isa<SCEVConstant>(Op))
ConstPart = cast<SCEVConstant>(SE.getMulExpr(ConstPart, Op));
else
LeftOver = SE.getMulExpr(LeftOver, Op);
LeftOvers.push_back(Op);
return std::make_pair(ConstPart, LeftOver);
return std::make_pair(ConstPart, SE.getMulExpr(LeftOvers));
}
} // namespace polly

View File

@ -0,0 +1,39 @@
; RUN: opt -polly-process-unprofitable -polly-scops %s -analyze | FileCheck %s
target datalayout = "e-m:e-i64:64-i128:128-n8:16:32:64-S128"
target triple = "aarch64--linux-android"
; Check for SCOP:
; CHECK: Stmt_for_body8_us_us95_i
; CHECK-NEXT: Domain :=
; CHECK-NEXT: [p_0] -> { Stmt_for_body8_us_us95_i[i0] : 0 <= i0 <= 4 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: [p_0] -> { Stmt_for_body8_us_us95_i[i0] -> [i0] };
; CHECK-NEXT; MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT; [p_0] -> { Stmt_for_body8_us_us95_i[i0] -> MemRef_0[1 + p_0] };
; CHECK-NEXT }
define void @test1() unnamed_addr align 2 {
entry:
%xFactor.0.reload = load i32, i32* undef
%0 = load i8*, i8** undef, align 8
%div = udiv i32 0, %xFactor.0.reload
%1 = load i32, i32* undef, align 4
%mul = mul i32 %1, %xFactor.0.reload
%col.023.us.us85.i = add i32 %div, -1
%mul11.us.us93.i = mul i32 %col.023.us.us85.i, %mul
br label %for.body8.us.us95.i
for.body8.us.us95.i:
%niter.i = phi i32 [ %niter.i.next, %for.body8.us.us95.i ], [ 0, %entry ]
%add12.us.us100.1.i = add i32 1, %mul11.us.us93.i
%idxprom13.us.us101.1.i = zext i32 %add12.us.us100.1.i to i64
%arrayidx14.us.us102.1.i = getelementptr inbounds i8, i8* %0, i64 %idxprom13.us.us101.1.i
store i8 0, i8* %arrayidx14.us.us102.1.i, align 1
%niter.ncmp.3.i = icmp eq i32 %niter.i, 4
%niter.i.next = add i32 %niter.i, 1
br i1 %niter.ncmp.3.i, label %for.body8.us.us95.epil.i.preheader, label %for.body8.us.us95.i
for.body8.us.us95.epil.i.preheader:
ret void
}