1; RUN: opt -irce -S < %s 2>&1 | FileCheck %s
2
3; This test demonstrates a miscompile: the outer loop's IV iterates in range of
4; [2, 400) and the range check is done against value 331. Due to a bug in range
5; intersection IRCE manages to eliminate the range check without inserting a
6; postloop, which is incorrect. So far IRCE is prohibited for this case.
7
8define void @test_01() {
9
10; CHECK-LABEL: test_01
11; CHECK-NOT:   br i1 true
12
13entry:
14  br label %loop_header
15
16loop_header:                            ; preds = %loop_latch, %entry
17  %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]
18  %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]
19  %tmp2 = icmp sgt i32 %iv.prev, -1
20  br i1 %tmp2, label %loop_header.split.us, label %exit
21
22loop_header.split.us:                   ; preds = %loop_header
23  br label %inner_loop
24
25inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us
26  %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]
27  %inner_iv_next = add nuw nsw i32 %inner_iv, 1
28  %inner_cond = icmp ult i32 %inner_iv_next, 31
29  br i1 %inner_cond, label %inner_loop, label %range_check_block
30
31exit:                                            ; preds = %loop_latch, %loop_header
32  ret void
33
34range_check_block:                                          ; preds = %inner_loop
35  %range_check = icmp slt i32 %iv, 331
36  br i1 %range_check, label %loop_latch, label %deopt
37
38loop_latch:                                         ; preds = %range_check_block
39  %iv_next = add i32 %iv, 1
40  %loop_cond = icmp ult i32 %iv_next, 400
41  br i1 %loop_cond, label %loop_header, label %exit
42
43deopt:                                          ; preds = %range_check_block
44  ret void
45}
46