1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -slp-vectorizer -S %s | FileCheck %s
3; RUN: opt -aa-pipeline=basic-aa -passes='slp-vectorizer' -S %s | FileCheck %s
4
5target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
6target triple = "arm64-apple-ios5.0.0"
7
8define void @select_umin_8xi16(i16* %ptr, i16 %x) {
9; CHECK-LABEL: @select_umin_8xi16(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>*
12; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2
13; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
14; CHECK-NEXT:    [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
15; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>*
16; CHECK-NEXT:    store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2
17; CHECK-NEXT:    ret void
18;
19entry:
20  %l.0 = load i16, i16* %ptr
21  %cmp.0 = icmp ult i16 %l.0, 16383
22  %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383
23  store i16 %s.0, i16* %ptr, align 2
24
25  %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1
26  %l.1 = load i16, i16* %gep.1
27  %cmp.1 = icmp ult i16 %l.1, 16383
28  %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383
29  store i16 %s.1, i16* %gep.1, align 2
30
31  %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2
32  %l.2 = load i16, i16* %gep.2
33  %cmp.2 = icmp ult i16 %l.2, 16383
34  %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383
35  store i16 %s.2, i16* %gep.2, align 2
36
37  %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3
38  %l.3 = load i16, i16* %gep.3
39  %cmp.3 = icmp ult i16 %l.3, 16383
40  %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383
41  store i16 %s.3, i16* %gep.3, align 2
42
43  %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4
44  %l.4 = load i16, i16* %gep.4
45  %cmp.4 = icmp ult i16 %l.4, 16383
46  %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383
47  store i16 %s.4, i16* %gep.4, align 2
48
49  %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5
50  %l.5 = load i16, i16* %gep.5
51  %cmp.5 = icmp ult i16 %l.5, 16383
52  %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383
53  store i16 %s.5, i16* %gep.5, align 2
54
55  %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6
56  %l.6 = load i16, i16* %gep.6
57  %cmp.6 = icmp ult i16 %l.6, 16383
58  %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383
59  store i16 %s.6, i16* %gep.6, align 2
60
61  %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7
62  %l.7 = load i16, i16* %gep.7
63  %cmp.7 = icmp ult i16 %l.7, 16383
64  %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383
65  store i16 %s.7, i16* %gep.7, align 2
66  ret void
67}
68
69define void @select_umin_4xi32(i32* %ptr, i32 %x) {
70; CHECK-LABEL: @select_umin_4xi32(
71; CHECK-NEXT:  entry:
72; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>*
73; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
74; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383>
75; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383>
76; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>*
77; CHECK-NEXT:    store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4
78; CHECK-NEXT:    ret void
79;
80entry:
81  %l.0 = load i32, i32* %ptr
82  %cmp.0 = icmp ult i32 %l.0, 16383
83  %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383
84  store i32 %s.0, i32* %ptr, align 4
85
86  %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1
87  %l.1 = load i32, i32* %gep.1
88  %cmp.1 = icmp ult i32 %l.1, 16383
89  %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383
90  store i32 %s.1, i32* %gep.1, align 4
91
92  %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2
93  %l.2 = load i32, i32* %gep.2
94  %cmp.2 = icmp ult i32 %l.2, 16383
95  %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383
96  store i32 %s.2, i32* %gep.2, align 4
97
98  %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3
99  %l.3 = load i32, i32* %gep.3
100  %cmp.3 = icmp ult i32 %l.3, 16383
101  %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383
102  store i32 %s.3, i32* %gep.3, align 4
103
104  ret void
105}
106
107define void @select_ule_ugt_mix_4xi32(i32* %ptr, i32 %x) {
108; CHECK-LABEL: @select_ule_ugt_mix_4xi32(
109; CHECK-NEXT:  entry:
110; CHECK-NEXT:    [[L_0:%.*]] = load i32, i32* [[PTR:%.*]], align 4
111; CHECK-NEXT:    [[CMP_0:%.*]] = icmp ult i32 [[L_0]], 16383
112; CHECK-NEXT:    [[S_0:%.*]] = select i1 [[CMP_0]], i32 [[L_0]], i32 16383
113; CHECK-NEXT:    store i32 [[S_0]], i32* [[PTR]], align 4
114; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i32 1
115; CHECK-NEXT:    [[L_1:%.*]] = load i32, i32* [[GEP_1]], align 4
116; CHECK-NEXT:    [[CMP_1:%.*]] = icmp ugt i32 [[L_1]], 16383
117; CHECK-NEXT:    [[S_1:%.*]] = select i1 [[CMP_1]], i32 [[L_1]], i32 16383
118; CHECK-NEXT:    store i32 [[S_1]], i32* [[GEP_1]], align 4
119; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i32 2
120; CHECK-NEXT:    [[L_2:%.*]] = load i32, i32* [[GEP_2]], align 4
121; CHECK-NEXT:    [[CMP_2:%.*]] = icmp ult i32 [[L_2]], 16383
122; CHECK-NEXT:    [[S_2:%.*]] = select i1 [[CMP_2]], i32 [[L_2]], i32 16383
123; CHECK-NEXT:    store i32 [[S_2]], i32* [[GEP_2]], align 4
124; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i32 3
125; CHECK-NEXT:    [[L_3:%.*]] = load i32, i32* [[GEP_3]], align 4
126; CHECK-NEXT:    [[CMP_3:%.*]] = icmp ugt i32 [[L_3]], 16383
127; CHECK-NEXT:    [[S_3:%.*]] = select i1 [[CMP_3]], i32 [[L_3]], i32 16383
128; CHECK-NEXT:    store i32 [[S_3]], i32* [[GEP_3]], align 4
129; CHECK-NEXT:    ret void
130;
131entry:
132  %l.0 = load i32, i32* %ptr
133  %cmp.0 = icmp ult i32 %l.0, 16383
134  %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383
135  store i32 %s.0, i32* %ptr, align 4
136
137  %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1
138  %l.1 = load i32, i32* %gep.1
139  %cmp.1 = icmp ugt i32 %l.1, 16383
140  %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383
141  store i32 %s.1, i32* %gep.1, align 4
142
143  %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2
144  %l.2 = load i32, i32* %gep.2
145  %cmp.2 = icmp ult i32 %l.2, 16383
146  %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383
147  store i32 %s.2, i32* %gep.2, align 4
148
149  %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3
150  %l.3 = load i32, i32* %gep.3
151  %cmp.3 = icmp ugt i32 %l.3, 16383
152  %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383
153  store i32 %s.3, i32* %gep.3, align 4
154
155  ret void
156}
157
158; There is no <2 x i64> version of umin, but we can efficiently lower
159; compare/select pairs with uniform predicates.
160define void @select_umin_2xi64(i64* %ptr, i64 %x) {
161; CHECK-LABEL: @select_umin_2xi64(
162; CHECK-NEXT:  entry:
163; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>*
164; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8
165; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i64> [[TMP1]], <i64 16383, i64 16383>
166; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383>
167; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>*
168; CHECK-NEXT:    store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4
169; CHECK-NEXT:    ret void
170;
171entry:
172  %l.0 = load i64, i64* %ptr
173  %cmp.0 = icmp ult i64 %l.0, 16383
174  %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383
175  store i64 %s.0, i64* %ptr, align 4
176
177  %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1
178  %l.1 = load i64, i64* %gep.1
179  %cmp.1 = icmp ult i64 %l.1, 16383
180  %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383
181  store i64 %s.1, i64* %gep.1, align 4
182
183  ret void
184}
185
186
187define void @select_umin_ule_8xi16(i16* %ptr, i16 %x) {
188; CHECK-LABEL: @select_umin_ule_8xi16(
189; CHECK-NEXT:  entry:
190; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>*
191; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2
192; CHECK-NEXT:    [[TMP2:%.*]] = icmp ule <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
193; CHECK-NEXT:    [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
194; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>*
195; CHECK-NEXT:    store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2
196; CHECK-NEXT:    ret void
197;
198entry:
199  %l.0 = load i16, i16* %ptr
200  %cmp.0 = icmp ule i16 %l.0, 16383
201  %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383
202  store i16 %s.0, i16* %ptr, align 2
203
204  %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1
205  %l.1 = load i16, i16* %gep.1
206  %cmp.1 = icmp ule i16 %l.1, 16383
207  %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383
208  store i16 %s.1, i16* %gep.1, align 2
209
210  %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2
211  %l.2 = load i16, i16* %gep.2
212  %cmp.2 = icmp ule i16 %l.2, 16383
213  %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383
214  store i16 %s.2, i16* %gep.2, align 2
215
216  %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3
217  %l.3 = load i16, i16* %gep.3
218  %cmp.3 = icmp ule i16 %l.3, 16383
219  %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383
220  store i16 %s.3, i16* %gep.3, align 2
221
222  %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4
223  %l.4 = load i16, i16* %gep.4
224  %cmp.4 = icmp ule i16 %l.4, 16383
225  %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383
226  store i16 %s.4, i16* %gep.4, align 2
227
228  %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5
229  %l.5 = load i16, i16* %gep.5
230  %cmp.5 = icmp ule i16 %l.5, 16383
231  %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383
232  store i16 %s.5, i16* %gep.5, align 2
233
234  %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6
235  %l.6 = load i16, i16* %gep.6
236  %cmp.6 = icmp ule i16 %l.6, 16383
237  %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383
238  store i16 %s.6, i16* %gep.6, align 2
239
240  %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7
241  %l.7 = load i16, i16* %gep.7
242  %cmp.7 = icmp ule i16 %l.7, 16383
243  %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383
244  store i16 %s.7, i16* %gep.7, align 2
245  ret void
246}
247
248define void @select_umin_ule_4xi32(i32* %ptr, i32 %x) {
249; CHECK-LABEL: @select_umin_ule_4xi32(
250; CHECK-NEXT:  entry:
251; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>*
252; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
253; CHECK-NEXT:    [[TMP2:%.*]] = icmp ule <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383>
254; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383>
255; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>*
256; CHECK-NEXT:    store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4
257; CHECK-NEXT:    ret void
258;
259entry:
260  %l.0 = load i32, i32* %ptr
261  %cmp.0 = icmp ule i32 %l.0, 16383
262  %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383
263  store i32 %s.0, i32* %ptr, align 4
264
265  %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1
266  %l.1 = load i32, i32* %gep.1
267  %cmp.1 = icmp ule i32 %l.1, 16383
268  %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383
269  store i32 %s.1, i32* %gep.1, align 4
270
271  %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2
272  %l.2 = load i32, i32* %gep.2
273  %cmp.2 = icmp ule i32 %l.2, 16383
274  %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383
275  store i32 %s.2, i32* %gep.2, align 4
276
277  %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3
278  %l.3 = load i32, i32* %gep.3
279  %cmp.3 = icmp ule i32 %l.3, 16383
280  %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383
281  store i32 %s.3, i32* %gep.3, align 4
282
283  ret void
284}
285
286; There is no <2 x i64> version of umin, but we can efficiently lower
287; compare/select pairs with uniform predicates.
288define void @select_umin_ule_2xi64(i64* %ptr, i64 %x) {
289; CHECK-LABEL: @select_umin_ule_2xi64(
290; CHECK-NEXT:  entry:
291; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>*
292; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8
293; CHECK-NEXT:    [[TMP2:%.*]] = icmp ule <2 x i64> [[TMP1]], <i64 16383, i64 16383>
294; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383>
295; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>*
296; CHECK-NEXT:    store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4
297; CHECK-NEXT:    ret void
298;
299entry:
300  %l.0 = load i64, i64* %ptr
301  %cmp.0 = icmp ule i64 %l.0, 16383
302  %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383
303  store i64 %s.0, i64* %ptr, align 4
304
305  %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1
306  %l.1 = load i64, i64* %gep.1
307  %cmp.1 = icmp ule i64 %l.1, 16383
308  %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383
309  store i64 %s.1, i64* %gep.1, align 4
310
311  ret void
312}
313
314define void @select_smin_8xi16(i16* %ptr, i16 %x) {
315; CHECK-LABEL: @select_smin_8xi16(
316; CHECK-NEXT:  entry:
317; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>*
318; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2
319; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
320; CHECK-NEXT:    [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
321; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>*
322; CHECK-NEXT:    store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2
323; CHECK-NEXT:    ret void
324;
325entry:
326  %l.0 = load i16, i16* %ptr
327  %cmp.0 = icmp slt i16 %l.0, 16383
328  %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383
329  store i16 %s.0, i16* %ptr, align 2
330
331  %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1
332  %l.1 = load i16, i16* %gep.1
333  %cmp.1 = icmp slt i16 %l.1, 16383
334  %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383
335  store i16 %s.1, i16* %gep.1, align 2
336
337  %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2
338  %l.2 = load i16, i16* %gep.2
339  %cmp.2 = icmp slt i16 %l.2, 16383
340  %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383
341  store i16 %s.2, i16* %gep.2, align 2
342
343  %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3
344  %l.3 = load i16, i16* %gep.3
345  %cmp.3 = icmp slt i16 %l.3, 16383
346  %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383
347  store i16 %s.3, i16* %gep.3, align 2
348
349  %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4
350  %l.4 = load i16, i16* %gep.4
351  %cmp.4 = icmp slt i16 %l.4, 16383
352  %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383
353  store i16 %s.4, i16* %gep.4, align 2
354
355  %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5
356  %l.5 = load i16, i16* %gep.5
357  %cmp.5 = icmp slt i16 %l.5, 16383
358  %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383
359  store i16 %s.5, i16* %gep.5, align 2
360
361  %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6
362  %l.6 = load i16, i16* %gep.6
363  %cmp.6 = icmp slt i16 %l.6, 16383
364  %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383
365  store i16 %s.6, i16* %gep.6, align 2
366
367  %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7
368  %l.7 = load i16, i16* %gep.7
369  %cmp.7 = icmp slt i16 %l.7, 16383
370  %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383
371  store i16 %s.7, i16* %gep.7, align 2
372  ret void
373}
374
375define void @select_smin_4xi32(i32* %ptr, i32 %x) {
376; CHECK-LABEL: @select_smin_4xi32(
377; CHECK-NEXT:  entry:
378; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>*
379; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
380; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383>
381; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383>
382; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>*
383; CHECK-NEXT:    store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4
384; CHECK-NEXT:    ret void
385;
386entry:
387  %l.0 = load i32, i32* %ptr
388  %cmp.0 = icmp slt i32 %l.0, 16383
389  %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383
390  store i32 %s.0, i32* %ptr, align 4
391
392  %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1
393  %l.1 = load i32, i32* %gep.1
394  %cmp.1 = icmp slt i32 %l.1, 16383
395  %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383
396  store i32 %s.1, i32* %gep.1, align 4
397
398  %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2
399  %l.2 = load i32, i32* %gep.2
400  %cmp.2 = icmp slt i32 %l.2, 16383
401  %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383
402  store i32 %s.2, i32* %gep.2, align 4
403
404  %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3
405  %l.3 = load i32, i32* %gep.3
406  %cmp.3 = icmp slt i32 %l.3, 16383
407  %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383
408  store i32 %s.3, i32* %gep.3, align 4
409
410  ret void
411}
412
413; There is no <2 x i64> version of smin, but we can efficiently lower
414; compare/select pairs with uniform predicates.
415define void @select_smin_2xi64(i64* %ptr, i64 %x) {
416; CHECK-LABEL: @select_smin_2xi64(
417; CHECK-NEXT:  entry:
418; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>*
419; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8
420; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt <2 x i64> [[TMP1]], <i64 16383, i64 16383>
421; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383>
422; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>*
423; CHECK-NEXT:    store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4
424; CHECK-NEXT:    ret void
425;
426entry:
427  %l.0 = load i64, i64* %ptr
428  %cmp.0 = icmp slt i64 %l.0, 16383
429  %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383
430  store i64 %s.0, i64* %ptr, align 4
431
432  %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1
433  %l.1 = load i64, i64* %gep.1
434  %cmp.1 = icmp slt i64 %l.1, 16383
435  %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383
436  store i64 %s.1, i64* %gep.1, align 4
437
438  ret void
439}
440
441define void @select_smin_sle_8xi16(i16* %ptr, i16 %x) {
442; CHECK-LABEL: @select_smin_sle_8xi16(
443; CHECK-NEXT:  entry:
444; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>*
445; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2
446; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
447; CHECK-NEXT:    [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
448; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>*
449; CHECK-NEXT:    store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2
450; CHECK-NEXT:    ret void
451;
452entry:
453  %l.0 = load i16, i16* %ptr
454  %cmp.0 = icmp sle i16 %l.0, 16383
455  %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383
456  store i16 %s.0, i16* %ptr, align 2
457
458  %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1
459  %l.1 = load i16, i16* %gep.1
460  %cmp.1 = icmp sle i16 %l.1, 16383
461  %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383
462  store i16 %s.1, i16* %gep.1, align 2
463
464  %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2
465  %l.2 = load i16, i16* %gep.2
466  %cmp.2 = icmp sle i16 %l.2, 16383
467  %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383
468  store i16 %s.2, i16* %gep.2, align 2
469
470  %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3
471  %l.3 = load i16, i16* %gep.3
472  %cmp.3 = icmp sle i16 %l.3, 16383
473  %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383
474  store i16 %s.3, i16* %gep.3, align 2
475
476  %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4
477  %l.4 = load i16, i16* %gep.4
478  %cmp.4 = icmp sle i16 %l.4, 16383
479  %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383
480  store i16 %s.4, i16* %gep.4, align 2
481
482  %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5
483  %l.5 = load i16, i16* %gep.5
484  %cmp.5 = icmp sle i16 %l.5, 16383
485  %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383
486  store i16 %s.5, i16* %gep.5, align 2
487
488  %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6
489  %l.6 = load i16, i16* %gep.6
490  %cmp.6 = icmp sle i16 %l.6, 16383
491  %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383
492  store i16 %s.6, i16* %gep.6, align 2
493
494  %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7
495  %l.7 = load i16, i16* %gep.7
496  %cmp.7 = icmp sle i16 %l.7, 16383
497  %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383
498  store i16 %s.7, i16* %gep.7, align 2
499  ret void
500}
501
502define void @select_smin_sle_4xi32(i32* %ptr, i32 %x) {
503; CHECK-LABEL: @select_smin_sle_4xi32(
504; CHECK-NEXT:  entry:
505; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>*
506; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
507; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383>
508; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383>
509; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>*
510; CHECK-NEXT:    store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4
511; CHECK-NEXT:    ret void
512;
513entry:
514  %l.0 = load i32, i32* %ptr
515  %cmp.0 = icmp sle i32 %l.0, 16383
516  %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383
517  store i32 %s.0, i32* %ptr, align 4
518
519  %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1
520  %l.1 = load i32, i32* %gep.1
521  %cmp.1 = icmp sle i32 %l.1, 16383
522  %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383
523  store i32 %s.1, i32* %gep.1, align 4
524
525  %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2
526  %l.2 = load i32, i32* %gep.2
527  %cmp.2 = icmp sle i32 %l.2, 16383
528  %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383
529  store i32 %s.2, i32* %gep.2, align 4
530
531  %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3
532  %l.3 = load i32, i32* %gep.3
533  %cmp.3 = icmp sle i32 %l.3, 16383
534  %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383
535  store i32 %s.3, i32* %gep.3, align 4
536
537  ret void
538}
539
540; There is no <2 x i64> version of smin, but we can efficiently lower
541; compare/select pairs with uniform predicates.
542define void @select_smin_sle_2xi64(i64* %ptr, i64 %x) {
543; CHECK-LABEL: @select_smin_sle_2xi64(
544; CHECK-NEXT:  entry:
545; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>*
546; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8
547; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle <2 x i64> [[TMP1]], <i64 16383, i64 16383>
548; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383>
549; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>*
550; CHECK-NEXT:    store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4
551; CHECK-NEXT:    ret void
552;
553entry:
554  %l.0 = load i64, i64* %ptr
555  %cmp.0 = icmp sle i64 %l.0, 16383
556  %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383
557  store i64 %s.0, i64* %ptr, align 4
558
559  %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1
560  %l.1 = load i64, i64* %gep.1
561  %cmp.1 = icmp sle i64 %l.1, 16383
562  %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383
563  store i64 %s.1, i64* %gep.1, align 4
564
565  ret void
566}
567define void @select_umax_8xi16(i16* %ptr, i16 %x) {
568; CHECK-LABEL: @select_umax_8xi16(
569; CHECK-NEXT:  entry:
570; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>*
571; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2
572; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
573; CHECK-NEXT:    [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
574; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>*
575; CHECK-NEXT:    store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2
576; CHECK-NEXT:    ret void
577;
578entry:
579  %l.0 = load i16, i16* %ptr
580  %cmp.0 = icmp ugt i16 %l.0, 16383
581  %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383
582  store i16 %s.0, i16* %ptr, align 2
583
584  %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1
585  %l.1 = load i16, i16* %gep.1
586  %cmp.1 = icmp ugt i16 %l.1, 16383
587  %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383
588  store i16 %s.1, i16* %gep.1, align 2
589
590  %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2
591  %l.2 = load i16, i16* %gep.2
592  %cmp.2 = icmp ugt i16 %l.2, 16383
593  %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383
594  store i16 %s.2, i16* %gep.2, align 2
595
596  %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3
597  %l.3 = load i16, i16* %gep.3
598  %cmp.3 = icmp ugt i16 %l.3, 16383
599  %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383
600  store i16 %s.3, i16* %gep.3, align 2
601
602  %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4
603  %l.4 = load i16, i16* %gep.4
604  %cmp.4 = icmp ugt i16 %l.4, 16383
605  %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383
606  store i16 %s.4, i16* %gep.4, align 2
607
608  %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5
609  %l.5 = load i16, i16* %gep.5
610  %cmp.5 = icmp ugt i16 %l.5, 16383
611  %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383
612  store i16 %s.5, i16* %gep.5, align 2
613
614  %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6
615  %l.6 = load i16, i16* %gep.6
616  %cmp.6 = icmp ugt i16 %l.6, 16383
617  %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383
618  store i16 %s.6, i16* %gep.6, align 2
619
620  %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7
621  %l.7 = load i16, i16* %gep.7
622  %cmp.7 = icmp ugt i16 %l.7, 16383
623  %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383
624  store i16 %s.7, i16* %gep.7, align 2
625  ret void
626}
627
628define void @select_umax_4xi32(i32* %ptr, i32 %x) {
629; CHECK-LABEL: @select_umax_4xi32(
630; CHECK-NEXT:  entry:
631; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>*
632; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
633; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383>
634; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383>
635; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>*
636; CHECK-NEXT:    store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4
637; CHECK-NEXT:    ret void
638;
639entry:
640  %l.0 = load i32, i32* %ptr
641  %cmp.0 = icmp ugt i32 %l.0, 16383
642  %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383
643  store i32 %s.0, i32* %ptr, align 4
644
645  %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1
646  %l.1 = load i32, i32* %gep.1
647  %cmp.1 = icmp ugt i32 %l.1, 16383
648  %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383
649  store i32 %s.1, i32* %gep.1, align 4
650
651  %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2
652  %l.2 = load i32, i32* %gep.2
653  %cmp.2 = icmp ugt i32 %l.2, 16383
654  %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383
655  store i32 %s.2, i32* %gep.2, align 4
656
657  %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3
658  %l.3 = load i32, i32* %gep.3
659  %cmp.3 = icmp ugt i32 %l.3, 16383
660  %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383
661  store i32 %s.3, i32* %gep.3, align 4
662
663  ret void
664}
665
666; There is no <2 x i64> version of umax, but we can efficiently lower
667; compare/select pairs with uniform predicates.
668define void @select_umax_2xi64(i64* %ptr, i64 %x) {
669; CHECK-LABEL: @select_umax_2xi64(
670; CHECK-NEXT:  entry:
671; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>*
672; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8
673; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt <2 x i64> [[TMP1]], <i64 16383, i64 16383>
674; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383>
675; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>*
676; CHECK-NEXT:    store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4
677; CHECK-NEXT:    ret void
678;
679entry:
680  %l.0 = load i64, i64* %ptr
681  %cmp.0 = icmp ugt i64 %l.0, 16383
682  %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383
683  store i64 %s.0, i64* %ptr, align 4
684
685  %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1
686  %l.1 = load i64, i64* %gep.1
687  %cmp.1 = icmp ugt i64 %l.1, 16383
688  %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383
689  store i64 %s.1, i64* %gep.1, align 4
690
691  ret void
692}
693
694define void @select_umax_uge_8xi16(i16* %ptr, i16 %x) {
695; CHECK-LABEL: @select_umax_uge_8xi16(
696; CHECK-NEXT:  entry:
697; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>*
698; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2
699; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
700; CHECK-NEXT:    [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
701; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>*
702; CHECK-NEXT:    store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2
703; CHECK-NEXT:    ret void
704;
705entry:
706  %l.0 = load i16, i16* %ptr
707  %cmp.0 = icmp uge i16 %l.0, 16383
708  %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383
709  store i16 %s.0, i16* %ptr, align 2
710
711  %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1
712  %l.1 = load i16, i16* %gep.1
713  %cmp.1 = icmp uge i16 %l.1, 16383
714  %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383
715  store i16 %s.1, i16* %gep.1, align 2
716
717  %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2
718  %l.2 = load i16, i16* %gep.2
719  %cmp.2 = icmp uge i16 %l.2, 16383
720  %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383
721  store i16 %s.2, i16* %gep.2, align 2
722
723  %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3
724  %l.3 = load i16, i16* %gep.3
725  %cmp.3 = icmp uge i16 %l.3, 16383
726  %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383
727  store i16 %s.3, i16* %gep.3, align 2
728
729  %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4
730  %l.4 = load i16, i16* %gep.4
731  %cmp.4 = icmp uge i16 %l.4, 16383
732  %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383
733  store i16 %s.4, i16* %gep.4, align 2
734
735  %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5
736  %l.5 = load i16, i16* %gep.5
737  %cmp.5 = icmp uge i16 %l.5, 16383
738  %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383
739  store i16 %s.5, i16* %gep.5, align 2
740
741  %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6
742  %l.6 = load i16, i16* %gep.6
743  %cmp.6 = icmp uge i16 %l.6, 16383
744  %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383
745  store i16 %s.6, i16* %gep.6, align 2
746
747  %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7
748  %l.7 = load i16, i16* %gep.7
749  %cmp.7 = icmp uge i16 %l.7, 16383
750  %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383
751  store i16 %s.7, i16* %gep.7, align 2
752  ret void
753}
754
755define void @select_umax_uge_4xi32(i32* %ptr, i32 %x) {
756; CHECK-LABEL: @select_umax_uge_4xi32(
757; CHECK-NEXT:  entry:
758; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>*
759; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
760; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383>
761; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383>
762; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>*
763; CHECK-NEXT:    store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4
764; CHECK-NEXT:    ret void
765;
766entry:
767  %l.0 = load i32, i32* %ptr
768  %cmp.0 = icmp uge i32 %l.0, 16383
769  %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383
770  store i32 %s.0, i32* %ptr, align 4
771
772  %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1
773  %l.1 = load i32, i32* %gep.1
774  %cmp.1 = icmp uge i32 %l.1, 16383
775  %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383
776  store i32 %s.1, i32* %gep.1, align 4
777
778  %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2
779  %l.2 = load i32, i32* %gep.2
780  %cmp.2 = icmp uge i32 %l.2, 16383
781  %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383
782  store i32 %s.2, i32* %gep.2, align 4
783
784  %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3
785  %l.3 = load i32, i32* %gep.3
786  %cmp.3 = icmp uge i32 %l.3, 16383
787  %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383
788  store i32 %s.3, i32* %gep.3, align 4
789
790  ret void
791}
792
793; There is no <2 x i64> version of umax, but we can efficiently lower
794; compare/select pairs with uniform predicates.
795define void @select_umax_uge_2xi64(i64* %ptr, i64 %x) {
796; CHECK-LABEL: @select_umax_uge_2xi64(
797; CHECK-NEXT:  entry:
798; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>*
799; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8
800; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], <i64 16383, i64 16383>
801; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383>
802; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>*
803; CHECK-NEXT:    store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4
804; CHECK-NEXT:    ret void
805;
806entry:
807  %l.0 = load i64, i64* %ptr
808  %cmp.0 = icmp uge i64 %l.0, 16383
809  %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383
810  store i64 %s.0, i64* %ptr, align 4
811
812  %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1
813  %l.1 = load i64, i64* %gep.1
814  %cmp.1 = icmp uge i64 %l.1, 16383
815  %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383
816  store i64 %s.1, i64* %gep.1, align 4
817
818  ret void
819}
820
821define void @select_smax_8xi16(i16* %ptr, i16 %x) {
822; CHECK-LABEL: @select_smax_8xi16(
823; CHECK-NEXT:  entry:
824; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>*
825; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2
826; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
827; CHECK-NEXT:    [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
828; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>*
829; CHECK-NEXT:    store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2
830; CHECK-NEXT:    ret void
831;
832entry:
833  %l.0 = load i16, i16* %ptr
834  %cmp.0 = icmp sgt i16 %l.0, 16383
835  %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383
836  store i16 %s.0, i16* %ptr, align 2
837
838  %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1
839  %l.1 = load i16, i16* %gep.1
840  %cmp.1 = icmp sgt i16 %l.1, 16383
841  %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383
842  store i16 %s.1, i16* %gep.1, align 2
843
844  %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2
845  %l.2 = load i16, i16* %gep.2
846  %cmp.2 = icmp sgt i16 %l.2, 16383
847  %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383
848  store i16 %s.2, i16* %gep.2, align 2
849
850  %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3
851  %l.3 = load i16, i16* %gep.3
852  %cmp.3 = icmp sgt i16 %l.3, 16383
853  %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383
854  store i16 %s.3, i16* %gep.3, align 2
855
856  %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4
857  %l.4 = load i16, i16* %gep.4
858  %cmp.4 = icmp sgt i16 %l.4, 16383
859  %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383
860  store i16 %s.4, i16* %gep.4, align 2
861
862  %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5
863  %l.5 = load i16, i16* %gep.5
864  %cmp.5 = icmp sgt i16 %l.5, 16383
865  %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383
866  store i16 %s.5, i16* %gep.5, align 2
867
868  %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6
869  %l.6 = load i16, i16* %gep.6
870  %cmp.6 = icmp sgt i16 %l.6, 16383
871  %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383
872  store i16 %s.6, i16* %gep.6, align 2
873
874  %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7
875  %l.7 = load i16, i16* %gep.7
876  %cmp.7 = icmp sgt i16 %l.7, 16383
877  %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383
878  store i16 %s.7, i16* %gep.7, align 2
879  ret void
880}
881
882define void @select_smax_4xi32(i32* %ptr, i32 %x) {
883; CHECK-LABEL: @select_smax_4xi32(
884; CHECK-NEXT:  entry:
885; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>*
886; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
887; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383>
888; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383>
889; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>*
890; CHECK-NEXT:    store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4
891; CHECK-NEXT:    ret void
892;
893entry:
894  %l.0 = load i32, i32* %ptr
895  %cmp.0 = icmp sgt i32 %l.0, 16383
896  %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383
897  store i32 %s.0, i32* %ptr, align 4
898
899  %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1
900  %l.1 = load i32, i32* %gep.1
901  %cmp.1 = icmp sgt i32 %l.1, 16383
902  %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383
903  store i32 %s.1, i32* %gep.1, align 4
904
905  %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2
906  %l.2 = load i32, i32* %gep.2
907  %cmp.2 = icmp sgt i32 %l.2, 16383
908  %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383
909  store i32 %s.2, i32* %gep.2, align 4
910
911  %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3
912  %l.3 = load i32, i32* %gep.3
913  %cmp.3 = icmp sgt i32 %l.3, 16383
914  %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383
915  store i32 %s.3, i32* %gep.3, align 4
916
917  ret void
918}
919
920; There is no <2 x i64> version of smax, but we can efficiently lower
921; compare/select pairs with uniform predicates.
922define void @select_smax_2xi64(i64* %ptr, i64 %x) {
923; CHECK-LABEL: @select_smax_2xi64(
924; CHECK-NEXT:  entry:
925; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>*
926; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8
927; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i64> [[TMP1]], <i64 16383, i64 16383>
928; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383>
929; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>*
930; CHECK-NEXT:    store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4
931; CHECK-NEXT:    ret void
932;
933entry:
934  %l.0 = load i64, i64* %ptr
935  %cmp.0 = icmp sgt i64 %l.0, 16383
936  %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383
937  store i64 %s.0, i64* %ptr, align 4
938
939  %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1
940  %l.1 = load i64, i64* %gep.1
941  %cmp.1 = icmp sgt i64 %l.1, 16383
942  %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383
943  store i64 %s.1, i64* %gep.1, align 4
944
945  ret void
946}
947
948
949define void @select_smax_sge_8xi16(i16* %ptr, i16 %x) {
950; CHECK-LABEL: @select_smax_sge_8xi16(
951; CHECK-NEXT:  entry:
952; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i16* [[PTR:%.*]] to <8 x i16>*
953; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[TMP0]], align 2
954; CHECK-NEXT:    [[TMP2:%.*]] = icmp sge <8 x i16> [[TMP1]], <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
955; CHECK-NEXT:    [[TMP3:%.*]] = select <8 x i1> [[TMP2]], <8 x i16> [[TMP1]], <8 x i16> <i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383, i16 16383>
956; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16* [[PTR]] to <8 x i16>*
957; CHECK-NEXT:    store <8 x i16> [[TMP3]], <8 x i16>* [[TMP4]], align 2
958; CHECK-NEXT:    ret void
959;
960entry:
961  %l.0 = load i16, i16* %ptr
962  %cmp.0 = icmp sge i16 %l.0, 16383
963  %s.0 = select i1 %cmp.0, i16 %l.0, i16 16383
964  store i16 %s.0, i16* %ptr, align 2
965
966  %gep.1 = getelementptr inbounds i16, i16* %ptr, i16 1
967  %l.1 = load i16, i16* %gep.1
968  %cmp.1 = icmp sge i16 %l.1, 16383
969  %s.1 = select i1 %cmp.1, i16 %l.1, i16 16383
970  store i16 %s.1, i16* %gep.1, align 2
971
972  %gep.2 = getelementptr inbounds i16, i16* %ptr, i16 2
973  %l.2 = load i16, i16* %gep.2
974  %cmp.2 = icmp sge i16 %l.2, 16383
975  %s.2 = select i1 %cmp.2, i16 %l.2, i16 16383
976  store i16 %s.2, i16* %gep.2, align 2
977
978  %gep.3 = getelementptr inbounds i16, i16* %ptr, i16 3
979  %l.3 = load i16, i16* %gep.3
980  %cmp.3 = icmp sge i16 %l.3, 16383
981  %s.3 = select i1 %cmp.3, i16 %l.3, i16 16383
982  store i16 %s.3, i16* %gep.3, align 2
983
984  %gep.4 = getelementptr inbounds i16, i16* %ptr, i16 4
985  %l.4 = load i16, i16* %gep.4
986  %cmp.4 = icmp sge i16 %l.4, 16383
987  %s.4 = select i1 %cmp.4, i16 %l.4, i16 16383
988  store i16 %s.4, i16* %gep.4, align 2
989
990  %gep.5 = getelementptr inbounds i16, i16* %ptr, i16 5
991  %l.5 = load i16, i16* %gep.5
992  %cmp.5 = icmp sge i16 %l.5, 16383
993  %s.5 = select i1 %cmp.5, i16 %l.5, i16 16383
994  store i16 %s.5, i16* %gep.5, align 2
995
996  %gep.6 = getelementptr inbounds i16, i16* %ptr, i16 6
997  %l.6 = load i16, i16* %gep.6
998  %cmp.6 = icmp sge i16 %l.6, 16383
999  %s.6 = select i1 %cmp.6, i16 %l.6, i16 16383
1000  store i16 %s.6, i16* %gep.6, align 2
1001
1002  %gep.7 = getelementptr inbounds i16, i16* %ptr, i16 7
1003  %l.7 = load i16, i16* %gep.7
1004  %cmp.7 = icmp sge i16 %l.7, 16383
1005  %s.7 = select i1 %cmp.7, i16 %l.7, i16 16383
1006  store i16 %s.7, i16* %gep.7, align 2
1007  ret void
1008}
1009
1010define void @select_smax_sge_4xi32(i32* %ptr, i32 %x) {
1011; CHECK-LABEL: @select_smax_sge_4xi32(
1012; CHECK-NEXT:  entry:
1013; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to <4 x i32>*
1014; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
1015; CHECK-NEXT:    [[TMP2:%.*]] = icmp sge <4 x i32> [[TMP1]], <i32 16383, i32 16383, i32 16383, i32 16383>
1016; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[TMP1]], <4 x i32> <i32 16383, i32 16383, i32 16383, i32 16383>
1017; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[PTR]] to <4 x i32>*
1018; CHECK-NEXT:    store <4 x i32> [[TMP3]], <4 x i32>* [[TMP4]], align 4
1019; CHECK-NEXT:    ret void
1020;
1021entry:
1022  %l.0 = load i32, i32* %ptr
1023  %cmp.0 = icmp sge i32 %l.0, 16383
1024  %s.0 = select i1 %cmp.0, i32 %l.0, i32 16383
1025  store i32 %s.0, i32* %ptr, align 4
1026
1027  %gep.1 = getelementptr inbounds i32, i32* %ptr, i32 1
1028  %l.1 = load i32, i32* %gep.1
1029  %cmp.1 = icmp sge i32 %l.1, 16383
1030  %s.1 = select i1 %cmp.1, i32 %l.1, i32 16383
1031  store i32 %s.1, i32* %gep.1, align 4
1032
1033  %gep.2 = getelementptr inbounds i32, i32* %ptr, i32 2
1034  %l.2 = load i32, i32* %gep.2
1035  %cmp.2 = icmp sge i32 %l.2, 16383
1036  %s.2 = select i1 %cmp.2, i32 %l.2, i32 16383
1037  store i32 %s.2, i32* %gep.2, align 4
1038
1039  %gep.3 = getelementptr inbounds i32, i32* %ptr, i32 3
1040  %l.3 = load i32, i32* %gep.3
1041  %cmp.3 = icmp sge i32 %l.3, 16383
1042  %s.3 = select i1 %cmp.3, i32 %l.3, i32 16383
1043  store i32 %s.3, i32* %gep.3, align 4
1044
1045  ret void
1046}
1047
1048; There is no <2 x i64> version of smax, but we can efficiently lower
1049; compare/select pairs with uniform predicates.
1050define void @select_smax_sge_2xi64(i64* %ptr, i64 %x) {
1051; CHECK-LABEL: @select_smax_sge_2xi64(
1052; CHECK-NEXT:  entry:
1053; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i64* [[PTR:%.*]] to <2 x i64>*
1054; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[TMP0]], align 8
1055; CHECK-NEXT:    [[TMP2:%.*]] = icmp sge <2 x i64> [[TMP1]], <i64 16383, i64 16383>
1056; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i64> [[TMP1]], <2 x i64> <i64 16383, i64 16383>
1057; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i64* [[PTR]] to <2 x i64>*
1058; CHECK-NEXT:    store <2 x i64> [[TMP3]], <2 x i64>* [[TMP4]], align 4
1059; CHECK-NEXT:    ret void
1060;
1061entry:
1062  %l.0 = load i64, i64* %ptr
1063  %cmp.0 = icmp sge i64 %l.0, 16383
1064  %s.0 = select i1 %cmp.0, i64 %l.0, i64 16383
1065  store i64 %s.0, i64* %ptr, align 4
1066
1067  %gep.1 = getelementptr inbounds i64, i64* %ptr, i64 1
1068  %l.1 = load i64, i64* %gep.1
1069  %cmp.1 = icmp sge i64 %l.1, 16383
1070  %s.1 = select i1 %cmp.1, i64 %l.1, i64 16383
1071  store i64 %s.1, i64* %gep.1, align 4
1072
1073  ret void
1074}
1075