1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=jump-threading < %s | FileCheck %s
; Check that the heuristic for avoiding accidental introduction of irreducible
; loops doesn't also prevent us from threading simple constructs where this
; isn't a problem.
declare void @opaque_body()
define void @jump_threading_loopheader() {
; CHECK-LABEL: @jump_threading_loopheader(
; CHECK-NEXT: top:
; CHECK-NEXT: br label [[ENTRY:%.*]]
; CHECK: entry:
; CHECK-NEXT: [[IND:%.*]] = phi i32 [ 0, [[TOP:%.*]] ], [ [[NEXTIND:%.*]], [[LATCH:%.*]] ]
; CHECK-NEXT: [[NEXTIND]] = add i32 [[IND]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[IND]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[LATCH]], label [[EXIT:%.*]]
; CHECK: latch:
; CHECK-NEXT: call void @opaque_body()
; CHECK-NEXT: br label [[ENTRY]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
top:
br label %entry
entry:
%ind = phi i32 [0, %top], [%nextind, %latch]
%nextind = add i32 %ind, 1
%cmp = icmp ule i32 %ind, 10
br i1 %cmp, label %body, label %latch
body:
call void @opaque_body()
br label %latch
latch:
%cond = phi i2 [1, %entry], [2, %body]
switch i2 %cond, label %unreach [
i2 2, label %entry
i2 1, label %exit
]
unreach:
unreachable
exit:
ret void
}
; We also need to check the opposite order of the branches, in the switch
; instruction because jump-threading relies on that to decide which edge to
; try to thread first.
define void @jump_threading_loopheader2() {
; CHECK-LABEL: @jump_threading_loopheader2(
; CHECK-NEXT: top:
; CHECK-NEXT: br label [[ENTRY:%.*]]
; CHECK: entry:
; CHECK-NEXT: [[IND:%.*]] = phi i32 [ 0, [[TOP:%.*]] ], [ [[NEXTIND:%.*]], [[LATCH:%.*]] ]
; CHECK-NEXT: [[NEXTIND]] = add i32 [[IND]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[IND]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LATCH]]
; CHECK: latch:
; CHECK-NEXT: br label [[ENTRY]]
; CHECK: exit:
; CHECK-NEXT: call void @opaque_body()
; CHECK-NEXT: ret void
;
top:
br label %entry
entry:
%ind = phi i32 [0, %top], [%nextind, %latch]
%nextind = add i32 %ind, 1
%cmp = icmp ule i32 %ind, 10
br i1 %cmp, label %body, label %latch
body:
call void @opaque_body()
br label %latch
latch:
%cond = phi i2 [1, %entry], [2, %body]
switch i2 %cond, label %unreach [
i2 1, label %entry
i2 2, label %exit
]
unreach:
unreachable
exit:
ret void
}
; Check if we can handle undef branch condition.
define void @jump_threading_loopheader3() {
; CHECK-LABEL: @jump_threading_loopheader3(
; CHECK-NEXT: top:
; CHECK-NEXT: br label [[ENTRY:%.*]]
; CHECK: entry:
; CHECK-NEXT: [[IND:%.*]] = phi i32 [ 0, [[TOP:%.*]] ], [ [[NEXTIND:%.*]], [[LATCH:%.*]] ]
; CHECK-NEXT: [[NEXTIND]] = add i32 [[IND]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[IND]], 10
; CHECK-NEXT: br i1 [[CMP]], label [[LATCH]], label [[EXIT:%.*]]
; CHECK: latch:
; CHECK-NEXT: call void @opaque_body()
; CHECK-NEXT: br label [[ENTRY]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
top:
br label %entry
entry:
%ind = phi i32 [0, %top], [%nextind, %latch]
%nextind = add i32 %ind, 1
%cmp = icmp ule i32 %ind, 10
br i1 %cmp, label %body, label %latch
body:
call void @opaque_body()
br label %latch
latch:
%phi = phi i32 [undef, %entry], [0, %body]
%cmp1 = icmp eq i32 %phi, 0
br i1 %cmp1, label %entry, label %exit
exit:
ret void
}
|