xref: /llvm-project/llvm/test/Transforms/LoopVectorize/reduction-inloop-min-max.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
1cc398664SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2cc398664SFlorian Hahn; RUN: opt < %s -passes=loop-vectorize,dce,instcombine -force-vector-interleave=1 -force-vector-width=4 -prefer-inloop-reductions -S | FileCheck %s
3cc398664SFlorian Hahn
4cc398664SFlorian Hahndefine i32 @reduction_smin(ptr nocapture %A, ptr nocapture %B) {
5cc398664SFlorian Hahn; CHECK-LABEL: define i32 @reduction_smin
6*29441e4fSNikita Popov; CHECK-SAME: (ptr captures(none) [[A:%.*]], ptr captures(none) [[B:%.*]]) {
7cc398664SFlorian Hahn; CHECK-NEXT:  entry:
8cc398664SFlorian Hahn; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
9cc398664SFlorian Hahn; CHECK:       vector.ph:
10cc398664SFlorian Hahn; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
11cc398664SFlorian Hahn; CHECK:       vector.body:
12cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
13cc398664SFlorian Hahn; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 1000, [[VECTOR_PH]] ], [ [[RDX_MINMAX:%.*]], [[VECTOR_BODY]] ]
14cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]
15cc398664SFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
16cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> [[WIDE_LOAD]])
17cc398664SFlorian Hahn; CHECK-NEXT:    [[RDX_MINMAX]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 [[VEC_PHI]])
18cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
19cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
20cc398664SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
21cc398664SFlorian Hahn; CHECK:       middle.block:
22cc398664SFlorian Hahn; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
23cc398664SFlorian Hahn; CHECK:       scalar.ph:
24cc398664SFlorian Hahn; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
25cc398664SFlorian Hahn; CHECK:       for.body:
26cc398664SFlorian Hahn; CHECK-NEXT:    br i1 poison, label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
27cc398664SFlorian Hahn; CHECK:       for.end:
28cc398664SFlorian Hahn; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[RDX_MINMAX]], [[MIDDLE_BLOCK]] ]
29cc398664SFlorian Hahn; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
30cc398664SFlorian Hahn;
31cc398664SFlorian Hahnentry:
32cc398664SFlorian Hahn  br label %for.body
33cc398664SFlorian Hahn
34cc398664SFlorian Hahnfor.body:                                         ; preds = %entry, %for.body
35cc398664SFlorian Hahn  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
36cc398664SFlorian Hahn  %result.08 = phi i32 [ %v0, %for.body ], [ 1000, %entry ]
37cc398664SFlorian Hahn  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
38cc398664SFlorian Hahn  %l0 = load i32, ptr %arrayidx, align 4
39cc398664SFlorian Hahn  %c0 = icmp slt i32 %result.08, %l0
40cc398664SFlorian Hahn  %v0 = select i1 %c0, i32 %result.08, i32 %l0
41cc398664SFlorian Hahn  %indvars.iv.next = add i64 %indvars.iv, 1
42cc398664SFlorian Hahn  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
43cc398664SFlorian Hahn  %exitcond = icmp eq i32 %lftr.wideiv, 256
44cc398664SFlorian Hahn  br i1 %exitcond, label %for.end, label %for.body
45cc398664SFlorian Hahn
46cc398664SFlorian Hahnfor.end:                                          ; preds = %for.body, %entry
47cc398664SFlorian Hahn  %result.0.lcssa = phi i32 [ %v0, %for.body ]
48cc398664SFlorian Hahn  ret i32 %result.0.lcssa
49cc398664SFlorian Hahn}
50cc398664SFlorian Hahn
51cc398664SFlorian Hahndefine i32 @reduction_smin_select_ops_flipped(ptr nocapture %A, ptr nocapture %B) {
52cc398664SFlorian Hahn; CHECK-LABEL: define i32 @reduction_smin_select_ops_flipped
53*29441e4fSNikita Popov; CHECK-SAME: (ptr captures(none) [[A:%.*]], ptr captures(none) [[B:%.*]]) {
54cc398664SFlorian Hahn; CHECK-NEXT:  entry:
55cc398664SFlorian Hahn; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
56cc398664SFlorian Hahn; CHECK:       vector.ph:
57cc398664SFlorian Hahn; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
58cc398664SFlorian Hahn; CHECK:       vector.body:
59cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
60cc398664SFlorian Hahn; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 1000, [[VECTOR_PH]] ], [ [[RDX_MINMAX:%.*]], [[VECTOR_BODY]] ]
61cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]
62cc398664SFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
63cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> [[WIDE_LOAD]])
64cc398664SFlorian Hahn; CHECK-NEXT:    [[RDX_MINMAX]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 [[VEC_PHI]])
65cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
66cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
67cc398664SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
68cc398664SFlorian Hahn; CHECK:       middle.block:
69cc398664SFlorian Hahn; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
70cc398664SFlorian Hahn; CHECK:       scalar.ph:
71cc398664SFlorian Hahn; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
72cc398664SFlorian Hahn; CHECK:       for.body:
73cc398664SFlorian Hahn; CHECK-NEXT:    br i1 poison, label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
74cc398664SFlorian Hahn; CHECK:       for.end:
75cc398664SFlorian Hahn; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[RDX_MINMAX]], [[MIDDLE_BLOCK]] ]
76cc398664SFlorian Hahn; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
77cc398664SFlorian Hahn;
78cc398664SFlorian Hahnentry:
79cc398664SFlorian Hahn  br label %for.body
80cc398664SFlorian Hahn
81cc398664SFlorian Hahnfor.body:                                         ; preds = %entry, %for.body
82cc398664SFlorian Hahn  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
83cc398664SFlorian Hahn  %result.08 = phi i32 [ %v0, %for.body ], [ 1000, %entry ]
84cc398664SFlorian Hahn  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
85cc398664SFlorian Hahn  %l0 = load i32, ptr %arrayidx, align 4
86cc398664SFlorian Hahn  %c0 = icmp slt i32 %result.08, %l0
87cc398664SFlorian Hahn  %v0 = select i1 %c0, i32 %l0, i32 %result.08
88cc398664SFlorian Hahn  %indvars.iv.next = add i64 %indvars.iv, 1
89cc398664SFlorian Hahn  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
90cc398664SFlorian Hahn  %exitcond = icmp eq i32 %lftr.wideiv, 256
91cc398664SFlorian Hahn  br i1 %exitcond, label %for.end, label %for.body
92cc398664SFlorian Hahn
93cc398664SFlorian Hahnfor.end:                                          ; preds = %for.body, %entry
94cc398664SFlorian Hahn  %result.0.lcssa = phi i32 [ %v0, %for.body ]
95cc398664SFlorian Hahn  ret i32 %result.0.lcssa
96cc398664SFlorian Hahn}
97cc398664SFlorian Hahn
98cc398664SFlorian Hahndefine i32 @reduction_smin_intrinsic(ptr nocapture %A, ptr nocapture %B) {
99cc398664SFlorian Hahn; CHECK-LABEL: define i32 @reduction_smin_intrinsic
100*29441e4fSNikita Popov; CHECK-SAME: (ptr captures(none) [[A:%.*]], ptr captures(none) [[B:%.*]]) {
101cc398664SFlorian Hahn; CHECK-NEXT:  entry:
102cc398664SFlorian Hahn; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
103cc398664SFlorian Hahn; CHECK:       vector.ph:
104cc398664SFlorian Hahn; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
105cc398664SFlorian Hahn; CHECK:       vector.body:
106cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
10738fffa63SPaul Walker; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ splat (i32 1000), [[VECTOR_PH]] ], [ [[TMP1:%.*]], [[VECTOR_BODY]] ]
108cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]
109cc398664SFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
110cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP1]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[VEC_PHI]], <4 x i32> [[WIDE_LOAD]])
111cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
112cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
113cc398664SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
114cc398664SFlorian Hahn; CHECK:       middle.block:
115cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> [[TMP1]])
116cc398664SFlorian Hahn; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
117cc398664SFlorian Hahn; CHECK:       scalar.ph:
118cc398664SFlorian Hahn; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
119cc398664SFlorian Hahn; CHECK:       for.body:
120cc398664SFlorian Hahn; CHECK-NEXT:    br i1 poison, label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
121cc398664SFlorian Hahn; CHECK:       for.end:
122cc398664SFlorian Hahn; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[TMP3]], [[MIDDLE_BLOCK]] ]
123cc398664SFlorian Hahn; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
124cc398664SFlorian Hahn;
125cc398664SFlorian Hahnentry:
126cc398664SFlorian Hahn  br label %for.body
127cc398664SFlorian Hahn
128cc398664SFlorian Hahnfor.body:                                         ; preds = %entry, %for.body
129cc398664SFlorian Hahn  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
130cc398664SFlorian Hahn  %result.08 = phi i32 [ %v0, %for.body ], [ 1000, %entry ]
131cc398664SFlorian Hahn  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
132cc398664SFlorian Hahn  %l0 = load i32, ptr %arrayidx, align 4
133cc398664SFlorian Hahn  %v0 = call i32 @llvm.smin.i32(i32 %result.08, i32 %l0)
134cc398664SFlorian Hahn  %indvars.iv.next = add i64 %indvars.iv, 1
135cc398664SFlorian Hahn  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
136cc398664SFlorian Hahn  %exitcond = icmp eq i32 %lftr.wideiv, 256
137cc398664SFlorian Hahn  br i1 %exitcond, label %for.end, label %for.body
138cc398664SFlorian Hahn
139cc398664SFlorian Hahnfor.end:                                          ; preds = %for.body, %entry
140cc398664SFlorian Hahn  %result.0.lcssa = phi i32 [ %v0, %for.body ]
141cc398664SFlorian Hahn  ret i32 %result.0.lcssa
142cc398664SFlorian Hahn}
143cc398664SFlorian Hahn
144cc398664SFlorian Hahndeclare i32 @llvm.smin.i32(i32, i32)
145cc398664SFlorian Hahn
146cc398664SFlorian Hahndefine i32 @reduction_umax(ptr nocapture %A, ptr nocapture %B) {
147cc398664SFlorian Hahn; CHECK-LABEL: define i32 @reduction_umax
148*29441e4fSNikita Popov; CHECK-SAME: (ptr captures(none) [[A:%.*]], ptr captures(none) [[B:%.*]]) {
149cc398664SFlorian Hahn; CHECK-NEXT:  entry:
150cc398664SFlorian Hahn; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
151cc398664SFlorian Hahn; CHECK:       vector.ph:
152cc398664SFlorian Hahn; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
153cc398664SFlorian Hahn; CHECK:       vector.body:
154cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
155cc398664SFlorian Hahn; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 1000, [[VECTOR_PH]] ], [ [[RDX_MINMAX:%.*]], [[VECTOR_BODY]] ]
156cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]
157cc398664SFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
158cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[WIDE_LOAD]])
159cc398664SFlorian Hahn; CHECK-NEXT:    [[RDX_MINMAX]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 [[VEC_PHI]])
160cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
161cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
162cc398664SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
163cc398664SFlorian Hahn; CHECK:       middle.block:
164cc398664SFlorian Hahn; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
165cc398664SFlorian Hahn; CHECK:       scalar.ph:
166cc398664SFlorian Hahn; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
167cc398664SFlorian Hahn; CHECK:       for.body:
168cc398664SFlorian Hahn; CHECK-NEXT:    br i1 poison, label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]]
169cc398664SFlorian Hahn; CHECK:       for.end:
170cc398664SFlorian Hahn; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[RDX_MINMAX]], [[MIDDLE_BLOCK]] ]
171cc398664SFlorian Hahn; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
172cc398664SFlorian Hahn;
173cc398664SFlorian Hahnentry:
174cc398664SFlorian Hahn  br label %for.body
175cc398664SFlorian Hahn
176cc398664SFlorian Hahnfor.body:                                         ; preds = %entry, %for.body
177cc398664SFlorian Hahn  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
178cc398664SFlorian Hahn  %result.08 = phi i32 [ %v0, %for.body ], [ 1000, %entry ]
179cc398664SFlorian Hahn  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
180cc398664SFlorian Hahn  %l0 = load i32, ptr %arrayidx, align 4
181cc398664SFlorian Hahn  %c0 = icmp ugt i32 %result.08, %l0
182cc398664SFlorian Hahn  %v0 = select i1 %c0, i32 %result.08, i32 %l0
183cc398664SFlorian Hahn  %indvars.iv.next = add i64 %indvars.iv, 1
184cc398664SFlorian Hahn  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
185cc398664SFlorian Hahn  %exitcond = icmp eq i32 %lftr.wideiv, 256
186cc398664SFlorian Hahn  br i1 %exitcond, label %for.end, label %for.body
187cc398664SFlorian Hahn
188cc398664SFlorian Hahnfor.end:                                          ; preds = %for.body, %entry
189cc398664SFlorian Hahn  %result.0.lcssa = phi i32 [ %v0, %for.body ]
190cc398664SFlorian Hahn  ret i32 %result.0.lcssa
191cc398664SFlorian Hahn}
192cc398664SFlorian Hahn
193cc398664SFlorian Hahndefine i32 @reduction_umax_select_ops_flipped(ptr nocapture %A, ptr nocapture %B) {
194cc398664SFlorian Hahn; CHECK-LABEL: define i32 @reduction_umax_select_ops_flipped
195*29441e4fSNikita Popov; CHECK-SAME: (ptr captures(none) [[A:%.*]], ptr captures(none) [[B:%.*]]) {
196cc398664SFlorian Hahn; CHECK-NEXT:  entry:
197cc398664SFlorian Hahn; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
198cc398664SFlorian Hahn; CHECK:       vector.ph:
199cc398664SFlorian Hahn; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
200cc398664SFlorian Hahn; CHECK:       vector.body:
201cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
202cc398664SFlorian Hahn; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi i32 [ 1000, [[VECTOR_PH]] ], [ [[RDX_MINMAX:%.*]], [[VECTOR_BODY]] ]
203cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]
204cc398664SFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
205cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> [[WIDE_LOAD]])
206cc398664SFlorian Hahn; CHECK-NEXT:    [[RDX_MINMAX]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 [[VEC_PHI]])
207cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
208cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
209cc398664SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
210cc398664SFlorian Hahn; CHECK:       middle.block:
211cc398664SFlorian Hahn; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
212cc398664SFlorian Hahn; CHECK:       scalar.ph:
213cc398664SFlorian Hahn; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
214cc398664SFlorian Hahn; CHECK:       for.body:
215cc398664SFlorian Hahn; CHECK-NEXT:    br i1 poison, label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]]
216cc398664SFlorian Hahn; CHECK:       for.end:
217cc398664SFlorian Hahn; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[RDX_MINMAX]], [[MIDDLE_BLOCK]] ]
218cc398664SFlorian Hahn; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
219cc398664SFlorian Hahn;
220cc398664SFlorian Hahnentry:
221cc398664SFlorian Hahn  br label %for.body
222cc398664SFlorian Hahn
223cc398664SFlorian Hahnfor.body:                                         ; preds = %entry, %for.body
224cc398664SFlorian Hahn  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
225cc398664SFlorian Hahn  %result.08 = phi i32 [ %v0, %for.body ], [ 1000, %entry ]
226cc398664SFlorian Hahn  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
227cc398664SFlorian Hahn  %l0 = load i32, ptr %arrayidx, align 4
228cc398664SFlorian Hahn  %c0 = icmp ugt i32 %result.08, %l0
229cc398664SFlorian Hahn  %v0 = select i1 %c0, i32 %l0, i32 %result.08
230cc398664SFlorian Hahn  %indvars.iv.next = add i64 %indvars.iv, 1
231cc398664SFlorian Hahn  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
232cc398664SFlorian Hahn  %exitcond = icmp eq i32 %lftr.wideiv, 256
233cc398664SFlorian Hahn  br i1 %exitcond, label %for.end, label %for.body
234cc398664SFlorian Hahn
235cc398664SFlorian Hahnfor.end:                                          ; preds = %for.body, %entry
236cc398664SFlorian Hahn  %result.0.lcssa = phi i32 [ %v0, %for.body ]
237cc398664SFlorian Hahn  ret i32 %result.0.lcssa
238cc398664SFlorian Hahn}
239cc398664SFlorian Hahn
240cc398664SFlorian Hahndefine i32 @reduction_umax_intrinsic(ptr nocapture %A, ptr nocapture %B) {
241cc398664SFlorian Hahn; CHECK-LABEL: define i32 @reduction_umax_intrinsic
242*29441e4fSNikita Popov; CHECK-SAME: (ptr captures(none) [[A:%.*]], ptr captures(none) [[B:%.*]]) {
243cc398664SFlorian Hahn; CHECK-NEXT:  entry:
244cc398664SFlorian Hahn; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
245cc398664SFlorian Hahn; CHECK:       vector.ph:
246cc398664SFlorian Hahn; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
247cc398664SFlorian Hahn; CHECK:       vector.body:
248cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
24938fffa63SPaul Walker; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ splat (i32 1000), [[VECTOR_PH]] ], [ [[TMP1:%.*]], [[VECTOR_BODY]] ]
250cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDEX]]
251cc398664SFlorian Hahn; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP0]], align 4
252cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP1]] = call <4 x i32> @llvm.umax.v4i32(<4 x i32> [[VEC_PHI]], <4 x i32> [[WIDE_LOAD]])
253cc398664SFlorian Hahn; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
254cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
255cc398664SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP2]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
256cc398664SFlorian Hahn; CHECK:       middle.block:
257cc398664SFlorian Hahn; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[TMP1]])
258cc398664SFlorian Hahn; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
259cc398664SFlorian Hahn; CHECK:       scalar.ph:
260cc398664SFlorian Hahn; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
261cc398664SFlorian Hahn; CHECK:       for.body:
262cc398664SFlorian Hahn; CHECK-NEXT:    br i1 poison, label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP13:![0-9]+]]
263cc398664SFlorian Hahn; CHECK:       for.end:
264cc398664SFlorian Hahn; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ poison, [[FOR_BODY]] ], [ [[TMP3]], [[MIDDLE_BLOCK]] ]
265cc398664SFlorian Hahn; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
266cc398664SFlorian Hahn;
267cc398664SFlorian Hahnentry:
268cc398664SFlorian Hahn  br label %for.body
269cc398664SFlorian Hahn
270cc398664SFlorian Hahnfor.body:                                         ; preds = %entry, %for.body
271cc398664SFlorian Hahn  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
272cc398664SFlorian Hahn  %result.08 = phi i32 [ %v0, %for.body ], [ 1000, %entry ]
273cc398664SFlorian Hahn  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
274cc398664SFlorian Hahn  %l0 = load i32, ptr %arrayidx, align 4
275cc398664SFlorian Hahn  %v0 = call i32 @llvm.umax.i32(i32 %result.08, i32 %l0)
276cc398664SFlorian Hahn  %indvars.iv.next = add i64 %indvars.iv, 1
277cc398664SFlorian Hahn  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
278cc398664SFlorian Hahn  %exitcond = icmp eq i32 %lftr.wideiv, 256
279cc398664SFlorian Hahn  br i1 %exitcond, label %for.end, label %for.body
280cc398664SFlorian Hahn
281cc398664SFlorian Hahnfor.end:                                          ; preds = %for.body, %entry
282cc398664SFlorian Hahn  %result.0.lcssa = phi i32 [ %v0, %for.body ]
283cc398664SFlorian Hahn  ret i32 %result.0.lcssa
284cc398664SFlorian Hahn}
285cc398664SFlorian Hahn
286cc398664SFlorian Hahndeclare i32 @llvm.umax.i32(i32, i32)
287