xref: /llvm-project/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll (revision 9f37ecf8fae9a6fc87a216bee0c83d465e8466b4)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: -p
2; RUN: opt < %s -passes=indvars -S | FileCheck %s
3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
4
5declare i1 @foo(ptr, ptr)
6declare i1 @bar()
7declare i1 @baz()
8
9define i1 @kill_backedge_and_phis(ptr align 1 %lhs, ptr align 1 %rhs, i32 %len) {
10; CHECK-LABEL: @kill_backedge_and_phis(
11; CHECK-NEXT:  entry:
12; CHECK-NEXT:    %length_not_zero = icmp ne i32 %len, 0
13; CHECK-NEXT:    br i1 %length_not_zero, label %loop_preheader, label %exit
14; CHECK:       loop_preheader:
15; CHECK-NEXT:    br label %loop
16; CHECK:       loop:
17; CHECK-NEXT:    %result = call i1 @foo(ptr %lhs, ptr %rhs)
18; CHECK-NEXT:    br i1 %result, label %exiting_1, label %exit.loopexit
19; CHECK:       exiting_1:
20; CHECK-NEXT:    br i1 false, label %exiting_2, label %exit.loopexit
21; CHECK:       exiting_2:
22; CHECK-NEXT:    %bar_ret = call i1 @bar()
23; CHECK-NEXT:    br i1 %bar_ret, label %exit.loopexit, label %exiting_3
24; CHECK:       exiting_3:
25; CHECK-NEXT:    %baz_ret = call i1 @baz()
26; CHECK-NEXT:    %or.cond = select i1 %baz_ret, i1 true, i1 false
27; CHECK-NEXT:    br i1 %or.cond, label %loop, label %exit.loopexit
28; CHECK:       exit.loopexit:
29; CHECK-NEXT:    %val.ph = phi i1 [ %baz_ret, %exiting_3 ], [ %bar_ret, %exiting_2 ], [ false, %exiting_1 ], [ %result, %loop ]
30; CHECK-NEXT:    br label %exit
31; CHECK:       exit:
32; CHECK-NEXT:    %val = phi i1 [ false, %entry ], [ %val.ph, %exit.loopexit ]
33; CHECK-NEXT:    ret i1 %val
34;
35entry:
36  %length_not_zero = icmp ne i32 %len, 0
37  br i1 %length_not_zero, label %loop_preheader, label %exit
38
39loop_preheader:
40  br label %loop
41
42loop:
43  %iv = phi i32 [ 0, %loop_preheader ], [ %iv.next, %latch ]
44  %iv.wide = phi i64 [ 0, %loop_preheader ], [ %iv.wide.next, %latch ]
45  %iv.next = add i32 %iv, 1
46  %iv.wide.next = add i64 %iv.wide, 1
47  %left_ptr = getelementptr inbounds i8, ptr %lhs, i32 %iv
48  %right_ptr = getelementptr inbounds i8, ptr %rhs, i32 %iv
49  %result = call i1 @foo(ptr %left_ptr, ptr %right_ptr)
50  br i1 %result, label %exiting_1, label %exit
51
52exiting_1:
53  %iv.wide.is_not_zero = icmp ne i64 %iv.wide, 0
54  br i1 %iv.wide.is_not_zero, label %exiting_2, label %exit
55
56exiting_2:
57  %bar_ret = call i1 @bar()
58  br i1 %bar_ret, label %exit, label %exiting_3
59
60exiting_3:
61  %baz_ret = call i1 @baz()
62  br i1 %baz_ret, label %latch, label %exit
63
64latch:
65  %continue = icmp ne i32 %iv.next, %len
66  br i1 %continue, label %loop, label %exit
67
68exit:
69  %val = phi i1 [ %result, %loop ], [ %iv.wide.is_not_zero, %exiting_1 ],
70  [ %bar_ret, %exiting_2 ], [ %baz_ret, %exiting_3 ],
71  [ %baz_ret, %latch ], [ 0, %entry ]
72  ret i1 %val
73}
74
75define i1 @siblings(ptr align 1 %lhs, ptr align 1 %rhs, i32 %len) {
76; CHECK-LABEL: @siblings(
77; CHECK-NEXT:  entry:
78; CHECK-NEXT:    %length_not_zero = icmp ne i32 %len, 0
79; CHECK-NEXT:    br i1 %length_not_zero, label %weird_loop.preheader, label %exit
80; CHECK:       weird_loop.preheader:
81; CHECK-NEXT:    br label %weird_loop
82; CHECK:       weird_loop:
83; CHECK-NEXT:    %weird.iv = phi i32 [ %weird.iv.next, %weird_loop ], [ 0, %weird_loop.preheader ]
84; CHECK-NEXT:    %weird.iv.next = add i32 %weird.iv, 1
85; CHECK-NEXT:    %weird.cond = call i1 @bar()
86; CHECK-NEXT:    br i1 %weird.cond, label %weird_loop, label %loop.preheader
87; CHECK:       loop.preheader:
88; CHECK-NEXT:    %weird.iv.lcssa = phi i32 [ %weird.iv, %weird_loop ]
89; CHECK-NEXT:    br label %loop
90; CHECK:       loop:
91; CHECK-NEXT:    %left_ptr = getelementptr inbounds i8, ptr %lhs, i32 %weird.iv.lcssa
92; CHECK-NEXT:    %right_ptr = getelementptr inbounds i8, ptr %rhs, i32 %weird.iv.lcssa
93; CHECK-NEXT:    %result = call i1 @foo(ptr %left_ptr, ptr %right_ptr)
94; CHECK-NEXT:    br i1 %result, label %exiting_1, label %exit.loopexit
95; CHECK:       exiting_1:
96; CHECK-NEXT:    br i1 false, label %exiting_2, label %exit.loopexit
97; CHECK:       exiting_2:
98; CHECK-NEXT:    %bar_ret = call i1 @bar()
99; CHECK-NEXT:    br i1 %bar_ret, label %exit.loopexit, label %exiting_3
100; CHECK:       exiting_3:
101; CHECK-NEXT:    %baz_ret = call i1 @baz()
102; CHECK-NEXT:    %or.cond = select i1 %baz_ret, i1 true, i1 false
103; CHECK-NEXT:    br i1 %or.cond, label %loop, label %exit.loopexit
104; CHECK:       exit.loopexit:
105; CHECK-NEXT:    %val.ph = phi i1 [ %baz_ret, %exiting_3 ], [ %bar_ret, %exiting_2 ], [ false, %exiting_1 ], [ %result, %loop ]
106; CHECK-NEXT:    br label %exit
107; CHECK:       exit:
108; CHECK-NEXT:    %val = phi i1 [ false, %entry ], [ %val.ph, %exit.loopexit ]
109; CHECK-NEXT:    ret i1 %val
110;
111entry:
112  %length_not_zero = icmp ne i32 %len, 0
113  br i1 %length_not_zero, label %weird_loop, label %exit
114
115weird_loop:
116  %weird.iv = phi i32 [ 0, %entry ], [ %weird.iv.next, %weird_loop ]
117  %weird.iv.next = add i32 %weird.iv, 1
118  %weird.iv.wide = zext i32 %weird.iv to i64
119  %weird.cond = call i1 @bar()
120  br i1 %weird.cond, label %weird_loop, label %loop
121
122loop:
123  %iv = phi i32 [ %weird.iv, %weird_loop ], [ %iv.next, %latch ]
124  %iv.wide = phi i64 [ %weird.iv.wide, %weird_loop ], [ %iv.wide.next, %latch ]
125  %iv.next = add i32 %iv, 1
126  %iv.wide.next = add i64 %iv.wide, 1
127  %left_ptr = getelementptr inbounds i8, ptr %lhs, i32 %iv
128  %right_ptr = getelementptr inbounds i8, ptr %rhs, i32 %iv
129  %result = call i1 @foo(ptr %left_ptr, ptr %right_ptr)
130  br i1 %result, label %exiting_1, label %exit
131
132exiting_1:
133  %iv.wide.is_not_zero = icmp ne i64 %iv.wide, %weird.iv.wide
134  br i1 %iv.wide.is_not_zero, label %exiting_2, label %exit
135
136exiting_2:
137  %bar_ret = call i1 @bar()
138  br i1 %bar_ret, label %exit, label %exiting_3
139
140exiting_3:
141  %baz_ret = call i1 @baz()
142  br i1 %baz_ret, label %latch, label %exit
143
144latch:
145  %continue = icmp ne i32 %iv.next, %len
146  br i1 %continue, label %loop, label %exit
147
148exit:
149  %val = phi i1 [ %result, %loop ], [ %iv.wide.is_not_zero, %exiting_1 ],
150  [ %bar_ret, %exiting_2 ], [ %baz_ret, %exiting_3 ],
151  [ %baz_ret, %latch ], [ 0, %entry ]
152  ret i1 %val
153}
154