OSDN Git Service

[Tests] Add cases where we're failing to discharge provably loop exits (tests for...
[android-x86/external-llvm.git] / test / Transforms / IndVarSimplify / eliminate-exit.ll
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -indvars -S < %s | FileCheck %s
3
4 define void @ult(i64 %n, i64 %m) {
5 ; CHECK-LABEL: @ult(
6 ; CHECK-NEXT:  entry:
7 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ult i64 [[N:%.*]], [[M:%.*]]
8 ; CHECK-NEXT:    br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
9 ; CHECK:       loop.preheader:
10 ; CHECK-NEXT:    br label [[LOOP:%.*]]
11 ; CHECK:       loop:
12 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
13 ; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
14 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
15 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
16 ; CHECK:       latch:
17 ; CHECK-NEXT:    call void @side_effect()
18 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
19 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
20 ; CHECK:       exit.loopexit:
21 ; CHECK-NEXT:    br label [[EXIT]]
22 ; CHECK:       exit:
23 ; CHECK-NEXT:    ret void
24 ;
25 entry:
26   %cmp0 = icmp ult i64 %n, %m
27   br i1 %cmp0, label %loop, label %exit
28 loop:
29   %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
30   %iv.next = add i64 %iv, 1
31   %cmp1 = icmp ult i64 %iv, %n
32   br i1 %cmp1, label %latch, label %exit
33 latch:
34   call void @side_effect()
35   %cmp2 = icmp ult i64 %iv, %m
36   br i1 %cmp2, label %loop, label %exit
37 exit:
38   ret void
39 }
40
41 define void @ugt(i64 %n, i64 %m) {
42 ; CHECK-LABEL: @ugt(
43 ; CHECK-NEXT:  entry:
44 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i64 [[N:%.*]], [[M:%.*]]
45 ; CHECK-NEXT:    br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
46 ; CHECK:       loop.preheader:
47 ; CHECK-NEXT:    br label [[LOOP:%.*]]
48 ; CHECK:       loop:
49 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
50 ; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
51 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
52 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
53 ; CHECK:       latch:
54 ; CHECK-NEXT:    call void @side_effect()
55 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
56 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
57 ; CHECK:       exit.loopexit:
58 ; CHECK-NEXT:    br label [[EXIT]]
59 ; CHECK:       exit:
60 ; CHECK-NEXT:    ret void
61 ;
62 entry:
63   %cmp0 = icmp ugt i64 %n, %m
64   br i1 %cmp0, label %loop, label %exit
65 loop:
66   %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
67   %iv.next = add i64 %iv, 1
68   %cmp1 = icmp ult i64 %iv, %n
69   br i1 %cmp1, label %latch, label %exit
70 latch:
71   call void @side_effect()
72   %cmp2 = icmp ult i64 %iv, %m
73   br i1 %cmp2, label %loop, label %exit
74 exit:
75   ret void
76 }
77
78 define void @ule(i64 %n, i64 %m) {
79 ; CHECK-LABEL: @ule(
80 ; CHECK-NEXT:  entry:
81 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ule i64 [[N:%.*]], [[M:%.*]]
82 ; CHECK-NEXT:    br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
83 ; CHECK:       loop.preheader:
84 ; CHECK-NEXT:    br label [[LOOP:%.*]]
85 ; CHECK:       loop:
86 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
87 ; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
88 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
89 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
90 ; CHECK:       latch:
91 ; CHECK-NEXT:    call void @side_effect()
92 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
93 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
94 ; CHECK:       exit.loopexit:
95 ; CHECK-NEXT:    br label [[EXIT]]
96 ; CHECK:       exit:
97 ; CHECK-NEXT:    ret void
98 ;
99 entry:
100   %cmp0 = icmp ule i64 %n, %m
101   br i1 %cmp0, label %loop, label %exit
102 loop:
103   %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
104   %iv.next = add i64 %iv, 1
105   %cmp1 = icmp ult i64 %iv, %n
106   br i1 %cmp1, label %latch, label %exit
107 latch:
108   call void @side_effect()
109   %cmp2 = icmp ult i64 %iv, %m
110   br i1 %cmp2, label %loop, label %exit
111 exit:
112   ret void
113 }
114
115 define void @uge(i64 %n, i64 %m) {
116 ; CHECK-LABEL: @uge(
117 ; CHECK-NEXT:  entry:
118 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp uge i64 [[N:%.*]], [[M:%.*]]
119 ; CHECK-NEXT:    br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
120 ; CHECK:       loop.preheader:
121 ; CHECK-NEXT:    br label [[LOOP:%.*]]
122 ; CHECK:       loop:
123 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
124 ; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
125 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]]
126 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
127 ; CHECK:       latch:
128 ; CHECK-NEXT:    call void @side_effect()
129 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]]
130 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
131 ; CHECK:       exit.loopexit:
132 ; CHECK-NEXT:    br label [[EXIT]]
133 ; CHECK:       exit:
134 ; CHECK-NEXT:    ret void
135 ;
136 entry:
137   %cmp0 = icmp uge i64 %n, %m
138   br i1 %cmp0, label %loop, label %exit
139 loop:
140   %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
141   %iv.next = add i64 %iv, 1
142   %cmp1 = icmp ult i64 %iv, %n
143   br i1 %cmp1, label %latch, label %exit
144 latch:
145   call void @side_effect()
146   %cmp2 = icmp ult i64 %iv, %m
147   br i1 %cmp2, label %loop, label %exit
148 exit:
149   ret void
150 }
151
152
153 define void @ult_const_max(i64 %n) {
154 ; CHECK-LABEL: @ult_const_max(
155 ; CHECK-NEXT:  entry:
156 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ult i64 [[N:%.*]], 20
157 ; CHECK-NEXT:    br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
158 ; CHECK:       loop.preheader:
159 ; CHECK-NEXT:    br label [[LOOP:%.*]]
160 ; CHECK:       loop:
161 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
162 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
163 ; CHECK-NEXT:    [[UDIV:%.*]] = udiv i64 [[IV]], 10
164 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[UDIV]], 2
165 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
166 ; CHECK:       latch:
167 ; CHECK-NEXT:    call void @side_effect()
168 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[IV]], [[N]]
169 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
170 ; CHECK:       exit.loopexit:
171 ; CHECK-NEXT:    br label [[EXIT]]
172 ; CHECK:       exit:
173 ; CHECK-NEXT:    ret void
174 ;
175 entry:
176   %cmp0 = icmp ult i64 %n, 20
177   br i1 %cmp0, label %loop, label %exit
178 loop:
179   %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
180   %iv.next = add i64 %iv, 1
181   %udiv = udiv i64 %iv, 10
182   %cmp1 = icmp ult i64 %udiv, 2
183   br i1 %cmp1, label %latch, label %exit
184 latch:
185   call void @side_effect()
186   %cmp2 = icmp ult i64 %iv, %n
187   br i1 %cmp2, label %loop, label %exit
188 exit:
189   ret void
190 }
191
192
193 declare void @side_effect()