xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis.ll (revision 98e016d99732dc8fef8cfd61d6ce1edd042309a1)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5
6
7declare void @use(i16)
8declare void @llvm.assume(i1)
9
10define void @test_monotonic_ptr_iv_inc_1_eq_to_uge(i8 %len.n, i16 %a) {
11; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge(
12; CHECK-NEXT:  entry:
13; CHECK-NEXT:    [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16
14; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp uge i16 [[LEN]], [[A:%.*]]
15; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
16; CHECK:       loop.ph:
17; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
18; CHECK:       loop.header:
19; CHECK-NEXT:    [[IV:%.*]] = phi i16 [ 0, [[LOOP_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
20; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[IV]], [[LEN]]
21; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
22; CHECK:       for.body:
23; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
24; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
25; CHECK:       loop.latch:
26; CHECK-NEXT:    call void @use(i16 [[IV]])
27; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1
28; CHECK-NEXT:    br label [[LOOP_HEADER]]
29; CHECK:       exit:
30; CHECK-NEXT:    ret void
31;
32entry:
33  %len = zext i8 %len.n to i16
34  %len.neg = icmp uge i16 %len, %a
35  br i1 %len.neg, label %exit, label %loop.ph
36
37loop.ph:
38  br label %loop.header
39
40loop.header:
41  %iv = phi i16 [ 0, %loop.ph ], [ %iv.next, %loop.latch ]
42  %c = icmp eq i16 %iv, %len
43  br i1 %c, label %exit, label %for.body
44
45for.body:
46  %t.1 = icmp uge i16 %iv, 0
47  %t.2 = icmp ult i16 %iv, %a
48  %and = and i1 %t.1, %t.2
49  br i1 %and, label %loop.latch, label %exit
50
51loop.latch:
52  call void @use(i16 %iv)
53  %iv.next = add nuw nsw i16 %iv, 1
54  br label %loop.header
55
56exit:
57  ret void
58}
59
60define void @test_remove_check_with_incrementing_integer_induction(i8 %len.n, i16 %a) {
61; CHECK-LABEL: @test_remove_check_with_incrementing_integer_induction(
62; CHECK-NEXT:  entry:
63; CHECK-NEXT:    [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16
64; CHECK-NEXT:    [[LEN_NEG_NOT:%.*]] = icmp ult i16 [[LEN]], [[A:%.*]]
65; CHECK-NEXT:    br i1 [[LEN_NEG_NOT]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
66; CHECK:       loop.header:
67; CHECK-NEXT:    [[IV:%.*]] = phi i16 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
68; CHECK-NEXT:    [[C:%.*]] = icmp ne i16 [[IV]], [[LEN]]
69; CHECK-NEXT:    [[T_2:%.*]] = icmp ult i16 [[IV]], [[A]]
70; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[C]], [[T_2]]
71; CHECK-NEXT:    br i1 [[OR_COND]], label [[LOOP_LATCH]], label [[EXIT]]
72; CHECK:       loop.latch:
73; CHECK-NEXT:    call void @use(i16 [[IV]])
74; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1
75; CHECK-NEXT:    br label [[LOOP_HEADER]]
76; CHECK:       exit:
77; CHECK-NEXT:    ret void
78;
79entry:
80  %len = zext i8 %len.n to i16
81  %len.neg.not = icmp ult i16 %len, %a
82  br i1 %len.neg.not, label %loop.header, label %exit
83
84loop.header:                                      ; preds = %entry, %loop.latch
85  %iv = phi i16 [ %iv.next, %loop.latch ], [ 0, %entry ]
86  %c = icmp ne i16 %iv, %len
87  %t.2 = icmp ult i16 %iv, %a
88  %or.cond = and i1 %c, %t.2
89  br i1 %or.cond, label %loop.latch, label %exit
90
91loop.latch:                                       ; preds = %loop.header
92  call void @use(i16 %iv)
93  %iv.next = add nuw nsw i16 %iv, 1
94  br label %loop.header
95
96exit:                                             ; preds = %loop.header, %entry
97  ret void
98}
99
100define void @test_monotonic_ptr_iv_inc_2_eq_to_uge(i8 %len.n, i16 %a) {
101; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_eq_to_uge(
102; CHECK-NEXT:  entry:
103; CHECK-NEXT:    [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16
104; CHECK-NEXT:    [[LEN_LT:%.*]] = icmp ult i16 [[LEN]], [[A:%.*]]
105; CHECK-NEXT:    br i1 [[LEN_LT]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]]
106; CHECK:       loop.ph:
107; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
108; CHECK:       loop.header:
109; CHECK-NEXT:    [[IV:%.*]] = phi i16 [ 0, [[LOOP_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
110; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[IV]], [[LEN]]
111; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
112; CHECK:       for.body:
113; CHECK-NEXT:    [[T_2:%.*]] = icmp ult i16 [[IV]], [[A]]
114; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]
115; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
116; CHECK:       loop.latch:
117; CHECK-NEXT:    call void @use(i16 [[IV]])
118; CHECK-NEXT:    [[IV_NEXT]] = add nuw i16 [[IV]], 2
119; CHECK-NEXT:    br label [[LOOP_HEADER]]
120; CHECK:       exit:
121; CHECK-NEXT:    ret void
122;
123entry:
124  %len = zext i8 %len.n to i16
125  %len.lt = icmp ult i16 %len, %a
126  br i1 %len.lt, label %loop.ph, label %exit
127
128loop.ph:
129  br label %loop.header
130
131loop.header:
132  %iv = phi i16 [ 0, %loop.ph ], [ %iv.next, %loop.latch ]
133  %c = icmp eq i16 %iv, %len
134  br i1 %c, label %exit, label %for.body
135
136for.body:
137  %t.1 = icmp uge i16 %iv, 0
138  %t.2 = icmp ult i16 %iv, %a
139  %and = and i1 %t.1, %t.2
140  br i1 %and, label %loop.latch, label %exit
141
142loop.latch:
143  call void @use(i16 %iv)
144  %iv.next = add nuw i16 %iv, 2
145  br label %loop.header
146
147exit:
148  ret void
149}
150
151define void @test_monotonic_ptr_iv_inc_2_eq_to_uge_variable_start(i16 %start, i8 %len.n, i16 %a) {
152; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_eq_to_uge_variable_start(
153; CHECK-NEXT:  entry:
154; CHECK-NEXT:    [[LEN:%.*]] = zext i8 [[LEN_N:%.*]] to i16
155; CHECK-NEXT:    [[LEN_LT:%.*]] = icmp ult i16 [[LEN]], [[A:%.*]]
156; CHECK-NEXT:    [[START_LT:%.*]] = icmp ult i16 [[START:%.*]], [[LEN]]
157; CHECK-NEXT:    [[AND_0:%.*]] = and i1 [[LEN_LT]], [[START_LT]]
158; CHECK-NEXT:    br i1 [[AND_0]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]]
159; CHECK:       loop.ph:
160; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
161; CHECK:       loop.header:
162; CHECK-NEXT:    [[IV:%.*]] = phi i16 [ [[START]], [[LOOP_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
163; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[IV]], [[LEN]]
164; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
165; CHECK:       for.body:
166; CHECK-NEXT:    [[T_2:%.*]] = icmp ult i16 [[IV]], [[A]]
167; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]
168; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
169; CHECK:       loop.latch:
170; CHECK-NEXT:    call void @use(i16 [[IV]])
171; CHECK-NEXT:    [[IV_NEXT]] = add nuw i16 [[IV]], 2
172; CHECK-NEXT:    br label [[LOOP_HEADER]]
173; CHECK:       exit:
174; CHECK-NEXT:    ret void
175;
176entry:
177  %len = zext i8 %len.n to i16
178  %len.lt = icmp ult i16 %len, %a
179  %start.lt = icmp ult i16 %start, %len
180  %and.0 = and i1 %len.lt, %start.lt
181  br i1 %and.0, label %loop.ph, label %exit
182
183loop.ph:
184  br label %loop.header
185
186loop.header:
187  %iv = phi i16 [ %start, %loop.ph ], [ %iv.next, %loop.latch ]
188  %c = icmp eq i16 %iv, %len
189  br i1 %c, label %exit, label %for.body
190
191for.body:
192  %t.1 = icmp uge i16 %iv, 0
193  %t.2 = icmp ult i16 %iv, %a
194  %and = and i1 %t.1, %t.2
195  br i1 %and, label %loop.latch, label %exit
196
197loop.latch:
198  call void @use(i16 %iv)
199  %iv.next = add nuw i16 %iv, 2
200  br label %loop.header
201
202exit:
203  ret void
204}
205
206
207