1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=slp-vectorizer -mtriple=x86_64-- -S | FileCheck %s --check-prefixes=CHECK,SSE
3 ; RUN: opt < %s -passes=slp-vectorizer -mtriple=x86_64-- -mattr=avx512vl -S | FileCheck %s --check-prefixes=CHECK,AVX
7 define i1 @logical_and_icmp(<4 x i32> %x) {
8 ; CHECK-LABEL: @logical_and_icmp(
9 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], zeroinitializer
10 ; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]]
11 ; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]])
12 ; CHECK-NEXT: ret i1 [[TMP3]]
14 %x0 = extractelement <4 x i32> %x, i32 0
15 %x1 = extractelement <4 x i32> %x, i32 1
16 %x2 = extractelement <4 x i32> %x, i32 2
17 %x3 = extractelement <4 x i32> %x, i32 3
18 %c0 = icmp slt i32 %x0, 0
19 %c1 = icmp slt i32 %x1, 0
20 %c2 = icmp slt i32 %x2, 0
21 %c3 = icmp slt i32 %x3, 0
22 %s1 = select i1 %c0, i1 %c1, i1 false
23 %s2 = select i1 %s1, i1 %c2, i1 false
24 %s3 = select i1 %s2, i1 %c3, i1 false
28 define i1 @logical_or_icmp(<4 x i32> %x, <4 x i32> %y) {
29 ; CHECK-LABEL: @logical_or_icmp(
30 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], [[Y:%.*]]
31 ; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]]
32 ; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP2]])
33 ; CHECK-NEXT: ret i1 [[TMP3]]
35 %x0 = extractelement <4 x i32> %x, i32 0
36 %x1 = extractelement <4 x i32> %x, i32 1
37 %x2 = extractelement <4 x i32> %x, i32 2
38 %x3 = extractelement <4 x i32> %x, i32 3
39 %y0 = extractelement <4 x i32> %y, i32 0
40 %y1 = extractelement <4 x i32> %y, i32 1
41 %y2 = extractelement <4 x i32> %y, i32 2
42 %y3 = extractelement <4 x i32> %y, i32 3
43 %c0 = icmp slt i32 %x0, %y0
44 %c1 = icmp slt i32 %x1, %y1
45 %c2 = icmp slt i32 %x2, %y2
46 %c3 = icmp slt i32 %x3, %y3
47 %s1 = select i1 %c0, i1 true, i1 %c1
48 %s2 = select i1 %s1, i1 true, i1 %c2
49 %s3 = select i1 %s2, i1 true, i1 %c3
53 define i1 @logical_and_fcmp(<4 x float> %x) {
54 ; CHECK-LABEL: @logical_and_fcmp(
55 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt <4 x float> [[X:%.*]], zeroinitializer
56 ; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]]
57 ; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]])
58 ; CHECK-NEXT: ret i1 [[TMP3]]
60 %x0 = extractelement <4 x float> %x, i32 0
61 %x1 = extractelement <4 x float> %x, i32 1
62 %x2 = extractelement <4 x float> %x, i32 2
63 %x3 = extractelement <4 x float> %x, i32 3
64 %c0 = fcmp olt float %x0, 0.0
65 %c1 = fcmp olt float %x1, 0.0
66 %c2 = fcmp olt float %x2, 0.0
67 %c3 = fcmp olt float %x3, 0.0
68 %s1 = select i1 %c0, i1 %c1, i1 false
69 %s2 = select i1 %s1, i1 %c2, i1 false
70 %s3 = select i1 %s2, i1 %c3, i1 false
74 define i1 @logical_or_fcmp(<4 x float> %x) {
75 ; CHECK-LABEL: @logical_or_fcmp(
76 ; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt <4 x float> [[X:%.*]], zeroinitializer
77 ; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]]
78 ; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP2]])
79 ; CHECK-NEXT: ret i1 [[TMP3]]
81 %x0 = extractelement <4 x float> %x, i32 0
82 %x1 = extractelement <4 x float> %x, i32 1
83 %x2 = extractelement <4 x float> %x, i32 2
84 %x3 = extractelement <4 x float> %x, i32 3
85 %c0 = fcmp olt float %x0, 0.0
86 %c1 = fcmp olt float %x1, 0.0
87 %c2 = fcmp olt float %x2, 0.0
88 %c3 = fcmp olt float %x3, 0.0
89 %s1 = select i1 %c0, i1 true, i1 %c1
90 %s2 = select i1 %s1, i1 true, i1 %c2
91 %s3 = select i1 %s2, i1 true, i1 %c3
95 define i1 @logical_and_icmp_diff_preds(<4 x i32> %x) {
96 ; SSE-LABEL: @logical_and_icmp_diff_preds(
97 ; SSE-NEXT: [[X0:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 0
98 ; SSE-NEXT: [[X2:%.*]] = extractelement <4 x i32> [[X]], i32 2
99 ; SSE-NEXT: [[C0:%.*]] = icmp ult i32 [[X0]], 0
100 ; SSE-NEXT: [[C2:%.*]] = icmp sgt i32 [[X2]], 0
101 ; SSE-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> poison, <2 x i32> <i32 3, i32 1>
102 ; SSE-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> [[TMP1]], zeroinitializer
103 ; SSE-NEXT: [[TMP3:%.*]] = extractelement <2 x i1> [[TMP2]], i32 1
104 ; SSE-NEXT: [[S1:%.*]] = select i1 [[C0]], i1 [[TMP3]], i1 false
105 ; SSE-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 [[C2]], i1 false
106 ; SSE-NEXT: [[TMP4:%.*]] = extractelement <2 x i1> [[TMP2]], i32 0
107 ; SSE-NEXT: [[S3:%.*]] = select i1 [[S2]], i1 [[TMP4]], i1 false
108 ; SSE-NEXT: ret i1 [[S3]]
110 ; AVX-LABEL: @logical_and_icmp_diff_preds(
111 ; AVX-NEXT: [[X0:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 0
112 ; AVX-NEXT: [[X1:%.*]] = extractelement <4 x i32> [[X]], i32 1
113 ; AVX-NEXT: [[X2:%.*]] = extractelement <4 x i32> [[X]], i32 2
114 ; AVX-NEXT: [[X3:%.*]] = extractelement <4 x i32> [[X]], i32 3
115 ; AVX-NEXT: [[C0:%.*]] = icmp ult i32 [[X0]], 0
116 ; AVX-NEXT: [[C1:%.*]] = icmp slt i32 [[X1]], 0
117 ; AVX-NEXT: [[C2:%.*]] = icmp sgt i32 [[X2]], 0
118 ; AVX-NEXT: [[C3:%.*]] = icmp slt i32 [[X3]], 0
119 ; AVX-NEXT: [[S1:%.*]] = select i1 [[C0]], i1 [[C1]], i1 false
120 ; AVX-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 [[C2]], i1 false
121 ; AVX-NEXT: [[S3:%.*]] = select i1 [[S2]], i1 [[C3]], i1 false
122 ; AVX-NEXT: ret i1 [[S3]]
124 %x0 = extractelement <4 x i32> %x, i32 0
125 %x1 = extractelement <4 x i32> %x, i32 1
126 %x2 = extractelement <4 x i32> %x, i32 2
127 %x3 = extractelement <4 x i32> %x, i32 3
128 %c0 = icmp ult i32 %x0, 0
129 %c1 = icmp slt i32 %x1, 0
130 %c2 = icmp sgt i32 %x2, 0
131 %c3 = icmp slt i32 %x3, 0
132 %s1 = select i1 %c0, i1 %c1, i1 false
133 %s2 = select i1 %s1, i1 %c2, i1 false
134 %s3 = select i1 %s2, i1 %c3, i1 false
138 define i1 @logical_and_icmp_diff_const(<4 x i32> %x) {
139 ; CHECK-LABEL: @logical_and_icmp_diff_const(
140 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], <i32 0, i32 1, i32 2, i32 3>
141 ; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]]
142 ; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]])
143 ; CHECK-NEXT: ret i1 [[TMP3]]
145 %x0 = extractelement <4 x i32> %x, i32 0
146 %x1 = extractelement <4 x i32> %x, i32 1
147 %x2 = extractelement <4 x i32> %x, i32 2
148 %x3 = extractelement <4 x i32> %x, i32 3
149 %c0 = icmp sgt i32 %x0, 0
150 %c1 = icmp sgt i32 %x1, 1
151 %c2 = icmp sgt i32 %x2, 2
152 %c3 = icmp sgt i32 %x3, 3
153 %s1 = select i1 %c0, i1 %c1, i1 false
154 %s2 = select i1 %s1, i1 %c2, i1 false
155 %s3 = select i1 %s2, i1 %c3, i1 false
159 define i1 @mixed_logical_icmp(<4 x i32> %x) {
160 ; CHECK-LABEL: @mixed_logical_icmp(
161 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], zeroinitializer
162 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i32 0
163 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i1> [[TMP1]], i32 1
164 ; CHECK-NEXT: [[S1:%.*]] = select i1 [[TMP2]], i1 [[TMP3]], i1 false
165 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i1> [[TMP1]], i32 2
166 ; CHECK-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 true, i1 [[TMP4]]
167 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i1> [[TMP1]], i32 3
168 ; CHECK-NEXT: [[S3:%.*]] = select i1 [[S2]], i1 [[TMP5]], i1 false
169 ; CHECK-NEXT: ret i1 [[S3]]
171 %x0 = extractelement <4 x i32> %x, i32 0
172 %x1 = extractelement <4 x i32> %x, i32 1
173 %x2 = extractelement <4 x i32> %x, i32 2
174 %x3 = extractelement <4 x i32> %x, i32 3
175 %c0 = icmp sgt i32 %x0, 0
176 %c1 = icmp sgt i32 %x1, 0
177 %c2 = icmp sgt i32 %x2, 0
178 %c3 = icmp sgt i32 %x3, 0
179 %s1 = select i1 %c0, i1 %c1, i1 false
180 %s2 = select i1 %s1, i1 true, i1 %c2
181 %s3 = select i1 %s2, i1 %c3, i1 false
185 define i1 @logical_and_icmp_subvec(<4 x i32> %x) {
186 ; CHECK-LABEL: @logical_and_icmp_subvec(
187 ; CHECK-NEXT: [[X2:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 2
188 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> poison, <2 x i32> <i32 0, i32 1>
189 ; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> [[TMP1]], zeroinitializer
190 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[X2]], 0
191 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x i1> [[TMP2]], i32 0
192 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i1> [[TMP2]], i32 1
193 ; CHECK-NEXT: [[S1:%.*]] = select i1 [[TMP3]], i1 [[TMP4]], i1 false
194 ; CHECK-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 [[C2]], i1 false
195 ; CHECK-NEXT: ret i1 [[S2]]
197 %x0 = extractelement <4 x i32> %x, i32 0
198 %x1 = extractelement <4 x i32> %x, i32 1
199 %x2 = extractelement <4 x i32> %x, i32 2
200 %c0 = icmp slt i32 %x0, 0
201 %c1 = icmp slt i32 %x1, 0
202 %c2 = icmp slt i32 %x2, 0
203 %s1 = select i1 %c0, i1 %c1, i1 false
204 %s2 = select i1 %s1, i1 %c2, i1 false
208 ; TODO: This is better than all-scalar and still safe,
209 ; but we want this to be 2 reductions with glue
210 ; logic...or a wide reduction?
212 define i1 @logical_and_icmp_clamp(<4 x i32> %x) {
213 ; CHECK-LABEL: @logical_and_icmp_clamp(
214 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
215 ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <8 x i32> [[TMP1]], <i32 17, i32 17, i32 17, i32 17, i32 42, i32 42, i32 42, i32 42>
216 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt <8 x i32> [[TMP1]], <i32 17, i32 17, i32 17, i32 17, i32 42, i32 42, i32 42, i32 42>
217 ; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <8 x i1> [[TMP2]], <8 x i1> [[TMP3]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15>
218 ; CHECK-NEXT: [[TMP5:%.*]] = freeze <8 x i1> [[TMP4]]
219 ; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> [[TMP5]])
220 ; CHECK-NEXT: ret i1 [[TMP6]]
222 %x0 = extractelement <4 x i32> %x, i32 0
223 %x1 = extractelement <4 x i32> %x, i32 1
224 %x2 = extractelement <4 x i32> %x, i32 2
225 %x3 = extractelement <4 x i32> %x, i32 3
226 %c0 = icmp slt i32 %x0, 42
227 %c1 = icmp slt i32 %x1, 42
228 %c2 = icmp slt i32 %x2, 42
229 %c3 = icmp slt i32 %x3, 42
230 %d0 = icmp sgt i32 %x0, 17
231 %d1 = icmp sgt i32 %x1, 17
232 %d2 = icmp sgt i32 %x2, 17
233 %d3 = icmp sgt i32 %x3, 17
234 %s1 = select i1 %c0, i1 %c1, i1 false
235 %s2 = select i1 %s1, i1 %c2, i1 false
236 %s3 = select i1 %s2, i1 %c3, i1 false
237 %s4 = select i1 %s3, i1 %d0, i1 false
238 %s5 = select i1 %s4, i1 %d1, i1 false
239 %s6 = select i1 %s5, i1 %d2, i1 false
240 %s7 = select i1 %s6, i1 %d3, i1 false
244 define i1 @logical_and_icmp_clamp_extra_use_cmp(<4 x i32> %x) {
245 ; CHECK-LABEL: @logical_and_icmp_clamp_extra_use_cmp(
246 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
247 ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <8 x i32> [[TMP1]], <i32 17, i32 17, i32 17, i32 17, i32 42, i32 42, i32 42, i32 42>
248 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt <8 x i32> [[TMP1]], <i32 17, i32 17, i32 17, i32 17, i32 42, i32 42, i32 42, i32 42>
249 ; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <8 x i1> [[TMP2]], <8 x i1> [[TMP3]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15>
250 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <8 x i1> [[TMP4]], i32 6
251 ; CHECK-NEXT: call void @use1(i1 [[TMP5]])
252 ; CHECK-NEXT: [[TMP6:%.*]] = freeze <8 x i1> [[TMP4]]
253 ; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> [[TMP6]])
254 ; CHECK-NEXT: ret i1 [[TMP7]]
256 %x0 = extractelement <4 x i32> %x, i32 0
257 %x1 = extractelement <4 x i32> %x, i32 1
258 %x2 = extractelement <4 x i32> %x, i32 2
259 %x3 = extractelement <4 x i32> %x, i32 3
260 %c0 = icmp slt i32 %x0, 42
261 %c1 = icmp slt i32 %x1, 42
262 %c2 = icmp slt i32 %x2, 42
263 call void @use1(i1 %c2)
264 %c3 = icmp slt i32 %x3, 42
265 %d0 = icmp sgt i32 %x0, 17
266 %d1 = icmp sgt i32 %x1, 17
267 %d2 = icmp sgt i32 %x2, 17
268 %d3 = icmp sgt i32 %x3, 17
269 %s1 = select i1 %c0, i1 %c1, i1 false
270 %s2 = select i1 %s1, i1 %c2, i1 false
271 %s3 = select i1 %s2, i1 %c3, i1 false
272 %s4 = select i1 %s3, i1 %d0, i1 false
273 %s5 = select i1 %s4, i1 %d1, i1 false
274 %s6 = select i1 %s5, i1 %d2, i1 false
275 %s7 = select i1 %s6, i1 %d3, i1 false
279 define i1 @logical_and_icmp_clamp_extra_use_select(<4 x i32> %x) {
280 ; CHECK-LABEL: @logical_and_icmp_clamp_extra_use_select(
281 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], <i32 42, i32 42, i32 42, i32 42>
282 ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <4 x i32> [[X]], <i32 17, i32 17, i32 17, i32 17>
283 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i1> [[TMP1]], i32 0
284 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i1> [[TMP1]], i32 1
285 ; CHECK-NEXT: [[S1:%.*]] = select i1 [[TMP3]], i1 [[TMP4]], i1 false
286 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i1> [[TMP1]], i32 2
287 ; CHECK-NEXT: [[S2:%.*]] = select i1 [[S1]], i1 [[TMP5]], i1 false
288 ; CHECK-NEXT: call void @use1(i1 [[S2]])
289 ; CHECK-NEXT: [[TMP6:%.*]] = freeze <4 x i1> [[TMP2]]
290 ; CHECK-NEXT: [[TMP7:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP6]])
291 ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x i1> [[TMP1]], i32 3
292 ; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP7]], i1 [[TMP8]], i1 false
293 ; CHECK-NEXT: [[OP_RDX1:%.*]] = select i1 [[S2]], i1 [[OP_RDX]], i1 false
294 ; CHECK-NEXT: ret i1 [[OP_RDX1]]
296 %x0 = extractelement <4 x i32> %x, i32 0
297 %x1 = extractelement <4 x i32> %x, i32 1
298 %x2 = extractelement <4 x i32> %x, i32 2
299 %x3 = extractelement <4 x i32> %x, i32 3
300 %c0 = icmp slt i32 %x0, 42
301 %c1 = icmp slt i32 %x1, 42
302 %c2 = icmp slt i32 %x2, 42
303 %c3 = icmp slt i32 %x3, 42
304 %d0 = icmp sgt i32 %x0, 17
305 %d1 = icmp sgt i32 %x1, 17
306 %d2 = icmp sgt i32 %x2, 17
307 %d3 = icmp sgt i32 %x3, 17
308 %s1 = select i1 %c0, i1 %c1, i1 false
309 %s2 = select i1 %s1, i1 %c2, i1 false
310 call void @use1(i1 %s2)
311 %s3 = select i1 %s2, i1 %c3, i1 false
312 %s4 = select i1 %s3, i1 %d0, i1 false
313 %s5 = select i1 %s4, i1 %d1, i1 false
314 %s6 = select i1 %s5, i1 %d2, i1 false
315 %s7 = select i1 %s6, i1 %d3, i1 false
319 define i1 @logical_and_icmp_clamp_v8i32(<8 x i32> %x, <8 x i32> %y) {
320 ; CHECK-LABEL: @logical_and_icmp_clamp_v8i32(
321 ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x i32> [[X:%.*]], <8 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
322 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i32> [[Y:%.*]], <8 x i32> <i32 42, i32 42, i32 42, i32 42, i32 poison, i32 poison, i32 poison, i32 poison>, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 0, i32 1, i32 2, i32 3>
323 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt <8 x i32> [[TMP1]], [[TMP2]]
324 ; CHECK-NEXT: [[TMP4:%.*]] = freeze <8 x i1> [[TMP3]]
325 ; CHECK-NEXT: [[TMP5:%.*]] = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> [[TMP4]])
326 ; CHECK-NEXT: ret i1 [[TMP5]]
328 %x0 = extractelement <8 x i32> %x, i32 0
329 %x1 = extractelement <8 x i32> %x, i32 1
330 %x2 = extractelement <8 x i32> %x, i32 2
331 %x3 = extractelement <8 x i32> %x, i32 3
332 %y0 = extractelement <8 x i32> %y, i32 0
333 %y1 = extractelement <8 x i32> %y, i32 1
334 %y2 = extractelement <8 x i32> %y, i32 2
335 %y3 = extractelement <8 x i32> %y, i32 3
336 %c0 = icmp slt i32 %x0, 42
337 %c1 = icmp slt i32 %x1, 42
338 %c2 = icmp slt i32 %x2, 42
339 %c3 = icmp slt i32 %x3, 42
340 %d0 = icmp slt i32 %x0, %y0
341 %d1 = icmp slt i32 %x1, %y1
342 %d2 = icmp slt i32 %x2, %y2
343 %d3 = icmp slt i32 %x3, %y3
344 %s1 = select i1 %c0, i1 %c1, i1 false
345 %s2 = select i1 %s1, i1 %c2, i1 false
346 %s3 = select i1 %s2, i1 %c3, i1 false
347 %s4 = select i1 %s3, i1 %d0, i1 false
348 %s5 = select i1 %s4, i1 %d1, i1 false
349 %s6 = select i1 %s5, i1 %d2, i1 false
350 %s7 = select i1 %s6, i1 %d3, i1 false
354 define i1 @logical_and_icmp_clamp_partial(<4 x i32> %x) {
355 ; CHECK-LABEL: @logical_and_icmp_clamp_partial(
356 ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 2
357 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> poison, <2 x i32> <i32 0, i32 1>
358 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt <2 x i32> [[TMP2]], <i32 42, i32 42>
359 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[TMP1]], 42
360 ; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt <4 x i32> [[X]], <i32 17, i32 17, i32 17, i32 17>
361 ; CHECK-NEXT: [[TMP5:%.*]] = freeze <4 x i1> [[TMP4]]
362 ; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP5]])
363 ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i1> [[TMP3]], i32 1
364 ; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP6]], i1 [[TMP7]], i1 false
365 ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP3]], i32 0
366 ; CHECK-NEXT: [[OP_RDX1:%.*]] = select i1 [[TMP8]], i1 [[C2]], i1 false
367 ; CHECK-NEXT: [[TMP9:%.*]] = freeze i1 [[OP_RDX]]
368 ; CHECK-NEXT: [[OP_RDX2:%.*]] = select i1 [[TMP9]], i1 [[OP_RDX1]], i1 false
369 ; CHECK-NEXT: ret i1 [[OP_RDX2]]
371 %x0 = extractelement <4 x i32> %x, i32 0
372 %x1 = extractelement <4 x i32> %x, i32 1
373 %x2 = extractelement <4 x i32> %x, i32 2
374 %x3 = extractelement <4 x i32> %x, i32 3
375 %c0 = icmp slt i32 %x0, 42
376 %c1 = icmp slt i32 %x1, 42
377 %c2 = icmp slt i32 %x2, 42
378 ; remove an element from the previous test
379 %d0 = icmp sgt i32 %x0, 17
380 %d1 = icmp sgt i32 %x1, 17
381 %d2 = icmp sgt i32 %x2, 17
382 %d3 = icmp sgt i32 %x3, 17
383 %s1 = select i1 %c0, i1 %c1, i1 false
384 %s2 = select i1 %s1, i1 %c2, i1 false
385 ; remove an element from the previous test
386 %s4 = select i1 %s2, i1 %d0, i1 false
387 %s5 = select i1 %s4, i1 %d1, i1 false
388 %s6 = select i1 %s5, i1 %d2, i1 false
389 %s7 = select i1 %s6, i1 %d3, i1 false
393 define i1 @logical_and_icmp_clamp_pred_diff(<4 x i32> %x) {
394 ; CHECK-LABEL: @logical_and_icmp_clamp_pred_diff(
395 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], <i32 42, i32 42, i32 42, i32 42>
396 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult <4 x i32> [[X]], <i32 42, i32 42, i32 42, i32 42>
397 ; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i1> [[TMP1]], <4 x i1> [[TMP2]], <4 x i32> <i32 0, i32 1, i32 2, i32 7>
398 ; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt <4 x i32> [[X]], <i32 17, i32 17, i32 17, i32 17>
399 ; CHECK-NEXT: [[TMP5:%.*]] = freeze <4 x i1> [[TMP4]]
400 ; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP5]])
401 ; CHECK-NEXT: [[TMP7:%.*]] = freeze <4 x i1> [[TMP3]]
402 ; CHECK-NEXT: [[TMP8:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP7]])
403 ; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP6]], i1 [[TMP8]], i1 false
404 ; CHECK-NEXT: ret i1 [[OP_RDX]]
406 %x0 = extractelement <4 x i32> %x, i32 0
407 %x1 = extractelement <4 x i32> %x, i32 1
408 %x2 = extractelement <4 x i32> %x, i32 2
409 %x3 = extractelement <4 x i32> %x, i32 3
410 %c0 = icmp slt i32 %x0, 42
411 %c1 = icmp slt i32 %x1, 42
412 %c2 = icmp slt i32 %x2, 42
413 %c3 = icmp ult i32 %x3, 42 ; predicate changed
414 %d0 = icmp sgt i32 %x0, 17
415 %d1 = icmp sgt i32 %x1, 17
416 %d2 = icmp sgt i32 %x2, 17
417 %d3 = icmp sgt i32 %x3, 17
418 %s1 = select i1 %c0, i1 %c1, i1 false
419 %s2 = select i1 %s1, i1 %c2, i1 false
420 %s3 = select i1 %s2, i1 %c3, i1 false
421 %s4 = select i1 %s3, i1 %d0, i1 false
422 %s5 = select i1 %s4, i1 %d1, i1 false
423 %s6 = select i1 %s5, i1 %d2, i1 false
424 %s7 = select i1 %s6, i1 %d3, i1 false
428 define i1 @logical_and_icmp_extra_op(<4 x i32> %x, <4 x i32> %y, i1 %c) {
429 ; CHECK-LABEL: @logical_and_icmp_extra_op(
430 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], [[Y:%.*]]
431 ; CHECK-NEXT: [[S3:%.*]] = select i1 [[C:%.*]], i1 [[C]], i1 false
432 ; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]]
433 ; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]])
434 ; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[S3]], i1 [[TMP3]], i1 false
435 ; CHECK-NEXT: ret i1 [[OP_RDX]]
437 %x0 = extractelement <4 x i32> %x, i32 0
438 %x1 = extractelement <4 x i32> %x, i32 1
439 %x2 = extractelement <4 x i32> %x, i32 2
440 %x3 = extractelement <4 x i32> %x, i32 3
441 %y0 = extractelement <4 x i32> %y, i32 0
442 %y1 = extractelement <4 x i32> %y, i32 1
443 %y2 = extractelement <4 x i32> %y, i32 2
444 %y3 = extractelement <4 x i32> %y, i32 3
445 %d0 = icmp slt i32 %x0, %y0
446 %d1 = icmp slt i32 %x1, %y1
447 %d2 = icmp slt i32 %x2, %y2
448 %d3 = icmp slt i32 %x3, %y3
449 %s3 = select i1 %c, i1 %c, i1 false
450 %s4 = select i1 %s3, i1 %d0, i1 false
451 %s5 = select i1 %s4, i1 %d1, i1 false
452 %s6 = select i1 %s5, i1 %d2, i1 false
453 %s7 = select i1 %s6, i1 %d3, i1 false
457 define i1 @logical_or_icmp_extra_op(<4 x i32> %x, <4 x i32> %y, i1 %c) {
458 ; CHECK-LABEL: @logical_or_icmp_extra_op(
459 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <4 x i32> [[X:%.*]], [[Y:%.*]]
460 ; CHECK-NEXT: [[S3:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[C]]
461 ; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]]
462 ; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP2]])
463 ; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[S3]], i1 true, i1 [[TMP3]]
464 ; CHECK-NEXT: ret i1 [[OP_RDX]]
466 %x0 = extractelement <4 x i32> %x, i32 0
467 %x1 = extractelement <4 x i32> %x, i32 1
468 %x2 = extractelement <4 x i32> %x, i32 2
469 %x3 = extractelement <4 x i32> %x, i32 3
470 %y0 = extractelement <4 x i32> %y, i32 0
471 %y1 = extractelement <4 x i32> %y, i32 1
472 %y2 = extractelement <4 x i32> %y, i32 2
473 %y3 = extractelement <4 x i32> %y, i32 3
474 %d0 = icmp slt i32 %x0, %y0
475 %d1 = icmp slt i32 %x1, %y1
476 %d2 = icmp slt i32 %x2, %y2
477 %d3 = icmp slt i32 %x3, %y3
478 %s3 = select i1 %c, i1 true, i1 %c
479 %s4 = select i1 %s3, i1 true, i1 %d0
480 %s5 = select i1 %s4, i1 true, i1 %d1
481 %s6 = select i1 %s5, i1 true, i1 %d2
482 %s7 = select i1 %s6, i1 true, i1 %d3
486 define i1 @logical_and_icmp_extra_args(<4 x i32> %x, i1 %c0, i1 %c1, i1 %c2) {
487 ; CHECK-LABEL: @logical_and_icmp_extra_args(
488 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i32> [[X:%.*]], <i32 17, i32 17, i32 17, i32 17>
489 ; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]]
490 ; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP2]])
491 ; CHECK-NEXT: [[OP_RDX:%.*]] = select i1 [[TMP3]], i1 [[C0:%.*]], i1 false
492 ; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[C1:%.*]]
493 ; CHECK-NEXT: [[OP_RDX1:%.*]] = select i1 [[TMP4]], i1 [[C2:%.*]], i1 false
494 ; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[OP_RDX]]
495 ; CHECK-NEXT: [[OP_RDX2:%.*]] = select i1 [[TMP5]], i1 [[OP_RDX1]], i1 false
496 ; CHECK-NEXT: ret i1 [[OP_RDX2]]
498 %x0 = extractelement <4 x i32> %x, i32 0
499 %x1 = extractelement <4 x i32> %x, i32 1
500 %x2 = extractelement <4 x i32> %x, i32 2
501 %x3 = extractelement <4 x i32> %x, i32 3
502 %d0 = icmp sgt i32 %x0, 17
503 %d1 = icmp sgt i32 %x1, 17
504 %d2 = icmp sgt i32 %x2, 17
505 %d3 = icmp sgt i32 %x3, 17
506 %s1 = select i1 %d0, i1 %c0, i1 false ; <- d0, d1, d2, d3 gets reduced.
507 %s2 = select i1 %s1, i1 %c1, i1 false ; <- c0, c1, c2 remain scalar.
508 %s3 = select i1 %s2, i1 %c2, i1 false
509 %s5 = select i1 %s3, i1 %d1, i1 false
510 %s6 = select i1 %s5, i1 %d2, i1 false
511 %s7 = select i1 %s6, i1 %d3, i1 false