xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/loops-bottom-tested-base.ll (revision ca0d3c99e109e5ed81b244712f0fa2d24b8812b1)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4declare void @use(i1)
5
6define void @loop_iv_cond_variable_bound(i32 %n) {
7; CHECK-LABEL: @loop_iv_cond_variable_bound(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    br label [[LOOP:%.*]]
10; CHECK:       loop:
11; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
12; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i32 [[IV]], [[N:%.*]]
13; CHECK-NEXT:    call void @use(i1 [[T_1]])
14; CHECK-NEXT:    [[T_2:%.*]] = icmp sge i32 [[IV]], 0
15; CHECK-NEXT:    call void @use(i1 [[T_2]])
16; CHECK-NEXT:    [[T_3:%.*]] = icmp sge i32 [[IV]], -1
17; CHECK-NEXT:    call void @use(i1 [[T_3]])
18; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i32 [[IV]], [[N]]
19; CHECK-NEXT:    call void @use(i1 [[C_1]])
20; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[IV]], 1
21; CHECK-NEXT:    call void @use(i1 [[C_2]])
22; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IV]], [[N]]
23; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
24; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
25; CHECK:       exit:
26; CHECK-NEXT:    ret void
27;
28entry:
29  br label %loop
30
31loop:
32  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
33  %t.1 = icmp ule i32 %iv, %n
34  call void @use(i1 %t.1)
35  %t.2 = icmp sge i32 %iv, 0
36  call void @use(i1 %t.2)
37  %t.3 = icmp sge i32 %iv, -1
38  call void @use(i1 %t.3)
39
40  %c.1 = icmp ult i32 %iv, %n
41  call void @use(i1 %c.1)
42  %c.2 = icmp ugt i32 %iv, 1
43  call void @use(i1 %c.2)
44
45  %cmp = icmp ult i32 %iv, %n
46  %iv.next = add nuw nsw i32 %iv, 1
47  br i1 %cmp, label %loop, label %exit
48
49exit:
50  ret void
51}
52
53define void @loop_iv_cond_constant_bound() {
54; CHECK-LABEL: @loop_iv_cond_constant_bound(
55; CHECK-NEXT:  entry:
56; CHECK-NEXT:    br label [[LOOP:%.*]]
57; CHECK:       loop:
58; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
59; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i32 [[IV]], 2
60; CHECK-NEXT:    call void @use(i1 [[T_1]])
61; CHECK-NEXT:    [[T_2:%.*]] = icmp sge i32 [[IV]], 0
62; CHECK-NEXT:    call void @use(i1 [[T_2]])
63; CHECK-NEXT:    [[T_3:%.*]] = icmp sge i32 [[IV]], -1
64; CHECK-NEXT:    call void @use(i1 [[T_3]])
65; CHECK-NEXT:    [[C_1:%.*]] = icmp ult i32 [[IV]], 2
66; CHECK-NEXT:    call void @use(i1 [[C_1]])
67; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[IV]], 1
68; CHECK-NEXT:    call void @use(i1 [[C_2]])
69; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IV]], 2
70; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
71; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
72; CHECK:       exit:
73; CHECK-NEXT:    ret void
74;
75entry:
76  br label %loop
77
78loop:
79  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
80  %t.1 = icmp ule i32 %iv, 2
81  call void @use(i1 %t.1)
82  %t.2 = icmp sge i32 %iv, 0
83  call void @use(i1 %t.2)
84  %t.3 = icmp sge i32 %iv, -1
85  call void @use(i1 %t.3)
86
87  %c.1 = icmp ult i32 %iv, 2
88  call void @use(i1 %c.1)
89  %c.2 = icmp ugt i32 %iv, 1
90  call void @use(i1 %c.2)
91
92  %cmp = icmp ult i32 %iv, 2
93  %iv.next = add nuw nsw i32 %iv, 1
94  br i1 %cmp, label %loop, label %exit
95
96exit:
97  ret void
98}
99
100declare void @clobber()
101
102define void @eq_exit_check_constant_int() {
103; CHECK-LABEL: @eq_exit_check_constant_int(
104; CHECK-NEXT:  entry:
105; CHECK-NEXT:    br label [[LOOP:%.*]]
106; CHECK:       loop:
107; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
108; CHECK-NEXT:    [[IV_NEXT]] = add nuw i64 [[IV]], 1
109; CHECK-NEXT:    call void @clobber()
110; CHECK-NEXT:    [[C:%.*]] = icmp eq i64 [[IV]], 2
111; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[LOOP]]
112; CHECK:       exit:
113; CHECK-NEXT:    ret void
114;
115entry:
116  br label %loop
117
118loop:
119  %iv = phi i64 [ 1, %entry], [ %iv.next, %loop ]
120  %iv.next = add nuw i64 %iv, 1
121  call void @clobber()
122  %c = icmp eq i64 %iv, 2
123  br i1 %c, label %exit, label %loop
124
125exit:
126  ret void
127}
128
129define void @eq_exit_check_variable(i64 %N) {
130; CHECK-LABEL: @eq_exit_check_variable(
131; CHECK-NEXT:  entry:
132; CHECK-NEXT:    [[PRECOND:%.*]] = icmp eq i64 [[N:%.*]], 0
133; CHECK-NEXT:    br i1 [[PRECOND]], label [[EXIT:%.*]], label [[LOOP:%.*]]
134; CHECK:       loop:
135; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
136; CHECK-NEXT:    [[IV_NEXT]] = add nuw i64 [[IV]], 1
137; CHECK-NEXT:    call void @clobber()
138; CHECK-NEXT:    [[EXITCOND86_NOT_I_I:%.*]] = icmp eq i64 [[IV]], [[N]]
139; CHECK-NEXT:    br i1 [[EXITCOND86_NOT_I_I]], label [[EXIT]], label [[LOOP]]
140; CHECK:       exit:
141; CHECK-NEXT:    ret void
142;
143entry:
144  %precond = icmp eq i64 %N, 0
145  br i1 %precond, label %exit, label %loop
146
147loop:
148  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
149  %iv.next = add nuw i64 %iv, 1
150  call void @clobber()
151  %exitcond86.not.i.i = icmp eq i64 %iv, %N
152  br i1 %exitcond86.not.i.i, label %exit, label %loop
153
154exit:
155  ret void
156}
157
158define void @eq_exit_check_constant_ptr(ptr %start) {
159; CHECK-LABEL: @eq_exit_check_constant_ptr(
160; CHECK-NEXT:  entry:
161; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i8 2
162; CHECK-NEXT:    br label [[LOOP:%.*]]
163; CHECK:       loop:
164; CHECK-NEXT:    [[IV:%.*]] = phi ptr [ [[START]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
165; CHECK-NEXT:    [[IV_NEXT]] = getelementptr inbounds i8, ptr [[IV]], i8 1
166; CHECK-NEXT:    call void @clobber()
167; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[IV]], [[UPPER]]
168; CHECK-NEXT:    br i1 [[C]], label [[EXIT:%.*]], label [[LOOP]]
169; CHECK:       exit:
170; CHECK-NEXT:    ret void
171;
172entry:
173  %upper = getelementptr inbounds i8, ptr %start, i8 2
174  br label %loop
175
176loop:
177  %iv = phi ptr [ %start, %entry], [ %iv.next, %loop ]
178  %iv.next = getelementptr inbounds i8, ptr %iv, i8 1
179  call void @clobber()
180  %c = icmp eq ptr %iv, %upper
181  br i1 %c, label %exit, label %loop
182
183exit:
184  ret void
185}
186