1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve.fp -loop-vectorize -tail-predication=enabled -dce -instcombine -S | FileCheck %s
3
4target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
5target triple = "thumbv8.1m.main-none-none-eabi"
6
7define i32 @reduction_sum_single(i32* noalias nocapture %A) {
8; CHECK-LABEL: @reduction_sum_single(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
11; CHECK:       vector.ph:
12; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
13; CHECK:       vector.body:
14; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
15; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP3:%.*]], [[VECTOR_BODY]] ]
16; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 [[INDEX]]
17; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 [[INDEX]], i32 257)
18; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
19; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP1]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
20; CHECK-NEXT:    [[TMP2:%.*]] = select <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> [[WIDE_MASKED_LOAD]], <4 x i32> zeroinitializer
21; CHECK-NEXT:    [[TMP3]] = add <4 x i32> [[VEC_PHI]], [[TMP2]]
22; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
23; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[INDEX_NEXT]], 260
24; CHECK-NEXT:    br i1 [[TMP4]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP0:!llvm.loop !.*]]
25; CHECK:       middle.block:
26; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @llvm.experimental.vector.reduce.add.v4i32(<4 x i32> [[TMP3]])
27; CHECK-NEXT:    br i1 true, label [[DOT_CRIT_EDGE:%.*]], label [[SCALAR_PH]]
28; CHECK:       scalar.ph:
29; CHECK-NEXT:    br label [[DOTLR_PH:%.*]]
30; CHECK:       .lr.ph:
31; CHECK-NEXT:    br i1 undef, label [[DOT_CRIT_EDGE]], label [[DOTLR_PH]], [[LOOP2:!llvm.loop !.*]]
32; CHECK:       ._crit_edge:
33; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ undef, [[DOTLR_PH]] ], [ [[TMP5]], [[MIDDLE_BLOCK]] ]
34; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
35;
36entry:
37  br label %.lr.ph
38
39.lr.ph:                                           ; preds = %entry, %.lr.ph
40  %indvars.iv = phi i32 [ %indvars.iv.next, %.lr.ph ], [ 0, %entry ]
41  %sum.02 = phi i32 [ %l7, %.lr.ph ], [ 0, %entry ]
42  %l2 = getelementptr inbounds i32, i32* %A, i32 %indvars.iv
43  %l3 = load i32, i32* %l2, align 4
44  %l7 = add i32 %sum.02, %l3
45  %indvars.iv.next = add i32 %indvars.iv, 1
46  %exitcond = icmp eq i32 %indvars.iv.next, 257
47  br i1 %exitcond, label %._crit_edge, label %.lr.ph
48
49._crit_edge:                                      ; preds = %.lr.ph
50  %sum.0.lcssa = phi i32 [ %l7, %.lr.ph ]
51  ret i32 %sum.0.lcssa
52}
53
54define i32 @reduction_sum(i32* noalias nocapture %A, i32* noalias nocapture %B) {
55; CHECK-LABEL: @reduction_sum(
56; CHECK-NEXT:  entry:
57; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
58; CHECK:       vector.ph:
59; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
60; CHECK:       vector.body:
61; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
62; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
63; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP7:%.*]], [[VECTOR_BODY]] ]
64; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 [[INDEX]]
65; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 [[INDEX]], i32 257)
66; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
67; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP1]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
68; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i32 [[INDEX]]
69; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32* [[TMP2]] to <4 x i32>*
70; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP3]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
71; CHECK-NEXT:    [[TMP4:%.*]] = add <4 x i32> [[VEC_PHI]], [[VEC_IND]]
72; CHECK-NEXT:    [[TMP5:%.*]] = add <4 x i32> [[TMP4]], [[WIDE_MASKED_LOAD]]
73; CHECK-NEXT:    [[TMP6:%.*]] = add <4 x i32> [[TMP5]], [[WIDE_MASKED_LOAD1]]
74; CHECK-NEXT:    [[TMP7]] = select <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> [[TMP6]], <4 x i32> [[VEC_PHI]]
75; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
76; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <4 x i32> [[VEC_IND]], <i32 4, i32 4, i32 4, i32 4>
77; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i32 [[INDEX_NEXT]], 260
78; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP4:!llvm.loop !.*]]
79; CHECK:       middle.block:
80; CHECK-NEXT:    [[TMP9:%.*]] = call i32 @llvm.experimental.vector.reduce.add.v4i32(<4 x i32> [[TMP7]])
81; CHECK-NEXT:    br i1 true, label [[DOT_CRIT_EDGE:%.*]], label [[SCALAR_PH]]
82; CHECK:       scalar.ph:
83; CHECK-NEXT:    br label [[DOTLR_PH:%.*]]
84; CHECK:       .lr.ph:
85; CHECK-NEXT:    br i1 undef, label [[DOT_CRIT_EDGE]], label [[DOTLR_PH]], [[LOOP5:!llvm.loop !.*]]
86; CHECK:       ._crit_edge:
87; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ undef, [[DOTLR_PH]] ], [ [[TMP9]], [[MIDDLE_BLOCK]] ]
88; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
89;
90entry:
91  br label %.lr.ph
92
93.lr.ph:                                           ; preds = %entry, %.lr.ph
94  %indvars.iv = phi i32 [ %indvars.iv.next, %.lr.ph ], [ 0, %entry ]
95  %sum.02 = phi i32 [ %l9, %.lr.ph ], [ 0, %entry ]
96  %l2 = getelementptr inbounds i32, i32* %A, i32 %indvars.iv
97  %l3 = load i32, i32* %l2, align 4
98  %l4 = getelementptr inbounds i32, i32* %B, i32 %indvars.iv
99  %l5 = load i32, i32* %l4, align 4
100  %l7 = add i32 %sum.02, %indvars.iv
101  %l8 = add i32 %l7, %l3
102  %l9 = add i32 %l8, %l5
103  %indvars.iv.next = add i32 %indvars.iv, 1
104  %exitcond = icmp eq i32 %indvars.iv.next, 257
105  br i1 %exitcond, label %._crit_edge, label %.lr.ph
106
107._crit_edge:                                      ; preds = %.lr.ph
108  %sum.0.lcssa = phi i32 [ %l9, %.lr.ph ]
109  ret i32 %sum.0.lcssa
110}
111
112define i32 @reduction_prod(i32* noalias nocapture %A, i32* noalias nocapture %B) {
113; CHECK-LABEL: @reduction_prod(
114; CHECK-NEXT:  entry:
115; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
116; CHECK:       vector.ph:
117; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
118; CHECK:       vector.body:
119; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
120; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 1, i32 1, i32 1, i32 1>, [[VECTOR_PH]] ], [ [[TMP6:%.*]], [[VECTOR_BODY]] ]
121; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 [[INDEX]]
122; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 [[INDEX]], i32 257)
123; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
124; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP1]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
125; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i32 [[INDEX]]
126; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32* [[TMP2]] to <4 x i32>*
127; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP3]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
128; CHECK-NEXT:    [[TMP4:%.*]] = mul <4 x i32> [[VEC_PHI]], [[WIDE_MASKED_LOAD]]
129; CHECK-NEXT:    [[TMP5:%.*]] = mul <4 x i32> [[TMP4]], [[WIDE_MASKED_LOAD1]]
130; CHECK-NEXT:    [[TMP6]] = select <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> [[TMP5]], <4 x i32> [[VEC_PHI]]
131; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
132; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], 260
133; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP6:!llvm.loop !.*]]
134; CHECK:       middle.block:
135; CHECK-NEXT:    [[TMP8:%.*]] = call i32 @llvm.experimental.vector.reduce.mul.v4i32(<4 x i32> [[TMP6]])
136; CHECK-NEXT:    br i1 true, label [[DOT_CRIT_EDGE:%.*]], label [[SCALAR_PH]]
137; CHECK:       scalar.ph:
138; CHECK-NEXT:    br label [[DOTLR_PH:%.*]]
139; CHECK:       .lr.ph:
140; CHECK-NEXT:    br i1 undef, label [[DOT_CRIT_EDGE]], label [[DOTLR_PH]], [[LOOP7:!llvm.loop !.*]]
141; CHECK:       ._crit_edge:
142; CHECK-NEXT:    [[PROD_0_LCSSA:%.*]] = phi i32 [ undef, [[DOTLR_PH]] ], [ [[TMP8]], [[MIDDLE_BLOCK]] ]
143; CHECK-NEXT:    ret i32 [[PROD_0_LCSSA]]
144;
145entry:
146  br label %.lr.ph
147
148.lr.ph:                                           ; preds = %entry, %.lr.ph
149  %indvars.iv = phi i32 [ %indvars.iv.next, %.lr.ph ], [ 0, %entry ]
150  %prod.02 = phi i32 [ %l9, %.lr.ph ], [ 1, %entry ]
151  %l2 = getelementptr inbounds i32, i32* %A, i32 %indvars.iv
152  %l3 = load i32, i32* %l2, align 4
153  %l4 = getelementptr inbounds i32, i32* %B, i32 %indvars.iv
154  %l5 = load i32, i32* %l4, align 4
155  %l8 = mul i32 %prod.02, %l3
156  %l9 = mul i32 %l8, %l5
157  %indvars.iv.next = add i32 %indvars.iv, 1
158  %exitcond = icmp eq i32 %indvars.iv.next, 257
159  br i1 %exitcond, label %._crit_edge, label %.lr.ph
160
161._crit_edge:                                      ; preds = %.lr.ph
162  %prod.0.lcssa = phi i32 [ %l9, %.lr.ph ]
163  ret i32 %prod.0.lcssa
164}
165
166define i32 @reduction_and(i32* nocapture %A, i32* nocapture %B) {
167; CHECK-LABEL: @reduction_and(
168; CHECK-NEXT:  entry:
169; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
170; CHECK:       vector.ph:
171; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
172; CHECK:       vector.body:
173; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
174; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 -1, i32 -1, i32 -1, i32 -1>, [[VECTOR_PH]] ], [ [[TMP6:%.*]], [[VECTOR_BODY]] ]
175; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 [[INDEX]]
176; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 [[INDEX]], i32 257)
177; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
178; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP1]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
179; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i32 [[INDEX]]
180; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32* [[TMP2]] to <4 x i32>*
181; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP3]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
182; CHECK-NEXT:    [[TMP4:%.*]] = and <4 x i32> [[VEC_PHI]], [[WIDE_MASKED_LOAD]]
183; CHECK-NEXT:    [[TMP5:%.*]] = and <4 x i32> [[TMP4]], [[WIDE_MASKED_LOAD1]]
184; CHECK-NEXT:    [[TMP6]] = select <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> [[TMP5]], <4 x i32> [[VEC_PHI]]
185; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
186; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], 260
187; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP8:!llvm.loop !.*]]
188; CHECK:       middle.block:
189; CHECK-NEXT:    [[TMP8:%.*]] = call i32 @llvm.experimental.vector.reduce.and.v4i32(<4 x i32> [[TMP6]])
190; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
191; CHECK:       scalar.ph:
192; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
193; CHECK:       for.body:
194; CHECK-NEXT:    br i1 undef, label [[FOR_END]], label [[FOR_BODY]], [[LOOP9:!llvm.loop !.*]]
195; CHECK:       for.end:
196; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ undef, [[FOR_BODY]] ], [ [[TMP8]], [[MIDDLE_BLOCK]] ]
197; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
198;
199entry:
200  br label %for.body
201
202for.body:                                         ; preds = %entry, %for.body
203  %indvars.iv = phi i32 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
204  %result.08 = phi i32 [ %and, %for.body ], [ -1, %entry ]
205  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %indvars.iv
206  %l0 = load i32, i32* %arrayidx, align 4
207  %arrayidx2 = getelementptr inbounds i32, i32* %B, i32 %indvars.iv
208  %l1 = load i32, i32* %arrayidx2, align 4
209  %add = and i32 %result.08, %l0
210  %and = and i32 %add, %l1
211  %indvars.iv.next = add i32 %indvars.iv, 1
212  %exitcond = icmp eq i32 %indvars.iv.next, 257
213  br i1 %exitcond, label %for.end, label %for.body
214
215for.end:                                          ; preds = %for.body, %entry
216  %result.0.lcssa = phi i32 [ %and, %for.body ]
217  ret i32 %result.0.lcssa
218}
219
220define i32 @reduction_or(i32* nocapture %A, i32* nocapture %B) {
221; CHECK-LABEL: @reduction_or(
222; CHECK-NEXT:  entry:
223; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
224; CHECK:       vector.ph:
225; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
226; CHECK:       vector.body:
227; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
228; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP6:%.*]], [[VECTOR_BODY]] ]
229; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 [[INDEX]]
230; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 [[INDEX]], i32 257)
231; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
232; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP1]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
233; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i32 [[INDEX]]
234; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32* [[TMP2]] to <4 x i32>*
235; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP3]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
236; CHECK-NEXT:    [[TMP4:%.*]] = add nsw <4 x i32> [[WIDE_MASKED_LOAD1]], [[WIDE_MASKED_LOAD]]
237; CHECK-NEXT:    [[TMP5:%.*]] = select <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> [[TMP4]], <4 x i32> zeroinitializer
238; CHECK-NEXT:    [[TMP6]] = or <4 x i32> [[VEC_PHI]], [[TMP5]]
239; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
240; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], 260
241; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP10:!llvm.loop !.*]]
242; CHECK:       middle.block:
243; CHECK-NEXT:    [[TMP8:%.*]] = call i32 @llvm.experimental.vector.reduce.or.v4i32(<4 x i32> [[TMP6]])
244; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
245; CHECK:       scalar.ph:
246; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
247; CHECK:       for.body:
248; CHECK-NEXT:    br i1 undef, label [[FOR_END]], label [[FOR_BODY]], [[LOOP11:!llvm.loop !.*]]
249; CHECK:       for.end:
250; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ undef, [[FOR_BODY]] ], [ [[TMP8]], [[MIDDLE_BLOCK]] ]
251; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
252;
253entry:
254  br label %for.body
255
256for.body:                                         ; preds = %entry, %for.body
257  %indvars.iv = phi i32 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
258  %result.08 = phi i32 [ %or, %for.body ], [ 0, %entry ]
259  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %indvars.iv
260  %l0 = load i32, i32* %arrayidx, align 4
261  %arrayidx2 = getelementptr inbounds i32, i32* %B, i32 %indvars.iv
262  %l1 = load i32, i32* %arrayidx2, align 4
263  %add = add nsw i32 %l1, %l0
264  %or = or i32 %add, %result.08
265  %indvars.iv.next = add i32 %indvars.iv, 1
266  %exitcond = icmp eq i32 %indvars.iv.next, 257
267  br i1 %exitcond, label %for.end, label %for.body
268
269for.end:                                          ; preds = %for.body, %entry
270  %result.0.lcssa = phi i32 [ %or, %for.body ]
271  ret i32 %result.0.lcssa
272}
273
274define i32 @reduction_xor(i32* nocapture %A, i32* nocapture %B) {
275; CHECK-LABEL: @reduction_xor(
276; CHECK-NEXT:  entry:
277; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
278; CHECK:       vector.ph:
279; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
280; CHECK:       vector.body:
281; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
282; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP6:%.*]], [[VECTOR_BODY]] ]
283; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 [[INDEX]]
284; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 [[INDEX]], i32 257)
285; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
286; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP1]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
287; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i32 [[INDEX]]
288; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32* [[TMP2]] to <4 x i32>*
289; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* [[TMP3]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> undef)
290; CHECK-NEXT:    [[TMP4:%.*]] = add nsw <4 x i32> [[WIDE_MASKED_LOAD1]], [[WIDE_MASKED_LOAD]]
291; CHECK-NEXT:    [[TMP5:%.*]] = select <4 x i1> [[ACTIVE_LANE_MASK]], <4 x i32> [[TMP4]], <4 x i32> zeroinitializer
292; CHECK-NEXT:    [[TMP6]] = xor <4 x i32> [[VEC_PHI]], [[TMP5]]
293; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
294; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], 260
295; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP12:!llvm.loop !.*]]
296; CHECK:       middle.block:
297; CHECK-NEXT:    [[TMP8:%.*]] = call i32 @llvm.experimental.vector.reduce.xor.v4i32(<4 x i32> [[TMP6]])
298; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
299; CHECK:       scalar.ph:
300; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
301; CHECK:       for.body:
302; CHECK-NEXT:    br i1 undef, label [[FOR_END]], label [[FOR_BODY]], [[LOOP13:!llvm.loop !.*]]
303; CHECK:       for.end:
304; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ undef, [[FOR_BODY]] ], [ [[TMP8]], [[MIDDLE_BLOCK]] ]
305; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
306;
307entry:
308  br label %for.body
309
310for.body:                                         ; preds = %entry, %for.body
311  %indvars.iv = phi i32 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
312  %result.08 = phi i32 [ %xor, %for.body ], [ 0, %entry ]
313  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %indvars.iv
314  %l0 = load i32, i32* %arrayidx, align 4
315  %arrayidx2 = getelementptr inbounds i32, i32* %B, i32 %indvars.iv
316  %l1 = load i32, i32* %arrayidx2, align 4
317  %add = add nsw i32 %l1, %l0
318  %xor = xor i32 %add, %result.08
319  %indvars.iv.next = add i32 %indvars.iv, 1
320  %exitcond = icmp eq i32 %indvars.iv.next, 257
321  br i1 %exitcond, label %for.end, label %for.body
322
323for.end:                                          ; preds = %for.body, %entry
324  %result.0.lcssa = phi i32 [ %xor, %for.body ]
325  ret i32 %result.0.lcssa
326}
327
328define float @reduction_fadd(float* nocapture %A, float* nocapture %B) {
329; CHECK-LABEL: @reduction_fadd(
330; CHECK-NEXT:  entry:
331; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
332; CHECK:       vector.ph:
333; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
334; CHECK:       vector.body:
335; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
336; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x float> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP6:%.*]], [[VECTOR_BODY]] ]
337; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i32 [[INDEX]]
338; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 [[INDEX]], i32 257)
339; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float* [[TMP0]] to <4 x float>*
340; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0v4f32(<4 x float>* [[TMP1]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x float> undef)
341; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i32 [[INDEX]]
342; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float* [[TMP2]] to <4 x float>*
343; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0v4f32(<4 x float>* [[TMP3]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x float> undef)
344; CHECK-NEXT:    [[TMP4:%.*]] = fadd fast <4 x float> [[VEC_PHI]], [[WIDE_MASKED_LOAD]]
345; CHECK-NEXT:    [[TMP5:%.*]] = fadd fast <4 x float> [[TMP4]], [[WIDE_MASKED_LOAD1]]
346; CHECK-NEXT:    [[TMP6]] = select <4 x i1> [[ACTIVE_LANE_MASK]], <4 x float> [[TMP5]], <4 x float> [[VEC_PHI]]
347; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
348; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], 260
349; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP14:!llvm.loop !.*]]
350; CHECK:       middle.block:
351; CHECK-NEXT:    [[TMP8:%.*]] = call fast float @llvm.experimental.vector.reduce.v2.fadd.f32.v4f32(float 0.000000e+00, <4 x float> [[TMP6]])
352; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
353; CHECK:       scalar.ph:
354; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
355; CHECK:       for.body:
356; CHECK-NEXT:    br i1 undef, label [[FOR_END]], label [[FOR_BODY]], [[LOOP15:!llvm.loop !.*]]
357; CHECK:       for.end:
358; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi float [ undef, [[FOR_BODY]] ], [ [[TMP8]], [[MIDDLE_BLOCK]] ]
359; CHECK-NEXT:    ret float [[RESULT_0_LCSSA]]
360;
361entry:
362  br label %for.body
363
364for.body:                                         ; preds = %entry, %for.body
365  %indvars.iv = phi i32 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
366  %result.08 = phi float [ %fadd, %for.body ], [ 0.0, %entry ]
367  %arrayidx = getelementptr inbounds float, float* %A, i32 %indvars.iv
368  %l0 = load float, float* %arrayidx, align 4
369  %arrayidx2 = getelementptr inbounds float, float* %B, i32 %indvars.iv
370  %l1 = load float, float* %arrayidx2, align 4
371  %add = fadd fast float %result.08, %l0
372  %fadd = fadd fast float %add, %l1
373  %indvars.iv.next = add i32 %indvars.iv, 1
374  %exitcond = icmp eq i32 %indvars.iv.next, 257
375  br i1 %exitcond, label %for.end, label %for.body
376
377for.end:                                          ; preds = %for.body, %entry
378  %result.0.lcssa = phi float [ %fadd, %for.body ]
379  ret float %result.0.lcssa
380}
381
382define float @reduction_fmul(float* nocapture %A, float* nocapture %B) {
383; CHECK-LABEL: @reduction_fmul(
384; CHECK-NEXT:  entry:
385; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
386; CHECK:       vector.ph:
387; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
388; CHECK:       vector.body:
389; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
390; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x float> [ <float 0.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, [[VECTOR_PH]] ], [ [[TMP6:%.*]], [[VECTOR_BODY]] ]
391; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i32 [[INDEX]]
392; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 [[INDEX]], i32 257)
393; CHECK-NEXT:    [[TMP1:%.*]] = bitcast float* [[TMP0]] to <4 x float>*
394; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0v4f32(<4 x float>* [[TMP1]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x float> undef)
395; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i32 [[INDEX]]
396; CHECK-NEXT:    [[TMP3:%.*]] = bitcast float* [[TMP2]] to <4 x float>*
397; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <4 x float> @llvm.masked.load.v4f32.p0v4f32(<4 x float>* [[TMP3]], i32 4, <4 x i1> [[ACTIVE_LANE_MASK]], <4 x float> undef)
398; CHECK-NEXT:    [[TMP4:%.*]] = fmul fast <4 x float> [[VEC_PHI]], [[WIDE_MASKED_LOAD]]
399; CHECK-NEXT:    [[TMP5:%.*]] = fmul fast <4 x float> [[TMP4]], [[WIDE_MASKED_LOAD1]]
400; CHECK-NEXT:    [[TMP6]] = select <4 x i1> [[ACTIVE_LANE_MASK]], <4 x float> [[TMP5]], <4 x float> [[VEC_PHI]]
401; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
402; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i32 [[INDEX_NEXT]], 260
403; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP16:!llvm.loop !.*]]
404; CHECK:       middle.block:
405; CHECK-NEXT:    [[TMP8:%.*]] = call fast float @llvm.experimental.vector.reduce.v2.fmul.f32.v4f32(float 1.000000e+00, <4 x float> [[TMP6]])
406; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
407; CHECK:       scalar.ph:
408; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
409; CHECK:       for.body:
410; CHECK-NEXT:    br i1 undef, label [[FOR_END]], label [[FOR_BODY]], [[LOOP17:!llvm.loop !.*]]
411; CHECK:       for.end:
412; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi float [ undef, [[FOR_BODY]] ], [ [[TMP8]], [[MIDDLE_BLOCK]] ]
413; CHECK-NEXT:    ret float [[RESULT_0_LCSSA]]
414;
415entry:
416  br label %for.body
417
418for.body:                                         ; preds = %entry, %for.body
419  %indvars.iv = phi i32 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
420  %result.08 = phi float [ %fmul, %for.body ], [ 0.0, %entry ]
421  %arrayidx = getelementptr inbounds float, float* %A, i32 %indvars.iv
422  %l0 = load float, float* %arrayidx, align 4
423  %arrayidx2 = getelementptr inbounds float, float* %B, i32 %indvars.iv
424  %l1 = load float, float* %arrayidx2, align 4
425  %add = fmul fast float %result.08, %l0
426  %fmul = fmul fast float %add, %l1
427  %indvars.iv.next = add i32 %indvars.iv, 1
428  %exitcond = icmp eq i32 %indvars.iv.next, 257
429  br i1 %exitcond, label %for.end, label %for.body
430
431for.end:                                          ; preds = %for.body, %entry
432  %result.0.lcssa = phi float [ %fmul, %for.body ]
433  ret float %result.0.lcssa
434}
435
436define i32 @reduction_min(i32* nocapture %A, i32* nocapture %B) {
437; CHECK-LABEL: @reduction_min(
438; CHECK-NEXT:  entry:
439; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
440; CHECK:       vector.ph:
441; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
442; CHECK:       vector.body:
443; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
444; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 1000, i32 1000, i32 1000, i32 1000>, [[VECTOR_PH]] ], [ [[TMP3:%.*]], [[VECTOR_BODY]] ]
445; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 [[INDEX]]
446; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
447; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP1]], align 4
448; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt <4 x i32> [[VEC_PHI]], [[WIDE_LOAD]]
449; CHECK-NEXT:    [[TMP3]] = select <4 x i1> [[TMP2]], <4 x i32> [[VEC_PHI]], <4 x i32> [[WIDE_LOAD]]
450; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
451; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[INDEX_NEXT]], 256
452; CHECK-NEXT:    br i1 [[TMP4]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP18:!llvm.loop !.*]]
453; CHECK:       middle.block:
454; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @llvm.experimental.vector.reduce.smin.v4i32(<4 x i32> [[TMP3]])
455; CHECK-NEXT:    br i1 false, label [[FOR_END:%.*]], label [[SCALAR_PH]]
456; CHECK:       scalar.ph:
457; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 256, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
458; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP5]], [[MIDDLE_BLOCK]] ], [ 1000, [[ENTRY]] ]
459; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
460; CHECK:       for.body:
461; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
462; CHECK-NEXT:    [[RESULT_08:%.*]] = phi i32 [ [[V0:%.*]], [[FOR_BODY]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
463; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 [[INDVARS_IV]]
464; CHECK-NEXT:    [[L0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
465; CHECK-NEXT:    [[C0:%.*]] = icmp slt i32 [[RESULT_08]], [[L0]]
466; CHECK-NEXT:    [[V0]] = select i1 [[C0]], i32 [[RESULT_08]], i32 [[L0]]
467; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i32 [[INDVARS_IV]], 1
468; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INDVARS_IV_NEXT]], 257
469; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], [[LOOP19:!llvm.loop !.*]]
470; CHECK:       for.end:
471; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ [[V0]], [[FOR_BODY]] ], [ [[TMP5]], [[MIDDLE_BLOCK]] ]
472; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
473;
474entry:
475  br label %for.body
476
477for.body:                                         ; preds = %entry, %for.body
478  %indvars.iv = phi i32 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
479  %result.08 = phi i32 [ %v0, %for.body ], [ 1000, %entry ]
480  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %indvars.iv
481  %l0 = load i32, i32* %arrayidx, align 4
482  %c0 = icmp slt i32 %result.08, %l0
483  %v0 = select i1 %c0, i32 %result.08, i32 %l0
484  %indvars.iv.next = add i32 %indvars.iv, 1
485  %exitcond = icmp eq i32 %indvars.iv.next, 257
486  br i1 %exitcond, label %for.end, label %for.body
487
488for.end:                                          ; preds = %for.body, %entry
489  %result.0.lcssa = phi i32 [ %v0, %for.body ]
490  ret i32 %result.0.lcssa
491}
492
493define i32 @reduction_max(i32* nocapture %A, i32* nocapture %B) {
494; CHECK-LABEL: @reduction_max(
495; CHECK-NEXT:  entry:
496; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
497; CHECK:       vector.ph:
498; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
499; CHECK:       vector.body:
500; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
501; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ <i32 1000, i32 1000, i32 1000, i32 1000>, [[VECTOR_PH]] ], [ [[TMP3:%.*]], [[VECTOR_BODY]] ]
502; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 [[INDEX]]
503; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[TMP0]] to <4 x i32>*
504; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP1]], align 4
505; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt <4 x i32> [[VEC_PHI]], [[WIDE_LOAD]]
506; CHECK-NEXT:    [[TMP3]] = select <4 x i1> [[TMP2]], <4 x i32> [[VEC_PHI]], <4 x i32> [[WIDE_LOAD]]
507; CHECK-NEXT:    [[INDEX_NEXT]] = add i32 [[INDEX]], 4
508; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[INDEX_NEXT]], 256
509; CHECK-NEXT:    br i1 [[TMP4]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], [[LOOP20:!llvm.loop !.*]]
510; CHECK:       middle.block:
511; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @llvm.experimental.vector.reduce.umax.v4i32(<4 x i32> [[TMP3]])
512; CHECK-NEXT:    br i1 false, label [[FOR_END:%.*]], label [[SCALAR_PH]]
513; CHECK:       scalar.ph:
514; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 256, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
515; CHECK-NEXT:    [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP5]], [[MIDDLE_BLOCK]] ], [ 1000, [[ENTRY]] ]
516; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
517; CHECK:       for.body:
518; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
519; CHECK-NEXT:    [[RESULT_08:%.*]] = phi i32 [ [[V0:%.*]], [[FOR_BODY]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
520; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 [[INDVARS_IV]]
521; CHECK-NEXT:    [[L0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
522; CHECK-NEXT:    [[C0:%.*]] = icmp ugt i32 [[RESULT_08]], [[L0]]
523; CHECK-NEXT:    [[V0]] = select i1 [[C0]], i32 [[RESULT_08]], i32 [[L0]]
524; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i32 [[INDVARS_IV]], 1
525; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INDVARS_IV_NEXT]], 257
526; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], [[LOOP21:!llvm.loop !.*]]
527; CHECK:       for.end:
528; CHECK-NEXT:    [[RESULT_0_LCSSA:%.*]] = phi i32 [ [[V0]], [[FOR_BODY]] ], [ [[TMP5]], [[MIDDLE_BLOCK]] ]
529; CHECK-NEXT:    ret i32 [[RESULT_0_LCSSA]]
530;
531entry:
532  br label %for.body
533
534for.body:                                         ; preds = %entry, %for.body
535  %indvars.iv = phi i32 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
536  %result.08 = phi i32 [ %v0, %for.body ], [ 1000, %entry ]
537  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %indvars.iv
538  %l0 = load i32, i32* %arrayidx, align 4
539  %c0 = icmp ugt i32 %result.08, %l0
540  %v0 = select i1 %c0, i32 %result.08, i32 %l0
541  %indvars.iv.next = add i32 %indvars.iv, 1
542  %exitcond = icmp eq i32 %indvars.iv.next, 257
543  br i1 %exitcond, label %for.end, label %for.body
544
545for.end:                                          ; preds = %for.body, %entry
546  %result.0.lcssa = phi i32 [ %v0, %for.body ]
547  ret i32 %result.0.lcssa
548}
549
550define float @reduction_fmax(float* nocapture %A, float* nocapture %B) {
551; CHECK-LABEL: @reduction_fmax(
552; CHECK-NEXT:  entry:
553; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
554; CHECK:       for.body:
555; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
556; CHECK-NEXT:    [[RESULT_08:%.*]] = phi float [ [[V0:%.*]], [[FOR_BODY]] ], [ 1.000000e+03, [[ENTRY]] ]
557; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i32 [[INDVARS_IV]]
558; CHECK-NEXT:    [[L0:%.*]] = load float, float* [[ARRAYIDX]], align 4
559; CHECK-NEXT:    [[C0:%.*]] = fcmp ogt float [[RESULT_08]], [[L0]]
560; CHECK-NEXT:    [[V0]] = select i1 [[C0]], float [[RESULT_08]], float [[L0]]
561; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i32 [[INDVARS_IV]], 1
562; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INDVARS_IV_NEXT]], 257
563; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END:%.*]], label [[FOR_BODY]]
564; CHECK:       for.end:
565; CHECK-NEXT:    ret float [[V0]]
566;
567entry:
568  br label %for.body
569
570for.body:                                         ; preds = %entry, %for.body
571  %indvars.iv = phi i32 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
572  %result.08 = phi float [ %v0, %for.body ], [ 1000.0, %entry ]
573  %arrayidx = getelementptr inbounds float, float* %A, i32 %indvars.iv
574  %l0 = load float, float* %arrayidx, align 4
575  %c0 = fcmp ogt float %result.08, %l0
576  %v0 = select i1 %c0, float %result.08, float %l0
577  %indvars.iv.next = add i32 %indvars.iv, 1
578  %exitcond = icmp eq i32 %indvars.iv.next, 257
579  br i1 %exitcond, label %for.end, label %for.body
580
581for.end:                                          ; preds = %for.body, %entry
582  %result.0.lcssa = phi float [ %v0, %for.body ]
583  ret float %result.0.lcssa
584}
585