[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / IRCE / range_intersect_miscompile.ll
blobfa7544d982216cfd5f7c4a0bdbf0dec6d73eddc5
1 ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s
2 ; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -S < %s 2>&1 | FileCheck %s
4 ; CHECK-LABEL: irce: in function test_01: constrained Loop at depth 1 containing:
5 ; CHECK-LABEL: irce: in function test_02: constrained Loop at depth 1 containing:
6 ; CHECK-LABEL: irce: in function test_03: constrained Loop at depth 1 containing:
7 ; CHECK-LABEL: irce: in function test_04: constrained Loop at depth 1 containing:
8 ; CHECK-LABEL: irce: in function test_05: constrained Loop at depth 1 containing:
10 ; This test used to demonstrate a miscompile: the outer loop's IV iterates in
11 ; range of [2, 400) and the range check is done against value 331. Due to a bug
12 ; in range intersection IRCE manages to eliminate the range check without
13 ; inserting a postloop, which is incorrect. We treat the range of this test as
14 ; an unsigned range and are able to intersect ranges correctly and insert a
15 ; postloop.
17 define void @test_01() {
19 ; CHECK-LABEL: test_01
20 ; CHECK-NOT:     preloop
21 ; CHECK:         range_check_block:                                ; preds = %inner_loop
22 ; CHECK-NEXT:      %range_check = icmp slt i32 %iv, 331
23 ; CHECK-NEXT:      br i1 true, label %loop_latch
24 ; CHECK:         loop_latch:
25 ; CHECK-NEXT:      %iv_next = add i32 %iv, 1
26 ; CHECK-NEXT:      %loop_cond = icmp ult i32 %iv_next, 400
27 ; CHECK-NEXT:      [[COND:%[^ ]+]] = icmp ult i32 %iv_next, 331
28 ; CHECK-NEXT:      br i1 [[COND]], label %loop_header, label %main.exit.selector
29 ; CHECK:         main.exit.selector:                               ; preds = %loop_latch
30 ; CHECK-NEXT:      %iv_next.lcssa = phi i32 [ %iv_next, %loop_latch ]
31 ; CHECK-NEXT:      %iv.lcssa = phi i32 [ %iv, %loop_latch ]
32 ; CHECK-NEXT:      [[MES_COND:%[^ ]+]] = icmp ult i32 %iv_next.lcssa, 400
33 ; CHECK-NEXT:      br i1 [[MES_COND]], label %main.pseudo.exit, label %exit
34 ; CHECK:         loop_latch.postloop:                              ; preds = %range_check_block.postloop
35 ; CHECK-NEXT:      %iv_next.postloop = add i32 %iv.postloop, 1
36 ; CHECK-NEXT:      %loop_cond.postloop = icmp ult i32 %iv_next.postloop, 400
37 ; CHECK-NEXT:      br i1 %loop_cond.postloop, label %loop_header.postloop, label %exit.loopexit
39 entry:
40   br label %loop_header
42 loop_header:                            ; preds = %loop_latch, %entry
43   %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]
44   %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]
45   %tmp2 = icmp sgt i32 %iv.prev, -1
46   br i1 %tmp2, label %loop_header.split.us, label %exit
48 loop_header.split.us:                   ; preds = %loop_header
49   br label %inner_loop
51 inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us
52   %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]
53   %inner_iv_next = add nuw nsw i32 %inner_iv, 1
54   %inner_cond = icmp ult i32 %inner_iv_next, 31
55   br i1 %inner_cond, label %inner_loop, label %range_check_block
57 exit:                                            ; preds = %loop_latch, %loop_header
58   ret void
60 range_check_block:                                          ; preds = %inner_loop
61   %range_check = icmp slt i32 %iv, 331
62   br i1 %range_check, label %loop_latch, label %deopt
64 loop_latch:                                         ; preds = %range_check_block
65   %iv_next = add i32 %iv, 1
66   %loop_cond = icmp ult i32 %iv_next, 400
67   br i1 %loop_cond, label %loop_header, label %exit
69 deopt:                                          ; preds = %range_check_block
70   ret void
73 ; Similar to test_01, but here the range check is done against 450. No postloop
74 ; is required.
76 define void @test_02() {
78 ; CHECK-LABEL: test_02
79 ; CHECK-NOT:     preloop
80 ; CHECK-NOT:     postloop
81 ; CHECK:         range_check_block:                                ; preds = %inner_loop
82 ; CHECK-NEXT:      %range_check = icmp slt i32 %iv, 450
83 ; CHECK-NEXT:      br i1 true, label %loop_latch
84 ; CHECK:         loop_latch:                                       ; preds = %range_check_block
85 ; CHECK-NEXT:      %iv_next = add i32 %iv, 1
86 ; CHECK-NEXT:      %loop_cond = icmp ult i32 %iv_next, 400
87 ; CHECK-NEXT:      br i1 %loop_cond, label %loop_header, label %exit
89 entry:
90   br label %loop_header
92 loop_header:                            ; preds = %loop_latch, %entry
93   %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]
94   %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]
95   %tmp2 = icmp sgt i32 %iv.prev, -1
96   br i1 %tmp2, label %loop_header.split.us, label %exit
98 loop_header.split.us:                   ; preds = %loop_header
99   br label %inner_loop
101 inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us
102   %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]
103   %inner_iv_next = add nuw nsw i32 %inner_iv, 1
104   %inner_cond = icmp ult i32 %inner_iv_next, 31
105   br i1 %inner_cond, label %inner_loop, label %range_check_block
107 exit:                                            ; preds = %loop_latch, %loop_header
108   ret void
110 range_check_block:                                          ; preds = %inner_loop
111   %range_check = icmp slt i32 %iv, 450
112   br i1 %range_check, label %loop_latch, label %deopt
114 loop_latch:                                         ; preds = %range_check_block
115   %iv_next = add i32 %iv, 1
116   %loop_cond = icmp ult i32 %iv_next, 400
117   br i1 %loop_cond, label %loop_header, label %exit
119 deopt:                                          ; preds = %range_check_block
120   ret void
123 ; Range check is made against 0, so the safe iteration range is empty. IRCE
124 ; should not apply to the inner loop. The condition %tmp2 can be eliminated.
126 define void @test_03() {
128 ; CHECK-LABEL: test_03
129 ; CHECK-NOT:   preloop
130 ; CHECK-NOT:   postloop
131 ; CHECK:         %tmp2 = icmp sgt i32 %iv.prev, -1
132 ; CHECK-NEXT:    br i1 true, label %loop_header.split.us, label %exit
133 ; CHECK:       range_check_block:
134 ; CHECK-NEXT:    %range_check = icmp slt i32 %iv, 0
135 ; CHECK-NEXT:    br i1 %range_check, label %loop_latch, label %deopt
137 entry:
138   br label %loop_header
140 loop_header:                            ; preds = %loop_latch, %entry
141   %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]
142   %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]
143   %tmp2 = icmp sgt i32 %iv.prev, -1
144   br i1 %tmp2, label %loop_header.split.us, label %exit
146 loop_header.split.us:                   ; preds = %loop_header
147   br label %inner_loop
149 inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us
150   %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]
151   %inner_iv_next = add nuw nsw i32 %inner_iv, 1
152   %inner_cond = icmp ult i32 %inner_iv_next, 31
153   br i1 %inner_cond, label %inner_loop, label %range_check_block
155 exit:                                            ; preds = %loop_latch, %loop_header
156   ret void
158 range_check_block:                                          ; preds = %inner_loop
159   %range_check = icmp slt i32 %iv, 0
160   br i1 %range_check, label %loop_latch, label %deopt
162 loop_latch:                                         ; preds = %range_check_block
163   %iv_next = add i32 %iv, 1
164   %loop_cond = icmp ult i32 %iv_next, 400
165   br i1 %loop_cond, label %loop_header, label %exit
167 deopt:                                          ; preds = %range_check_block
168   ret void
171 ; We can also properly eliminate range check against %n which is not always
172 ; known positive.
174 define void @test_04(i32* %p) {
176 ; CHECK-LABEL: test_04
177 ; CHECK:       entry
178 ; CHECK-NOT:   preloop
179 ; CHECK:         %tmp2 = icmp sgt i32 %iv.prev, -1
180 ; CHECK-NEXT:    br i1 true, label %loop_header.split.us, label %exit
181 ; CHECK:       range_check_block:
182 ; CHECK-NEXT:    %range_check = icmp slt i32 %iv, %n
183 ; CHECK-NEXT:    br i1 true, label %loop_latch, label %deopt
184 ; CHECK:       postloop:
186 entry:
187   %n = load i32, i32* %p
188   br label %loop_header
190 loop_header:                            ; preds = %loop_latch, %entry
191   %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]
192   %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]
193   %tmp2 = icmp sgt i32 %iv.prev, -1
194   br i1 %tmp2, label %loop_header.split.us, label %exit
196 loop_header.split.us:                   ; preds = %loop_header
197   br label %inner_loop
199 inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us
200   %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]
201   %inner_iv_next = add nuw nsw i32 %inner_iv, 1
202   %inner_cond = icmp ult i32 %inner_iv_next, 31
203   br i1 %inner_cond, label %inner_loop, label %range_check_block
205 exit:                                            ; preds = %loop_latch, %loop_header
206   ret void
208 range_check_block:                                          ; preds = %inner_loop
209   %range_check = icmp slt i32 %iv, %n
210   br i1 %range_check, label %loop_latch, label %deopt
212 loop_latch:                                         ; preds = %range_check_block
213   %iv_next = add i32 %iv, 1
214   %loop_cond = icmp ult i32 %iv_next, 400
215   br i1 %loop_cond, label %loop_header, label %exit
217 deopt:                                          ; preds = %range_check_block
218   ret void
221 ; Same as test_04, but range guarantees that %n is positive. So we can safely
222 ; intersect ranges (with insertion of postloop).
224 define void @test_05(i32* %p) {
226 ; CHECK-LABEL: test_05
227 ; CHECK-NOT:     preloop
228 ; CHECK:         entry:
229 ; CHECK-NEXT:      %n = load i32, i32* %p, align 4, !range !
230 ; CHECK-NEXT:      %exit.mainloop.at = call i32 @llvm.umax.i32(i32 %n, i32 2)
231 ; CHECK-NEXT:      [[CMP_2:%[^ ]+]] = icmp ult i32 2, %exit.mainloop.at
232 ; CHECK-NEXT:      br i1 [[CMP_2]], label %loop_header.preheader, label %main.pseudo.exit
233 ; CHECK:         range_check_block:                                ; preds = %inner_loop
234 ; CHECK-NEXT:      %range_check = icmp slt i32 %iv, %n
235 ; CHECK-NEXT:      br i1 true, label %loop_latch, label %deopt.loopexit2
236 ; CHECK:         loop_latch:                                       ; preds = %range_check_block
237 ; CHECK-NEXT:      %iv_next = add i32 %iv, 1
238 ; CHECK-NEXT:      %loop_cond = icmp ult i32 %iv_next, 400
239 ; CHECK-NEXT:      [[COND:%[^ ]+]] = icmp ult i32 %iv_next, %exit.mainloop.at
240 ; CHECK-NEXT:      br i1 [[COND]], label %loop_header, label %main.exit.selector
241 ; CHECK:         main.exit.selector:                               ; preds = %loop_latch
242 ; CHECK-NEXT:      %iv_next.lcssa = phi i32 [ %iv_next, %loop_latch ]
243 ; CHECK-NEXT:      %iv.lcssa = phi i32 [ %iv, %loop_latch ]
244 ; CHECK-NEXT:      [[MES_COND:%[^ ]+]] = icmp ult i32 %iv_next.lcssa, 400
245 ; CHECK-NEXT:      br i1 [[MES_COND]], label %main.pseudo.exit, label %exit
246 ; CHECK:         loop_latch.postloop:                              ; preds = %range_check_block.postloop
247 ; CHECK-NEXT:      %iv_next.postloop = add i32 %iv.postloop, 1
248 ; CHECK-NEXT:      %loop_cond.postloop = icmp ult i32 %iv_next.postloop, 400
249 ; CHECK-NEXT:      br i1 %loop_cond.postloop, label %loop_header.postloop, label %exit.loopexit
251 entry:
252   %n = load i32, i32* %p, !range !0
253   br label %loop_header
255 loop_header:                            ; preds = %loop_latch, %entry
256   %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]
257   %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]
258   %tmp2 = icmp sgt i32 %iv.prev, -1
259   br i1 %tmp2, label %loop_header.split.us, label %exit
261 loop_header.split.us:                   ; preds = %loop_header
262   br label %inner_loop
264 inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us
265   %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]
266   %inner_iv_next = add nuw nsw i32 %inner_iv, 1
267   %inner_cond = icmp ult i32 %inner_iv_next, 31
268   br i1 %inner_cond, label %inner_loop, label %range_check_block
270 exit:                                            ; preds = %loop_latch, %loop_header
271   ret void
273 range_check_block:                                          ; preds = %inner_loop
274   %range_check = icmp slt i32 %iv, %n
275   br i1 %range_check, label %loop_latch, label %deopt
277 loop_latch:                                         ; preds = %range_check_block
278   %iv_next = add i32 %iv, 1
279   %loop_cond = icmp ult i32 %iv_next, 400
280   br i1 %loop_cond, label %loop_header, label %exit
282 deopt:                                          ; preds = %range_check_block
283   ret void
286 !0 = !{i32 0, i32 50}