Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion llvm/lib/Analysis/DependenceAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,10 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
continue;
Value *Ptr = getLoadStorePointerOperand(&Inst);
const Loop *L = LI.getLoopFor(Inst.getParent());
const Loop *OutermostLoop = L ? L->getOutermostLoop() : nullptr;
const SCEV *PtrSCEV = SE.getSCEVAtScope(Ptr, L);
const SCEV *AccessFn = SE.removePointerBase(PtrSCEV);
SCEVMonotonicity Mon = Checker.checkMonotonicity(AccessFn, L);
SCEVMonotonicity Mon = Checker.checkMonotonicity(AccessFn, OutermostLoop);
OS.indent(2) << "Inst: " << Inst << "\n";
OS.indent(4) << "Expr: " << *AccessFn << "\n";
Mon.print(OS, 4);
Expand Down Expand Up @@ -945,6 +946,8 @@ SCEVMonotonicity SCEVMonotonicityChecker::invariantOrUnknown(const SCEV *Expr) {
SCEVMonotonicity
SCEVMonotonicityChecker::checkMonotonicity(const SCEV *Expr,
const Loop *OutermostLoop) {
assert((!OutermostLoop || OutermostLoop->isOutermost()) &&
"OutermostLoop must be outermost");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤣

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a silly assertion, but it was buggy because OutermostLoop was not outermost...

assert(Expr->getType()->isIntegerTy() && "Expr must be integer type");
this->OutermostLoop = OutermostLoop;
return visit(Expr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,8 @@ exit:
}

; The value of step reccurence is not invariant with respect to the outer most
; loop (the i-loop).
; loop (the i-loop). It is theoretically multivariate monotonic by definition,
; but we cannot handle non-affine addrec for now.
;
; offset_i = 0;
; for (int i = 0; i < 100; i++) {
Expand All @@ -312,7 +313,8 @@ define void @step_is_variant(ptr %a) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {%offset.i,+,1}<nuw><nsw><%loop.j>
; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
; CHECK-NEXT: Monotonicity: Unknown
; CHECK-NEXT: Reason: %offset.i
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - confused!
Expand Down Expand Up @@ -346,6 +348,56 @@ exit:
ret void
}

; The value of step reccurence is not invariant with respect to the outer most
; loop (the i-loop). Actually, `offset_i` is not monotonic.
;
; offset_i = 0;
; for (int i = 0; i < 100; i++) {
; for (int j = 0; j < 100; j++)
; a[offset_i + j] = 0;
; offset_i += (i % 2 == 0) ? -1 : 3;
; }
;
define void @step_is_variant2(ptr %a) {
; CHECK-LABEL: 'step_is_variant2'
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {%offset.i,+,1}<nsw><%loop.j>
; CHECK-NEXT: Monotonicity: Unknown
; CHECK-NEXT: Reason: %offset.i
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - confused!
;
entry:
br label %loop.i.header

loop.i.header:
%i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ]
%offset.i = phi i64 [ 0, %entry ], [ %offset.i.next, %loop.i.latch ]
%step.i.0 = phi i64 [ -1, %entry ], [ %step.i.1, %loop.i.latch ]
%step.i.1 = phi i64 [ 3, %entry ], [ %step.i.0, %loop.i.latch ]
br label %loop.j

loop.j:
%j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ]
%offset = add nsw i64 %offset.i, %j
%idx = getelementptr inbounds i8, ptr %a, i64 %offset
store i8 0, ptr %idx
%j.inc = add nsw i64 %j, 1
%exitcond.j = icmp eq i64 %j.inc, 100
br i1 %exitcond.j, label %loop.i.latch, label %loop.j

loop.i.latch:
%i.inc = add nsw i64 %i, 1
%offset.i.next = add nsw i64 %offset.i, %step.i.0
%exitcond.i = icmp eq i64 %i.inc, 100
br i1 %exitcond.i, label %exit, label %loop.i.header

exit:
ret void
}

; The AddRec doesn't have nsw flag for the j-loop, since the store may not be
; executed.
;
Expand Down