[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / CorrelatedValuePropagation / vectors.ll
blob7060b4244d98851f3997d9116b8b17adfc1c6aa6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt -S -passes=correlated-propagation < %s | FileCheck %s
4 define <2 x i1> @cmp1(<2 x i8> %a) {
5 ; CHECK-LABEL: define <2 x i1> @cmp1(
6 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
7 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i8> [[A]], splat (i8 1)
8 ; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
10   %add = add nuw <2 x i8> %a, splat (i8 1)
11   %cmp = icmp ne <2 x i8> %add, zeroinitializer
12   ret <2 x i1> %cmp
15 define <2 x i1> @cmp2(<2 x i8> %a) {
16 ; CHECK-LABEL: define <2 x i1> @cmp2(
17 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
18 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i8> [[A]], splat (i8 5)
19 ; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
21   %add = add nuw <2 x i8> %a, splat (i8 5)
22   %cmp = icmp ugt <2 x i8> %add, splat (i8 2)
23   ret <2 x i1> %cmp
26 define <2 x i1> @cmp_nonsplat(<2 x i8> %a) {
27 ; CHECK-LABEL: define <2 x i1> @cmp_nonsplat(
28 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
29 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i8> [[A]], <i8 4, i8 5>
30 ; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
32   %add = add nuw <2 x i8> %a, <i8 4, i8 5>
33   %cmp = icmp ugt <2 x i8> %add, <i8 2, i8 3>
34   ret <2 x i1> %cmp
37 ; Handling this would require keeping track of ranges on a per-element basis.
38 define <2 x i1> @cmp_nonsplat_fail(<2 x i8> %a) {
39 ; CHECK-LABEL: define <2 x i1> @cmp_nonsplat_fail(
40 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
41 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i8> [[A]], <i8 3, i8 4>
42 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i8> [[ADD]], <i8 2, i8 3>
43 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
45   %add = add nuw <2 x i8> %a, <i8 3, i8 4>
46   %cmp = icmp ugt <2 x i8> %add, <i8 2, i8 3>
47   ret <2 x i1> %cmp
50 define <2 x i1> @cmp_signedness(<2 x i8> %a) {
51 ; CHECK-LABEL: define <2 x i1> @cmp_signedness(
52 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
53 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
54 ; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult <2 x i16> [[ZEXT]], splat (i16 5)
55 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
57   %zext = zext <2 x i8> %a to <2 x i16>
58   %cmp = icmp slt <2 x i16> %zext, splat (i16 5)
59   ret <2 x i1> %cmp
62 define <2 x i16> @infer_nowrap(<2 x i8> %a) {
63 ; CHECK-LABEL: define range(i16 1, 257) <2 x i16> @infer_nowrap(
64 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
65 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
66 ; CHECK-NEXT:    [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], splat (i16 1)
67 ; CHECK-NEXT:    ret <2 x i16> [[RES]]
69   %zext = zext <2 x i8> %a to <2 x i16>
70   %res = add <2 x i16> %zext, splat (i16 1)
71   ret <2 x i16> %res
74 define <2 x i16> @infer_nowrap_nonsplat(<2 x i8> %a) {
75 ; CHECK-LABEL: define range(i16 1, 258) <2 x i16> @infer_nowrap_nonsplat(
76 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
77 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
78 ; CHECK-NEXT:    [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], <i16 1, i16 2>
79 ; CHECK-NEXT:    ret <2 x i16> [[RES]]
81   %zext = zext <2 x i8> %a to <2 x i16>
82   %res = add <2 x i16> %zext, <i16 1, i16 2>
83   ret <2 x i16> %res
86 define <vscale x 2 x i16> @infer_nowrap_scalable(<vscale x 2 x i8> %a) {
87 ; CHECK-LABEL: define range(i16 1, 257) <vscale x 2 x i16> @infer_nowrap_scalable(
88 ; CHECK-SAME: <vscale x 2 x i8> [[A:%.*]]) {
89 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <vscale x 2 x i8> [[A]] to <vscale x 2 x i16>
90 ; CHECK-NEXT:    [[RES:%.*]] = add nuw nsw <vscale x 2 x i16> [[ZEXT]], shufflevector (<vscale x 2 x i16> insertelement (<vscale x 2 x i16> poison, i16 1, i64 0), <vscale x 2 x i16> poison, <vscale x 2 x i32> zeroinitializer)
91 ; CHECK-NEXT:    ret <vscale x 2 x i16> [[RES]]
93   %zext = zext <vscale x 2 x i8> %a to <vscale x 2 x i16>
94   %res = add <vscale x 2 x i16> %zext, splat (i16 1)
95   ret <vscale x 2 x i16> %res
98 define <2 x i16> @infer_nowrap_poison(<2 x i8> %a) {
99 ; CHECK-LABEL: define range(i16 1, 257) <2 x i16> @infer_nowrap_poison(
100 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
101 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
102 ; CHECK-NEXT:    [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], <i16 1, i16 poison>
103 ; CHECK-NEXT:    ret <2 x i16> [[RES]]
105   %zext = zext <2 x i8> %a to <2 x i16>
106   %res = add <2 x i16> %zext, <i16 1, i16 poison>
107   ret <2 x i16> %res
110 define <2 x i16> @infer_nowrap_nonsplat_nsw_only(<2 x i8> %a) {
111 ; CHECK-LABEL: define range(i16 -1, 257) <2 x i16> @infer_nowrap_nonsplat_nsw_only(
112 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
113 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
114 ; CHECK-NEXT:    [[RES:%.*]] = add nsw <2 x i16> [[ZEXT]], <i16 1, i16 -1>
115 ; CHECK-NEXT:    ret <2 x i16> [[RES]]
117   %zext = zext <2 x i8> %a to <2 x i16>
118   %res = add <2 x i16> %zext, <i16 1, i16 -1>
119   ret <2 x i16> %res
122 define <2 x i16> @abs(<2 x i8> %a) {
123 ; CHECK-LABEL: define range(i16 0, 256) <2 x i16> @abs(
124 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
125 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
126 ; CHECK-NEXT:    ret <2 x i16> [[ZEXT]]
128   %zext = zext <2 x i8> %a to <2 x i16>
129   %res = call <2 x i16> @llvm.abs(<2 x i16> %zext, i1 false)
130   ret <2 x i16> %res
133 define <2 x i16> @saturating(<2 x i8> %a) {
134 ; CHECK-LABEL: define range(i16 1, 257) <2 x i16> @saturating(
135 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
136 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
137 ; CHECK-NEXT:    [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], splat (i16 1)
138 ; CHECK-NEXT:    ret <2 x i16> [[RES]]
140   %zext = zext <2 x i8> %a to <2 x i16>
141   %res = call <2 x i16> @llvm.uadd.sat(<2 x i16> %zext, <2 x i16> splat (i16 1))
142   ret <2 x i16> %res
145 define {<2 x i16>, <2 x i1>} @with_overflow(<2 x i8> %a) {
146 ; CHECK-LABEL: define { <2 x i16>, <2 x i1> } @with_overflow(
147 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
148 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
149 ; CHECK-NEXT:    [[RES1:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], splat (i16 1)
150 ; CHECK-NEXT:    [[RES:%.*]] = insertvalue { <2 x i16>, <2 x i1> } { <2 x i16> poison, <2 x i1> zeroinitializer }, <2 x i16> [[RES1]], 0
151 ; CHECK-NEXT:    ret { <2 x i16>, <2 x i1> } [[RES]]
153   %zext = zext <2 x i8> %a to <2 x i16>
154   %res = call {<2 x i16>, <2 x i1>} @llvm.uadd.with.overflow(<2 x i16> %zext, <2 x i16> splat (i16 1))
155   ret {<2 x i16>, <2 x i1>} %res
158 define <2 x i16> @srem1(<2 x i8> %a) {
159 ; CHECK-LABEL: define range(i16 0, 42) <2 x i16> @srem1(
160 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
161 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
162 ; CHECK-NEXT:    [[RES1_LHS_TRUNC:%.*]] = trunc <2 x i16> [[ZEXT]] to <2 x i8>
163 ; CHECK-NEXT:    [[RES12:%.*]] = urem <2 x i8> [[RES1_LHS_TRUNC]], splat (i8 42)
164 ; CHECK-NEXT:    [[RES:%.*]] = zext <2 x i8> [[RES12]] to <2 x i16>
165 ; CHECK-NEXT:    ret <2 x i16> [[RES]]
167   %zext = zext <2 x i8> %a to <2 x i16>
168   %res = srem <2 x i16> %zext, splat (i16 42)
169   ret <2 x i16> %res
172 define <2 x i16> @srem2(<2 x i8> %a) {
173 ; CHECK-LABEL: define range(i16 -41, 42) <2 x i16> @srem2(
174 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
175 ; CHECK-NEXT:    [[ZEXT:%.*]] = sext <2 x i8> [[A]] to <2 x i16>
176 ; CHECK-NEXT:    [[RES_LHS_TRUNC:%.*]] = trunc <2 x i16> [[ZEXT]] to <2 x i8>
177 ; CHECK-NEXT:    [[RES1:%.*]] = srem <2 x i8> [[RES_LHS_TRUNC]], splat (i8 42)
178 ; CHECK-NEXT:    [[RES:%.*]] = sext <2 x i8> [[RES1]] to <2 x i16>
179 ; CHECK-NEXT:    ret <2 x i16> [[RES]]
181   %zext = sext <2 x i8> %a to <2 x i16>
182   %res = srem <2 x i16> %zext, splat (i16 42)
183   ret <2 x i16> %res
186 define <2 x i16> @ashr(<2 x i8> %a) {
187 ; CHECK-LABEL: define range(i16 0, 128) <2 x i16> @ashr(
188 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
189 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
190 ; CHECK-NEXT:    [[RES:%.*]] = lshr <2 x i16> [[ZEXT]], splat (i16 1)
191 ; CHECK-NEXT:    ret <2 x i16> [[RES]]
193   %zext = zext <2 x i8> %a to <2 x i16>
194   %res = ashr <2 x i16> %zext, splat (i16 1)
195   ret <2 x i16> %res
198 define <2 x i32> @sext(<2 x i8> %a) {
199 ; CHECK-LABEL: define range(i32 0, 256) <2 x i32> @sext(
200 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
201 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
202 ; CHECK-NEXT:    [[RES:%.*]] = zext nneg <2 x i16> [[ZEXT]] to <2 x i32>
203 ; CHECK-NEXT:    ret <2 x i32> [[RES]]
205   %zext = zext <2 x i8> %a to <2 x i16>
206   %res = sext <2 x i16> %zext to <2 x i32>
207   ret <2 x i32> %res
210 define <2 x float> @sitofp(<2 x i8> %a) {
211 ; CHECK-LABEL: define <2 x float> @sitofp(
212 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
213 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
214 ; CHECK-NEXT:    [[RES:%.*]] = uitofp nneg <2 x i16> [[ZEXT]] to <2 x float>
215 ; CHECK-NEXT:    ret <2 x float> [[RES]]
217   %zext = zext <2 x i8> %a to <2 x i16>
218   %res = sitofp <2 x i16> %zext to <2 x float>
219   ret <2 x float> %res
222 define <2 x i16> @and(<2 x i8> %a) {
223 ; CHECK-LABEL: define range(i16 0, 256) <2 x i16> @and(
224 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
225 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
226 ; CHECK-NEXT:    ret <2 x i16> [[ZEXT]]
228   %zext = zext <2 x i8> %a to <2 x i16>
229   %res = and <2 x i16> %zext, splat (i16 u0xff)
230   ret <2 x i16> %res
233 define <2 x i16> @and_with_poison(<2 x i8> %a) {
234 ; CHECK-LABEL: define range(i16 0, 256) <2 x i16> @and_with_poison(
235 ; CHECK-SAME: <2 x i8> [[A:%.*]]) {
236 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
237 ; CHECK-NEXT:    ret <2 x i16> [[ZEXT]]
239   %zext = zext <2 x i8> %a to <2 x i16>
240   %res = and <2 x i16> %zext, <i16 u0xff, i16 poison>
241   ret <2 x i16> %res
244 define <4 x i64> @issue_97674_getConstantOnEdge(i1 %cond) {
245 ; CHECK-LABEL: define range(i64 0, 2) <4 x i64> @issue_97674_getConstantOnEdge(
246 ; CHECK-SAME: i1 [[COND:%.*]]) {
247 ; CHECK-NEXT:  [[ENTRY:.*]]:
248 ; CHECK-NEXT:    br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
249 ; CHECK:       [[IF_THEN]]:
250 ; CHECK-NEXT:    [[FOLDS:%.*]] = add nuw nsw <4 x i64> zeroinitializer, splat (i64 1)
251 ; CHECK-NEXT:    br label %[[IF_END]]
252 ; CHECK:       [[IF_END]]:
253 ; CHECK-NEXT:    [[R:%.*]] = phi <4 x i64> [ splat (i64 1), %[[IF_THEN]] ], [ zeroinitializer, %[[ENTRY]] ]
254 ; CHECK-NEXT:    ret <4 x i64> [[R]]
256 entry:
257   br i1 %cond, label %if.then, label %if.end
259 if.then:
260   %folds = add <4 x i64> zeroinitializer, <i64 1, i64 1, i64 1, i64 1>
261   br label %if.end
263 if.end:
264   %r = phi <4 x i64> [ %folds, %if.then ], [ zeroinitializer, %entry ]
265   ret <4 x i64> %r
268 define <4 x i64> @issue_97674_getConstant() {
269 ; CHECK-LABEL: define <4 x i64> @issue_97674_getConstant() {
270 ; CHECK-NEXT:  [[ENTRY:.*:]]
271 ; CHECK-NEXT:    [[FOLDS:%.*]] = add nuw nsw <4 x i64> zeroinitializer, zeroinitializer
272 ; CHECK-NEXT:    ret <4 x i64> zeroinitializer
274 entry:
275   %folds = add <4 x i64> zeroinitializer, zeroinitializer
276   ret <4 x i64> %folds
279 define <2 x i16> @phi_merge1(i1 %c, <2 x i8> %a) {
280 ; CHECK-LABEL: define range(i16 2, 259) <2 x i16> @phi_merge1(
281 ; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]]) {
282 ; CHECK-NEXT:  [[ENTRY:.*]]:
283 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
284 ; CHECK-NEXT:    br i1 [[C]], label %[[IF:.*]], label %[[JOIN:.*]]
285 ; CHECK:       [[IF]]:
286 ; CHECK-NEXT:    br label %[[JOIN]]
287 ; CHECK:       [[JOIN]]:
288 ; CHECK-NEXT:    [[PHI:%.*]] = phi <2 x i16> [ [[ZEXT]], %[[ENTRY]] ], [ <i16 1, i16 2>, %[[IF]] ]
289 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw <2 x i16> [[PHI]], <i16 2, i16 3>
290 ; CHECK-NEXT:    ret <2 x i16> [[ADD]]
292 entry:
293   %zext = zext <2 x i8> %a to <2 x i16>
294   br i1 %c, label %if, label %join
297   br label %join
299 join:
300   %phi = phi <2 x i16> [ %zext, %entry ], [ <i16 1, i16 2>, %if ]
301   %add = add <2 x i16> %phi, <i16 2, i16 3>
302   ret <2 x i16> %add
305 define <2 x i16> @phi_merge2(i1 %c, <2 x i8> %a) {
306 ; CHECK-LABEL: define range(i16 2, 259) <2 x i16> @phi_merge2(
307 ; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]]) {
308 ; CHECK-NEXT:  [[ENTRY:.*]]:
309 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
310 ; CHECK-NEXT:    br i1 [[C]], label %[[IF:.*]], label %[[JOIN:.*]]
311 ; CHECK:       [[IF]]:
312 ; CHECK-NEXT:    br label %[[JOIN]]
313 ; CHECK:       [[JOIN]]:
314 ; CHECK-NEXT:    [[PHI:%.*]] = phi <2 x i16> [ <i16 1, i16 2>, %[[ENTRY]] ], [ [[ZEXT]], %[[IF]] ]
315 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw <2 x i16> [[PHI]], <i16 2, i16 3>
316 ; CHECK-NEXT:    ret <2 x i16> [[ADD]]
318 entry:
319   %zext = zext <2 x i8> %a to <2 x i16>
320   br i1 %c, label %if, label %join
323   br label %join
325 join:
326   %phi = phi <2 x i16> [ <i16 1, i16 2>, %entry ], [ %zext, %if ]
327   %add = add <2 x i16> %phi, <i16 2, i16 3>
328   ret <2 x i16> %add
331 ;; Check if ICMP instruction is constant folded or not.
332 define <2 x i1> @insertelement_fold1() {
333 ; CHECK-LABEL: define <2 x i1> @insertelement_fold1() {
334 ; CHECK-NEXT:    [[IE1:%.*]] = insertelement <2 x i32> poison, i32 10, i64 0
335 ; CHECK-NEXT:    [[IE2:%.*]] = insertelement <2 x i32> [[IE1]], i32 20, i64 1
336 ; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
338   %ie1 = insertelement <2 x i32> poison, i32 10, i64 0
339   %ie2 = insertelement <2 x i32> %ie1, i32 20, i64 1
340   %icmp1 = icmp slt <2 x i32> %ie2, <i32 1024, i32 1024>
341   ret <2 x i1> %icmp1
344 ;; Check if LVI is able to handle constant vector operands
345 ;; in InsertElementInst and CVP is able to fold ICMP instruction.
346 define <2 x i1> @insertelement_fold2() {
347 ; CHECK-LABEL: define <2 x i1> @insertelement_fold2() {
348 ; CHECK-NEXT:    [[IE1:%.*]] = insertelement <2 x i32> <i32 poison, i32 20>, i32 10, i64 0
349 ; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
351   %ie1 = insertelement <2 x i32> <i32 poison, i32 20>, i32 10, i64 0
352   %icmp1 = icmp slt <2 x i32> %ie1, <i32 1024, i32 1024>
353   ret <2 x i1> %icmp1