blob: b9836d9d60dc39fa6ddbf98f30e42645094bd0b7 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 --keep-loops="true" -S | FileCheck %s
; Threading the latch edge to %exit does not bypass the header.
define void @trip_count_one(ptr %p) {
; CHECK-LABEL: define void @trip_count_one(
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
; CHECK-NEXT: ret void
;
entry:
br label %header
header:
%first = phi i1 [ true, %entry ], [ false, %latch ]
br i1 %first, label %body, label %exit
body:
store i32 0, ptr %p, align 4
br label %latch
latch:
br label %header
exit:
ret void
}
; %inner reaches %latch without going through %header, so threading %latch to
; %inner would form a cycle bypassing %header.
define void @latch_to_body(ptr %p, i1 %a, i1 %c) {
; CHECK-LABEL: define void @latch_to_body(
; CHECK-SAME: ptr [[P:%.*]], i1 [[A:%.*]], i1 [[C:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[HEADER:.*]]
; CHECK: [[HEADER]]:
; CHECK-NEXT: [[V:%.*]] = phi i1 [ [[A]], %[[ENTRY]] ], [ false, %[[INNER:.*]] ]
; CHECK-NEXT: br i1 [[V]], label %[[EXIT:.*]], label %[[INNER]]
; CHECK: [[INNER]]:
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
; CHECK-NEXT: br i1 [[C]], label %[[HEADER]], label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %header
header:
%v = phi i1 [ %a, %entry ], [ false, %latch ]
br i1 %v, label %exit, label %inner
inner:
store i32 0, ptr %p, align 4
br i1 %c, label %latch, label %exit
latch:
br label %header
exit:
ret void
}
; Do not thread through a loop header with multiple backedges.
define void @multi_latch(ptr %p, i1 %a, i1 %b, i1 %c) {
; CHECK-LABEL: define void @multi_latch(
; CHECK-SAME: ptr [[P:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], i1 [[C:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[HEADER:.*]]
; CHECK: [[HEADER]]:
; CHECK-NEXT: [[V:%.*]] = phi i1 [ [[A]], %[[ENTRY]] ], [ [[B]], %[[LATCH1:.*]] ], [ false, %[[LATCH2:.*]] ]
; CHECK-NEXT: br i1 [[V]], label %[[BODY:.*]], label %[[EXIT:.*]]
; CHECK: [[BODY]]:
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
; CHECK-NEXT: br i1 [[C]], label %[[LATCH1]], label %[[LATCH2]]
; CHECK: [[LATCH1]]:
; CHECK-NEXT: store i32 1, ptr [[P]], align 4
; CHECK-NEXT: br label %[[HEADER]]
; CHECK: [[LATCH2]]:
; CHECK-NEXT: store i32 2, ptr [[P]], align 4
; CHECK-NEXT: br label %[[HEADER]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %header
header:
%v = phi i1 [ %a, %entry ], [ %b, %latch1 ], [ false, %latch2 ]
br i1 %v, label %body, label %exit
body:
store i32 0, ptr %p, align 4
br i1 %c, label %latch1, label %latch2
latch1:
store i32 1, ptr %p, align 4
br label %header
latch2:
store i32 2, ptr %p, align 4
br label %header
exit:
ret void
}