[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / monotonic-int-phis-decrement.ll
blob155423d33a69a8e456c441cd342bf47ff86dbc0b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2 ; RUN: opt -p constraint-elimination -S %s | FileCheck %s
4 declare void @use(i1)
5 declare void @llvm.assume(i1)
7 define void @add_rec_decreasing_cond_true_constant(i8 noundef %len) {
8 ; CHECK-LABEL: define void @add_rec_decreasing_cond_true_constant(
9 ; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
12 ; CHECK:       loop.header:
13 ; CHECK-NEXT:    [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
14 ; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
15 ; CHECK-NEXT:    br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
16 ; CHECK:       loop.latch:
17 ; CHECK-NEXT:    call void @use(i1 true)
18 ; CHECK-NEXT:    [[K_DEC]] = add i8 [[K_0]], -1
19 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
20 ; CHECK:       exit:
21 ; CHECK-NEXT:    ret void
23 entry:
24   br label %loop.header
26 loop.header:
27   %k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
28   %cmp2.not = icmp eq i8 %k.0, 0
29   br i1 %cmp2.not, label %exit, label %loop.latch
31 loop.latch:
32   %cmp.not.i = icmp ult i8 %k.0, 5
33   call void @use(i1 %cmp.not.i)
34   %k.dec = add i8 %k.0, -1
35   br label %loop.header
37 exit:
38   ret void
41 define void @add_rec_decreasing_cond_not_true_constant(i8 noundef %len) {
42 ; CHECK-LABEL: define void @add_rec_decreasing_cond_not_true_constant(
43 ; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
44 ; CHECK-NEXT:  entry:
45 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
46 ; CHECK:       loop.header:
47 ; CHECK-NEXT:    [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
48 ; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
49 ; CHECK-NEXT:    br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
50 ; CHECK:       loop.latch:
51 ; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 4
52 ; CHECK-NEXT:    call void @use(i1 [[CMP_NOT_I]])
53 ; CHECK-NEXT:    [[K_DEC]] = add i8 [[K_0]], -1
54 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
55 ; CHECK:       exit:
56 ; CHECK-NEXT:    ret void
58 entry:
59   br label %loop.header
61 loop.header:
62   %k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
63   %cmp2.not = icmp eq i8 %k.0, 0
64   br i1 %cmp2.not, label %exit, label %loop.latch
66 loop.latch:
67   %cmp.not.i = icmp ult i8 %k.0, 4
68   call void @use(i1 %cmp.not.i)
69   %k.dec = add i8 %k.0, -1
70   br label %loop.header
72 exit:
73   ret void
76 define void @add_rec_decreasing_cond_true_start_signed_positive(i8 noundef %start) {
77 ; CHECK-LABEL: define void @add_rec_decreasing_cond_true_start_signed_positive(
78 ; CHECK-SAME: i8 noundef [[START:%.*]]) {
79 ; CHECK-NEXT:  entry:
80 ; CHECK-NEXT:    [[PRECOND:%.*]] = icmp sge i8 [[START]], 1
81 ; CHECK-NEXT:    call void @llvm.assume(i1 [[PRECOND]])
82 ; CHECK-NEXT:    [[START_1:%.*]] = add i8 [[START]], -1
83 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
84 ; CHECK:       loop.header:
85 ; CHECK-NEXT:    [[K_0:%.*]] = phi i8 [ [[START_1]], [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
86 ; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
87 ; CHECK-NEXT:    br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
88 ; CHECK:       loop.latch:
89 ; CHECK-NEXT:    call void @use(i1 true)
90 ; CHECK-NEXT:    [[K_DEC]] = add i8 [[K_0]], -1
91 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
92 ; CHECK:       exit:
93 ; CHECK-NEXT:    ret void
95 entry:
96   %precond = icmp sge i8 %start, 1
97   call void @llvm.assume(i1 %precond)
98   %start.1 = add i8 %start, -1
99   br label %loop.header
101 loop.header:
102   %k.0 = phi i8 [ %start.1, %entry], [ %k.dec, %loop.latch ]
103   %cmp2.not = icmp eq i8 %k.0, 0
104   br i1 %cmp2.not, label %exit, label %loop.latch
106 loop.latch:
107   %cmp.not.i = icmp ult i8 %k.0, %start
108   call void @use(i1 %cmp.not.i)
109   %k.dec = add i8 %k.0, -1
110   br label %loop.header
112 exit:
113   ret void
116 define void @add_rec_decreasing_cond_not_true_start_signed_positive(i8 noundef %start) {
117 ; CHECK-LABEL: define void @add_rec_decreasing_cond_not_true_start_signed_positive(
118 ; CHECK-SAME: i8 noundef [[START:%.*]]) {
119 ; CHECK-NEXT:  entry:
120 ; CHECK-NEXT:    [[PRECOND:%.*]] = icmp sge i8 [[START]], 1
121 ; CHECK-NEXT:    call void @llvm.assume(i1 [[PRECOND]])
122 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
123 ; CHECK:       loop.header:
124 ; CHECK-NEXT:    [[K_0:%.*]] = phi i8 [ [[START]], [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
125 ; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
126 ; CHECK-NEXT:    br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
127 ; CHECK:       loop.latch:
128 ; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], [[START]]
129 ; CHECK-NEXT:    call void @use(i1 [[CMP_NOT_I]])
130 ; CHECK-NEXT:    [[K_DEC]] = add i8 [[K_0]], -1
131 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
132 ; CHECK:       exit:
133 ; CHECK-NEXT:    ret void
135 entry:
136   %precond = icmp sge i8 %start, 1
137   call void @llvm.assume(i1 %precond)
138   br label %loop.header
140 loop.header:
141   %k.0 = phi i8 [ %start, %entry], [ %k.dec, %loop.latch ]
142   %cmp2.not = icmp eq i8 %k.0, 0
143   br i1 %cmp2.not, label %exit, label %loop.latch
145 loop.latch:
146   %cmp.not.i = icmp ult i8 %k.0, %start
147   call void @use(i1 %cmp.not.i)
148   %k.dec = add i8 %k.0, -1
149   br label %loop.header
151 exit:
152   ret void
155 define void @add_rec_decreasing_add_rec_positive_to_negative(i8 noundef %len) {
156 ; CHECK-LABEL: define void @add_rec_decreasing_add_rec_positive_to_negative(
157 ; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
158 ; CHECK-NEXT:  entry:
159 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
160 ; CHECK:       loop.header:
161 ; CHECK-NEXT:    [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
162 ; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], -2
163 ; CHECK-NEXT:    br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
164 ; CHECK:       loop.latch:
165 ; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
166 ; CHECK-NEXT:    call void @use(i1 [[CMP_NOT_I]])
167 ; CHECK-NEXT:    [[K_DEC]] = add i8 [[K_0]], -1
168 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
169 ; CHECK:       exit:
170 ; CHECK-NEXT:    ret void
172 entry:
173   br label %loop.header
175 loop.header:
176   %k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
177   %cmp2.not = icmp eq i8 %k.0, -2
178   br i1 %cmp2.not, label %exit, label %loop.latch
180 loop.latch:
181   %cmp.not.i = icmp ult i8 %k.0, 5
182   call void @use(i1 %cmp.not.i)
183   %k.dec = add i8 %k.0, -1
184   br label %loop.header
186 exit:
187   ret void
190 define void @add_rec_decreasing_2_cond_true_constant(i8 noundef %len) {
191 ; CHECK-LABEL: define void @add_rec_decreasing_2_cond_true_constant(
192 ; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
193 ; CHECK-NEXT:  entry:
194 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
195 ; CHECK:       loop.header:
196 ; CHECK-NEXT:    [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
197 ; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
198 ; CHECK-NEXT:    br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
199 ; CHECK:       loop.latch:
200 ; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
201 ; CHECK-NEXT:    call void @use(i1 [[CMP_NOT_I]])
202 ; CHECK-NEXT:    [[K_DEC]] = add i8 [[K_0]], -2
203 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
204 ; CHECK:       exit:
205 ; CHECK-NEXT:    ret void
207 entry:
208   br label %loop.header
210 loop.header:
211   %k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
212   %cmp2.not = icmp eq i8 %k.0, 0
213   br i1 %cmp2.not, label %exit, label %loop.latch
215 loop.latch:
216   %cmp.not.i = icmp ult i8 %k.0, 5
217   call void @use(i1 %cmp.not.i)
218   %k.dec = add i8 %k.0, -2
219   br label %loop.header
221 exit:
222   ret void
225 define void @add_rec_decreasing_2_cond_not_true_constant(i8 noundef %len) {
226 ; CHECK-LABEL: define void @add_rec_decreasing_2_cond_not_true_constant(
227 ; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
228 ; CHECK-NEXT:  entry:
229 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
230 ; CHECK:       loop.header:
231 ; CHECK-NEXT:    [[K_0:%.*]] = phi i8 [ 5, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
232 ; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
233 ; CHECK-NEXT:    br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
234 ; CHECK:       loop.latch:
235 ; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
236 ; CHECK-NEXT:    call void @use(i1 [[CMP_NOT_I]])
237 ; CHECK-NEXT:    [[K_DEC]] = add i8 [[K_0]], -2
238 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
239 ; CHECK:       exit:
240 ; CHECK-NEXT:    ret void
242 entry:
243   br label %loop.header
245 loop.header:
246   %k.0 = phi i8 [ 5, %entry], [ %k.dec, %loop.latch ]
247   %cmp2.not = icmp eq i8 %k.0, 0
248   br i1 %cmp2.not, label %exit, label %loop.latch
250 loop.latch:
251   %cmp.not.i = icmp ult i8 %k.0, 5
252   call void @use(i1 %cmp.not.i)
253   %k.dec = add i8 %k.0, -2
254   br label %loop.header
256 exit:
257   ret void