blob: 71a6693b7d25dacf0f2541d0ec11ed0093773fce [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=loop-interchange -loop-interchange-profitabilities=ignore -debug-only=loop-interchange -S 2>&1 | FileCheck %s
; REQUIRES: asserts
; This test shows a case where the IR‑transformation phase of loop interchange
; can fail partway. As a result, the final output becomes a partially
; transformed IR.
;
; FIXME: The IR‑transformation phase must not stop partway; in such cases, the
; entire process should bail out early during the legality‑check phase.
; CHECK: Inner loop header does not have a unique successor
define void @f(i1 %cond, ptr %A) {
; CHECK-LABEL: define void @f(
; CHECK-SAME: i1 [[COND:%.*]], ptr [[A:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: br label %[[OUTER_HEADER_PREHEADER:.*]]
; CHECK: [[OUTER_HEADER_PREHEADER]]:
; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
; CHECK: [[OUTER_HEADER]]:
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], %[[OUTER_LATCH:.*]] ], [ 0, %[[OUTER_HEADER_PREHEADER]] ]
; CHECK-NEXT: br label %[[INNER_HEADER_PREHEADER:.*]]
; CHECK: [[INNER_HEADER_PREHEADER]]:
; CHECK-NEXT: br label %[[INNER_HEADER:.*]]
; CHECK: [[INNER_HEADER]]:
; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[INNER_LATCH_SPLIT:.*]] ], [ 0, %[[INNER_HEADER_PREHEADER]] ]
; CHECK-NEXT: br i1 [[COND]], label %[[INNER_BODY_0:.*]], label %[[INNER_BODY_1:.*]]
; CHECK: [[INNER_BODY_0]]:
; CHECK-NEXT: br label %[[INNER_LATCH:.*]]
; CHECK: [[INNER_BODY_1]]:
; CHECK-NEXT: br label %[[INNER_LATCH]]
; CHECK: [[INNER_LATCH]]:
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [42 x i8], ptr [[A]], i64 [[J]], i64 [[I]]
; CHECK-NEXT: store i8 1, ptr [[GEP]], align 1
; CHECK-NEXT: [[J_INC:%.*]] = add i64 [[J]], 1
; CHECK-NEXT: [[EC_J:%.*]] = icmp eq i64 [[J_INC]], 42
; CHECK-NEXT: br label %[[INNER_LATCH_SPLIT]]
; CHECK: [[INNER_LATCH_SPLIT]]:
; CHECK-NEXT: [[TMP0]] = add i64 [[J]], 1
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 42
; CHECK-NEXT: br i1 [[TMP1]], label %[[INNER_EXIT:.*]], label %[[INNER_HEADER]]
; CHECK: [[BB2:.*:]]
; CHECK-NEXT: unreachable
; CHECK: [[INNER_EXIT]]:
; CHECK-NEXT: br label %[[OUTER_LATCH]]
; CHECK: [[OUTER_LATCH]]:
; CHECK-NEXT: [[I_INC]] = add i64 [[I]], 1
; CHECK-NEXT: [[EC_I:%.*]] = icmp eq i64 [[I_INC]], 42
; CHECK-NEXT: br i1 [[EC_I]], label %[[EXIT:.*]], label %[[OUTER_HEADER]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %outer.header
outer.header:
%i = phi i64 [ 0, %entry ], [ %i.inc, %outer.latch ]
br label %inner.header
inner.header:
%j = phi i64 [ 0, %outer.header ], [ %j.inc, %inner.latch ]
br i1 %cond, label %inner.body.0, label %inner.body.1
inner.body.0:
br label %inner.latch
inner.body.1:
br label %inner.latch
inner.latch:
%gep = getelementptr [42 x i8], ptr %A, i64 %j, i64 %i
store i8 1, ptr %gep
%j.inc = add i64 %j, 1
%ec.j = icmp eq i64 %j.inc, 42
br i1 %ec.j, label %inner.exit, label %inner.header
br label %inner.latch
inner.exit:
br label %outer.latch
outer.latch:
%i.inc = add i64 %i, 1
%ec.i = icmp eq i64 %i.inc, 42
br i1 %ec.i, label %exit, label %outer.header
exit:
ret void
}