blob: 8af54c42e1d48cfb5ae66ade1090b35f88ce7be2 [file] [edit]
; REQUIRES: asserts
; RUN: opt < %s -passes=loop-interchange -loop-interchange-profitabilities=ignore -debug-only=loop-interchange -disable-output -S 2>%t
; RUN: FileCheck --input-file=%t %s
; This test documents a currently missed optimization opportunity.
;
; collectPerfectNests() walks up from each innermost loop and stops as soon as
; it reaches a loop with more than one subloop. But because [loop.i, loop.j] is never put in
; any LoopList, the pass never analyses or attempts that interchange — the
; opportunity is silently missed.
;
; Corresponding C code:
;
; for (int i = 0; i < 8; ++i)
; for (int j = 0; j < 8; ++j) {
; A[i][j] = 0; // missed: i/j interchange
; for (int k = 0; k < 8; ++k) {
; for (int l = 0; l < 8; ++l)
; for (int m = 0; m < 8; ++m)
; Left[m][l] = 0; // interchanged: l/m swapped
; for (int n = 0; n < 8; ++n)
; for (int o = 0; o < 8; ++o)
; Right[o][n] = 0; // interchanged: n/o swapped
; }
; }
;
;
; CHECK: Processing LoopList of size = 2 containing the following loops:
; CHECK-NEXT: - Loop at depth 4 containing: %loop.l.header<header>,%loop.m.header,%loop.m.latch,%loop.l.latch<latch><exiting>
; CHECK-NEXT: Loop at depth 5 containing: %loop.m.header<header>,%loop.m.latch<latch><exiting>
; CHECK-NEXT: - Loop at depth 5 containing: %loop.m.header<header>,%loop.m.latch<latch><exiting>
; CHECK: Loops interchanged: outer loop 'loop.l.header' and inner loop 'loop.m.header'
;
; CHECK: Processing LoopList of size = 2 containing the following loops:
; CHECK-NEXT: - Loop at depth 4 containing: %loop.n.header<header>,%loop.o.header,%loop.o.latch,%loop.n.latch<latch><exiting>
; CHECK-NEXT: Loop at depth 5 containing: %loop.o.header<header>,%loop.o.latch<latch><exiting>
; CHECK-NEXT: - Loop at depth 5 containing: %loop.o.header<header>,%loop.o.latch<latch><exiting>
; CHECK: Loops interchanged: outer loop 'loop.n.header' and inner loop 'loop.o.header'
;
;
; CHECK-NOT: loop.i.header
; CHECK-NOT: loop.j.header
define void @missed_outer_prefix_subnest(ptr noalias %Left, ptr noalias %Right,
ptr noalias %A) {
entry:
br label %loop.i.header
loop.i.header:
%i = phi i64 [ 0, %entry ], [ %i.next, %loop.i.latch ]
br label %loop.j.header
loop.j.header:
%j = phi i64 [ 0, %loop.i.header ], [ %j.next, %loop.j.latch ]
%a.row = mul nuw nsw i64 %i, 8
%a.idx = add nuw nsw i64 %a.row, %j
%a.ptr = getelementptr i8, ptr %A, i64 %a.idx
store i8 0, ptr %a.ptr, align 1
br label %loop.k.header
loop.k.header:
%k = phi i64 [ 0, %loop.j.header ], [ %k.next, %loop.k.latch ]
br label %loop.l.header
loop.l.header:
%l = phi i64 [ 0, %loop.k.header ], [ %l.next, %loop.l.latch ]
br label %loop.m.header
loop.m.header:
%m = phi i64 [ 0, %loop.l.header ], [ %m.next, %loop.m.latch ]
%left.row.base = mul nuw nsw i64 %m, 8
%left.index = add nuw nsw i64 %left.row.base, %l
%left.element.ptr = getelementptr i8, ptr %Left, i64 %left.index
store i8 0, ptr %left.element.ptr, align 1
br label %loop.m.latch
loop.m.latch:
%m.next = add nuw nsw i64 %m, 1
%m.done = icmp eq i64 %m.next, 8
br i1 %m.done, label %loop.l.latch, label %loop.m.header
loop.l.latch:
%l.next = add nuw nsw i64 %l, 1
%l.done = icmp eq i64 %l.next, 8
br i1 %l.done, label %loop.n.header, label %loop.l.header
loop.n.header:
%n = phi i64 [ 0, %loop.l.latch ], [ %n.next, %loop.n.latch ]
br label %loop.o.header
loop.o.header:
%o = phi i64 [ 0, %loop.n.header ], [ %o.next, %loop.o.latch ]
%right.row.base = mul nuw nsw i64 %o, 8
%right.index = add nuw nsw i64 %right.row.base, %n
%right.element.ptr = getelementptr i8, ptr %Right, i64 %right.index
store i8 0, ptr %right.element.ptr, align 1
br label %loop.o.latch
loop.o.latch:
%o.next = add nuw nsw i64 %o, 1
%o.done = icmp eq i64 %o.next, 8
br i1 %o.done, label %loop.n.latch, label %loop.o.header
loop.n.latch:
%n.next = add nuw nsw i64 %n, 1
%n.done = icmp eq i64 %n.next, 8
br i1 %n.done, label %loop.k.latch, label %loop.n.header
loop.k.latch:
%k.next = add nuw nsw i64 %k, 1
%k.done = icmp eq i64 %k.next, 8
br i1 %k.done, label %loop.j.latch, label %loop.k.header
loop.j.latch:
%j.next = add nuw nsw i64 %j, 1
%j.done = icmp eq i64 %j.next, 8
br i1 %j.done, label %loop.i.latch, label %loop.j.header
loop.i.latch:
%i.next = add nuw nsw i64 %i, 1
%i.done = icmp eq i64 %i.next, 8
br i1 %i.done, label %exit, label %loop.i.header
exit:
ret void
}