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