[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / Transforms / SLPVectorizer / AArch64 / horizontal.ll
blob7e4b95d7234994bc0e5f4eba068f31b7618af5b8
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -slp-vectorizer -slp-threshold=-6 -S -pass-remarks-output=%t < %s | FileCheck %s
3 ; RUN: cat %t | FileCheck -check-prefix=YAML %s
6 ; FIXME: The threshold is changed to keep this test case a bit smaller.
7 ; The AArch64 cost model should not give such high costs to select statements.
9 target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
10 target triple = "aarch64--linux"
12 ; YAML:      --- !Passed
13 ; YAML-NEXT: Pass:            slp-vectorizer
14 ; YAML-NEXT: Name:            VectorizedHorizontalReduction
15 ; YAML-NEXT: Function:        test_select
16 ; YAML-NEXT: Args:
17 ; YAML-NEXT:   - String:          'Vectorized horizontal reduction with cost '
18 ; YAML-NEXT:   - Cost:            '-8'
19 ; YAML-NEXT:   - String:          ' and with tree size '
20 ; YAML-NEXT:   - TreeSize:        '8'
22 define i32 @test_select(i32* noalias nocapture readonly %blk1, i32* noalias nocapture readonly %blk2, i32 %lx, i32 %h) {
23 ; CHECK-LABEL: @test_select(
24 ; CHECK-NEXT:  entry:
25 ; CHECK-NEXT:    [[CMP_22:%.*]] = icmp sgt i32 [[H:%.*]], 0
26 ; CHECK-NEXT:    br i1 [[CMP_22]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]
27 ; CHECK:       for.body.lr.ph:
28 ; CHECK-NEXT:    [[IDX_EXT:%.*]] = sext i32 [[LX:%.*]] to i64
29 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
30 ; CHECK:       for.body:
31 ; CHECK-NEXT:    [[S_026:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[OP_EXTRA:%.*]], [[FOR_BODY]] ]
32 ; CHECK-NEXT:    [[J_025:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
33 ; CHECK-NEXT:    [[P2_024:%.*]] = phi i32* [ [[BLK2:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR29:%.*]], [[FOR_BODY]] ]
34 ; CHECK-NEXT:    [[P1_023:%.*]] = phi i32* [ [[BLK1:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR:%.*]], [[FOR_BODY]] ]
35 ; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, i32* [[P1_023]], i64 1
36 ; CHECK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, i32* [[P2_024]], i64 1
37 ; CHECK-NEXT:    [[ARRAYIDX12:%.*]] = getelementptr inbounds i32, i32* [[P1_023]], i64 2
38 ; CHECK-NEXT:    [[ARRAYIDX13:%.*]] = getelementptr inbounds i32, i32* [[P2_024]], i64 2
39 ; CHECK-NEXT:    [[ARRAYIDX20:%.*]] = getelementptr inbounds i32, i32* [[P1_023]], i64 3
40 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[P1_023]] to <4 x i32>*
41 ; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
42 ; CHECK-NEXT:    [[ARRAYIDX21:%.*]] = getelementptr inbounds i32, i32* [[P2_024]], i64 3
43 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i32* [[P2_024]] to <4 x i32>*
44 ; CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i32>, <4 x i32>* [[TMP2]], align 4
45 ; CHECK-NEXT:    [[TMP4:%.*]] = sub nsw <4 x i32> [[TMP1]], [[TMP3]]
46 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp slt <4 x i32> [[TMP4]], zeroinitializer
47 ; CHECK-NEXT:    [[TMP6:%.*]] = sub nsw <4 x i32> zeroinitializer, [[TMP4]]
48 ; CHECK-NEXT:    [[TMP7:%.*]] = select <4 x i1> [[TMP5]], <4 x i32> [[TMP6]], <4 x i32> [[TMP4]]
49 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 undef, [[S_026]]
50 ; CHECK-NEXT:    [[ADD11:%.*]] = add nsw i32 [[ADD]], undef
51 ; CHECK-NEXT:    [[ADD19:%.*]] = add nsw i32 [[ADD11]], undef
52 ; CHECK-NEXT:    [[TMP8:%.*]] = call i32 @llvm.experimental.vector.reduce.add.v4i32(<4 x i32> [[TMP7]])
53 ; CHECK-NEXT:    [[OP_EXTRA]] = add nsw i32 [[TMP8]], [[S_026]]
54 ; CHECK-NEXT:    [[ADD27:%.*]] = add nsw i32 [[ADD19]], undef
55 ; CHECK-NEXT:    [[ADD_PTR]] = getelementptr inbounds i32, i32* [[P1_023]], i64 [[IDX_EXT]]
56 ; CHECK-NEXT:    [[ADD_PTR29]] = getelementptr inbounds i32, i32* [[P2_024]], i64 [[IDX_EXT]]
57 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[J_025]], 1
58 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[H]]
59 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]
60 ; CHECK:       for.end.loopexit:
61 ; CHECK-NEXT:    br label [[FOR_END]]
62 ; CHECK:       for.end:
63 ; CHECK-NEXT:    [[S_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OP_EXTRA]], [[FOR_END_LOOPEXIT]] ]
64 ; CHECK-NEXT:    ret i32 [[S_0_LCSSA]]
66 entry:
67   %cmp.22 = icmp sgt i32 %h, 0
68   br i1 %cmp.22, label %for.body.lr.ph, label %for.end
70 for.body.lr.ph:                                   ; preds = %entry
71   %idx.ext = sext i32 %lx to i64
72   br label %for.body
74 for.body:                                         ; preds = %for.body, %for.body.lr.ph
75   %s.026 = phi i32 [ 0, %for.body.lr.ph ], [ %add27, %for.body ]
76   %j.025 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
77   %p2.024 = phi i32* [ %blk2, %for.body.lr.ph ], [ %add.ptr29, %for.body ]
78   %p1.023 = phi i32* [ %blk1, %for.body.lr.ph ], [ %add.ptr, %for.body ]
79   %0 = load i32, i32* %p1.023, align 4
80   %1 = load i32, i32* %p2.024, align 4
81   %sub = sub nsw i32 %0, %1
82   %cmp2 = icmp slt i32 %sub, 0
83   %sub3 = sub nsw i32 0, %sub
84   %sub3.sub = select i1 %cmp2, i32 %sub3, i32 %sub
85   %add = add nsw i32 %sub3.sub, %s.026
86   %arrayidx4 = getelementptr inbounds i32, i32* %p1.023, i64 1
87   %2 = load i32, i32* %arrayidx4, align 4
88   %arrayidx5 = getelementptr inbounds i32, i32* %p2.024, i64 1
89   %3 = load i32, i32* %arrayidx5, align 4
90   %sub6 = sub nsw i32 %2, %3
91   %cmp7 = icmp slt i32 %sub6, 0
92   %sub9 = sub nsw i32 0, %sub6
93   %v.1 = select i1 %cmp7, i32 %sub9, i32 %sub6
94   %add11 = add nsw i32 %add, %v.1
95   %arrayidx12 = getelementptr inbounds i32, i32* %p1.023, i64 2
96   %4 = load i32, i32* %arrayidx12, align 4
97   %arrayidx13 = getelementptr inbounds i32, i32* %p2.024, i64 2
98   %5 = load i32, i32* %arrayidx13, align 4
99   %sub14 = sub nsw i32 %4, %5
100   %cmp15 = icmp slt i32 %sub14, 0
101   %sub17 = sub nsw i32 0, %sub14
102   %sub17.sub14 = select i1 %cmp15, i32 %sub17, i32 %sub14
103   %add19 = add nsw i32 %add11, %sub17.sub14
104   %arrayidx20 = getelementptr inbounds i32, i32* %p1.023, i64 3
105   %6 = load i32, i32* %arrayidx20, align 4
106   %arrayidx21 = getelementptr inbounds i32, i32* %p2.024, i64 3
107   %7 = load i32, i32* %arrayidx21, align 4
108   %sub22 = sub nsw i32 %6, %7
109   %cmp23 = icmp slt i32 %sub22, 0
110   %sub25 = sub nsw i32 0, %sub22
111   %v.3 = select i1 %cmp23, i32 %sub25, i32 %sub22
112   %add27 = add nsw i32 %add19, %v.3
113   %add.ptr = getelementptr inbounds i32, i32* %p1.023, i64 %idx.ext
114   %add.ptr29 = getelementptr inbounds i32, i32* %p2.024, i64 %idx.ext
115   %inc = add nuw nsw i32 %j.025, 1
116   %exitcond = icmp eq i32 %inc, %h
117   br i1 %exitcond, label %for.end.loopexit, label %for.body
119 for.end.loopexit:                                 ; preds = %for.body
120   br label %for.end
122 for.end:                                          ; preds = %for.end.loopexit, %entry
123   %s.0.lcssa = phi i32 [ 0, %entry ], [ %add27, %for.end.loopexit ]
124   ret i32 %s.0.lcssa
127 ;; Check whether SLP can find a reduction phi whose incoming blocks are not
128 ;; the same as the block containing the phi.
130 ;; Came from code like,
132 ;; int s = 0;
133 ;; for (int j = 0; j < h; j++) {
134 ;;   s += p1[0] * p2[0]
135 ;;   s += p1[1] * p2[1];
136 ;;   s += p1[2] * p2[2];
137 ;;   s += p1[3] * p2[3];
138 ;;   if (s >= lim)
139 ;;      break;
140 ;;   p1 += lx;
141 ;;   p2 += lx;
142 ;; }
143 define i32 @reduction_with_br(i32* noalias nocapture readonly %blk1, i32* noalias nocapture readonly %blk2, i32 %lx, i32 %h, i32 %lim) {
144 ; YAML:      --- !Passed
145 ; YAML-NEXT: Pass:            slp-vectorizer
146 ; YAML-NEXT: Name:            VectorizedHorizontalReduction
147 ; YAML-NEXT: Function:        reduction_with_br
148 ; YAML-NEXT: Args:
149 ; YAML-NEXT:   - String:          'Vectorized horizontal reduction with cost '
150 ; YAML-NEXT:   - Cost:            '-11'
151 ; YAML-NEXT:   - String:          ' and with tree size '
152 ; YAML-NEXT:   - TreeSize:        '3'
153 ; CHECK-LABEL: @reduction_with_br(
154 ; CHECK-NEXT:  entry:
155 ; CHECK-NEXT:    [[CMP_16:%.*]] = icmp sgt i32 [[H:%.*]], 0
156 ; CHECK-NEXT:    br i1 [[CMP_16]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]
157 ; CHECK:       for.body.lr.ph:
158 ; CHECK-NEXT:    [[IDX_EXT:%.*]] = sext i32 [[LX:%.*]] to i64
159 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
160 ; CHECK:       for.body:
161 ; CHECK-NEXT:    [[S_020:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[OP_EXTRA:%.*]], [[IF_END:%.*]] ]
162 ; CHECK-NEXT:    [[J_019:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END]] ]
163 ; CHECK-NEXT:    [[P2_018:%.*]] = phi i32* [ [[BLK2:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR16:%.*]], [[IF_END]] ]
164 ; CHECK-NEXT:    [[P1_017:%.*]] = phi i32* [ [[BLK1:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR:%.*]], [[IF_END]] ]
165 ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* [[P1_017]], i64 1
166 ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, i32* [[P2_018]], i64 1
167 ; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, i32* [[P1_017]], i64 2
168 ; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, i32* [[P2_018]], i64 2
169 ; CHECK-NEXT:    [[ARRAYIDX10:%.*]] = getelementptr inbounds i32, i32* [[P1_017]], i64 3
170 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[P1_017]] to <4 x i32>*
171 ; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4
172 ; CHECK-NEXT:    [[ARRAYIDX11:%.*]] = getelementptr inbounds i32, i32* [[P2_018]], i64 3
173 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i32* [[P2_018]] to <4 x i32>*
174 ; CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i32>, <4 x i32>* [[TMP2]], align 4
175 ; CHECK-NEXT:    [[TMP4:%.*]] = mul nsw <4 x i32> [[TMP3]], [[TMP1]]
176 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 undef, [[S_020]]
177 ; CHECK-NEXT:    [[ADD5:%.*]] = add nsw i32 [[ADD]], undef
178 ; CHECK-NEXT:    [[ADD9:%.*]] = add nsw i32 [[ADD5]], undef
179 ; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @llvm.experimental.vector.reduce.add.v4i32(<4 x i32> [[TMP4]])
180 ; CHECK-NEXT:    [[OP_EXTRA]] = add nsw i32 [[TMP5]], [[S_020]]
181 ; CHECK-NEXT:    [[ADD13:%.*]] = add nsw i32 [[ADD9]], undef
182 ; CHECK-NEXT:    [[CMP14:%.*]] = icmp slt i32 [[OP_EXTRA]], [[LIM:%.*]]
183 ; CHECK-NEXT:    br i1 [[CMP14]], label [[IF_END]], label [[FOR_END_LOOPEXIT:%.*]]
184 ; CHECK:       if.end:
185 ; CHECK-NEXT:    [[ADD_PTR]] = getelementptr inbounds i32, i32* [[P1_017]], i64 [[IDX_EXT]]
186 ; CHECK-NEXT:    [[ADD_PTR16]] = getelementptr inbounds i32, i32* [[P2_018]], i64 [[IDX_EXT]]
187 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[J_019]], 1
188 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[H]]
189 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT]]
190 ; CHECK:       for.end.loopexit:
191 ; CHECK-NEXT:    br label [[FOR_END]]
192 ; CHECK:       for.end:
193 ; CHECK-NEXT:    [[S_1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OP_EXTRA]], [[FOR_END_LOOPEXIT]] ]
194 ; CHECK-NEXT:    ret i32 [[S_1]]
196 entry:
197   %cmp.16 = icmp sgt i32 %h, 0
198   br i1 %cmp.16, label %for.body.lr.ph, label %for.end
200 for.body.lr.ph:                                   ; preds = %entry
201   %idx.ext = sext i32 %lx to i64
202   br label %for.body
204 for.body:                                         ; preds = %for.body.lr.ph, %if.end
205   %s.020 = phi i32 [ 0, %for.body.lr.ph ], [ %add13, %if.end ]
206   %j.019 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %if.end ]
207   %p2.018 = phi i32* [ %blk2, %for.body.lr.ph ], [ %add.ptr16, %if.end ]
208   %p1.017 = phi i32* [ %blk1, %for.body.lr.ph ], [ %add.ptr, %if.end ]
209   %0 = load i32, i32* %p1.017, align 4
210   %1 = load i32, i32* %p2.018, align 4
211   %mul = mul nsw i32 %1, %0
212   %add = add nsw i32 %mul, %s.020
213   %arrayidx2 = getelementptr inbounds i32, i32* %p1.017, i64 1
214   %2 = load i32, i32* %arrayidx2, align 4
215   %arrayidx3 = getelementptr inbounds i32, i32* %p2.018, i64 1
216   %3 = load i32, i32* %arrayidx3, align 4
217   %mul4 = mul nsw i32 %3, %2
218   %add5 = add nsw i32 %add, %mul4
219   %arrayidx6 = getelementptr inbounds i32, i32* %p1.017, i64 2
220   %4 = load i32, i32* %arrayidx6, align 4
221   %arrayidx7 = getelementptr inbounds i32, i32* %p2.018, i64 2
222   %5 = load i32, i32* %arrayidx7, align 4
223   %mul8 = mul nsw i32 %5, %4
224   %add9 = add nsw i32 %add5, %mul8
225   %arrayidx10 = getelementptr inbounds i32, i32* %p1.017, i64 3
226   %6 = load i32, i32* %arrayidx10, align 4
227   %arrayidx11 = getelementptr inbounds i32, i32* %p2.018, i64 3
228   %7 = load i32, i32* %arrayidx11, align 4
229   %mul12 = mul nsw i32 %7, %6
230   %add13 = add nsw i32 %add9, %mul12
231   %cmp14 = icmp slt i32 %add13, %lim
232   br i1 %cmp14, label %if.end, label %for.end.loopexit
234 if.end:                                           ; preds = %for.body
235   %add.ptr = getelementptr inbounds i32, i32* %p1.017, i64 %idx.ext
236   %add.ptr16 = getelementptr inbounds i32, i32* %p2.018, i64 %idx.ext
237   %inc = add nuw nsw i32 %j.019, 1
238   %cmp = icmp slt i32 %inc, %h
239   br i1 %cmp, label %for.body, label %for.end.loopexit
241 for.end.loopexit:                                 ; preds = %for.body, %if.end
242   br label %for.end
244 for.end:                                          ; preds = %for.end.loopexit, %entry
245   %s.1 = phi i32 [ 0, %entry ], [ %add13, %for.end.loopexit ]
246   ret i32 %s.1
249 ; YAML:      --- !Passed
250 ; YAML-NEXT: Pass:            slp-vectorizer
251 ; YAML-NEXT: Name:            VectorizedHorizontalReduction
252 ; YAML-NEXT: Function:        test_unrolled_select
253 ; YAML-NEXT: Args:
254 ; YAML-NEXT:   - String:          'Vectorized horizontal reduction with cost '
255 ; YAML-NEXT:   - Cost:            '-47'
256 ; YAML-NEXT:   - String:          ' and with tree size '
257 ; YAML-NEXT:   - TreeSize:        '10'
259 define i32 @test_unrolled_select(i8* noalias nocapture readonly %blk1, i8* noalias nocapture readonly %blk2, i32 %lx, i32 %h, i32 %lim) #0 {
260 ; CHECK-LABEL: @test_unrolled_select(
261 ; CHECK-NEXT:  entry:
262 ; CHECK-NEXT:    [[CMP_43:%.*]] = icmp sgt i32 [[H:%.*]], 0
263 ; CHECK-NEXT:    br i1 [[CMP_43]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]
264 ; CHECK:       for.body.lr.ph:
265 ; CHECK-NEXT:    [[IDX_EXT:%.*]] = sext i32 [[LX:%.*]] to i64
266 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
267 ; CHECK:       for.body:
268 ; CHECK-NEXT:    [[S_047:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[OP_EXTRA:%.*]], [[IF_END_86:%.*]] ]
269 ; CHECK-NEXT:    [[J_046:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END_86]] ]
270 ; CHECK-NEXT:    [[P2_045:%.*]] = phi i8* [ [[BLK2:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR88:%.*]], [[IF_END_86]] ]
271 ; CHECK-NEXT:    [[P1_044:%.*]] = phi i8* [ [[BLK1:%.*]], [[FOR_BODY_LR_PH]] ], [ [[ADD_PTR:%.*]], [[IF_END_86]] ]
272 ; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds i8, i8* [[P1_044]], i64 1
273 ; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds i8, i8* [[P2_045]], i64 1
274 ; CHECK-NEXT:    [[ARRAYIDX17:%.*]] = getelementptr inbounds i8, i8* [[P1_044]], i64 2
275 ; CHECK-NEXT:    [[ARRAYIDX19:%.*]] = getelementptr inbounds i8, i8* [[P2_045]], i64 2
276 ; CHECK-NEXT:    [[ARRAYIDX28:%.*]] = getelementptr inbounds i8, i8* [[P1_044]], i64 3
277 ; CHECK-NEXT:    [[ARRAYIDX30:%.*]] = getelementptr inbounds i8, i8* [[P2_045]], i64 3
278 ; CHECK-NEXT:    [[ARRAYIDX39:%.*]] = getelementptr inbounds i8, i8* [[P1_044]], i64 4
279 ; CHECK-NEXT:    [[ARRAYIDX41:%.*]] = getelementptr inbounds i8, i8* [[P2_045]], i64 4
280 ; CHECK-NEXT:    [[ARRAYIDX50:%.*]] = getelementptr inbounds i8, i8* [[P1_044]], i64 5
281 ; CHECK-NEXT:    [[ARRAYIDX52:%.*]] = getelementptr inbounds i8, i8* [[P2_045]], i64 5
282 ; CHECK-NEXT:    [[ARRAYIDX61:%.*]] = getelementptr inbounds i8, i8* [[P1_044]], i64 6
283 ; CHECK-NEXT:    [[ARRAYIDX63:%.*]] = getelementptr inbounds i8, i8* [[P2_045]], i64 6
284 ; CHECK-NEXT:    [[ARRAYIDX72:%.*]] = getelementptr inbounds i8, i8* [[P1_044]], i64 7
285 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i8* [[P1_044]] to <8 x i8>*
286 ; CHECK-NEXT:    [[TMP1:%.*]] = load <8 x i8>, <8 x i8>* [[TMP0]], align 1
287 ; CHECK-NEXT:    [[TMP2:%.*]] = zext <8 x i8> [[TMP1]] to <8 x i32>
288 ; CHECK-NEXT:    [[ARRAYIDX74:%.*]] = getelementptr inbounds i8, i8* [[P2_045]], i64 7
289 ; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i8* [[P2_045]] to <8 x i8>*
290 ; CHECK-NEXT:    [[TMP4:%.*]] = load <8 x i8>, <8 x i8>* [[TMP3]], align 1
291 ; CHECK-NEXT:    [[TMP5:%.*]] = zext <8 x i8> [[TMP4]] to <8 x i32>
292 ; CHECK-NEXT:    [[TMP6:%.*]] = sub nsw <8 x i32> [[TMP2]], [[TMP5]]
293 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt <8 x i32> [[TMP6]], zeroinitializer
294 ; CHECK-NEXT:    [[TMP8:%.*]] = sub nsw <8 x i32> zeroinitializer, [[TMP6]]
295 ; CHECK-NEXT:    [[TMP9:%.*]] = select <8 x i1> [[TMP7]], <8 x i32> [[TMP8]], <8 x i32> [[TMP6]]
296 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 undef, [[S_047]]
297 ; CHECK-NEXT:    [[ADD16:%.*]] = add nsw i32 [[ADD]], undef
298 ; CHECK-NEXT:    [[ADD27:%.*]] = add nsw i32 [[ADD16]], undef
299 ; CHECK-NEXT:    [[ADD38:%.*]] = add nsw i32 [[ADD27]], undef
300 ; CHECK-NEXT:    [[ADD49:%.*]] = add nsw i32 [[ADD38]], undef
301 ; CHECK-NEXT:    [[ADD60:%.*]] = add nsw i32 [[ADD49]], undef
302 ; CHECK-NEXT:    [[ADD71:%.*]] = add nsw i32 [[ADD60]], undef
303 ; CHECK-NEXT:    [[TMP10:%.*]] = call i32 @llvm.experimental.vector.reduce.add.v8i32(<8 x i32> [[TMP9]])
304 ; CHECK-NEXT:    [[OP_EXTRA]] = add nsw i32 [[TMP10]], [[S_047]]
305 ; CHECK-NEXT:    [[ADD82:%.*]] = add nsw i32 [[ADD71]], undef
306 ; CHECK-NEXT:    [[CMP83:%.*]] = icmp slt i32 [[OP_EXTRA]], [[LIM:%.*]]
307 ; CHECK-NEXT:    br i1 [[CMP83]], label [[IF_END_86]], label [[FOR_END_LOOPEXIT:%.*]]
308 ; CHECK:       if.end.86:
309 ; CHECK-NEXT:    [[ADD_PTR]] = getelementptr inbounds i8, i8* [[P1_044]], i64 [[IDX_EXT]]
310 ; CHECK-NEXT:    [[ADD_PTR88]] = getelementptr inbounds i8, i8* [[P2_045]], i64 [[IDX_EXT]]
311 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[J_046]], 1
312 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[H]]
313 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT]]
314 ; CHECK:       for.end.loopexit:
315 ; CHECK-NEXT:    br label [[FOR_END]]
316 ; CHECK:       for.end:
317 ; CHECK-NEXT:    [[S_1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[OP_EXTRA]], [[FOR_END_LOOPEXIT]] ]
318 ; CHECK-NEXT:    ret i32 [[S_1]]
320 entry:
321   %cmp.43 = icmp sgt i32 %h, 0
322   br i1 %cmp.43, label %for.body.lr.ph, label %for.end
324 for.body.lr.ph:                                   ; preds = %entry
325   %idx.ext = sext i32 %lx to i64
326   br label %for.body
328 for.body:                                         ; preds = %for.body.lr.ph, %if.end.86
329   %s.047 = phi i32 [ 0, %for.body.lr.ph ], [ %add82, %if.end.86 ]
330   %j.046 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %if.end.86 ]
331   %p2.045 = phi i8* [ %blk2, %for.body.lr.ph ], [ %add.ptr88, %if.end.86 ]
332   %p1.044 = phi i8* [ %blk1, %for.body.lr.ph ], [ %add.ptr, %if.end.86 ]
333   %0 = load i8, i8* %p1.044, align 1
334   %conv = zext i8 %0 to i32
335   %1 = load i8, i8* %p2.045, align 1
336   %conv2 = zext i8 %1 to i32
337   %sub = sub nsw i32 %conv, %conv2
338   %cmp3 = icmp slt i32 %sub, 0
339   %sub5 = sub nsw i32 0, %sub
340   %sub5.sub = select i1 %cmp3, i32 %sub5, i32 %sub
341   %add = add nsw i32 %sub5.sub, %s.047
342   %arrayidx6 = getelementptr inbounds i8, i8* %p1.044, i64 1
343   %2 = load i8, i8* %arrayidx6, align 1
344   %conv7 = zext i8 %2 to i32
345   %arrayidx8 = getelementptr inbounds i8, i8* %p2.045, i64 1
346   %3 = load i8, i8* %arrayidx8, align 1
347   %conv9 = zext i8 %3 to i32
348   %sub10 = sub nsw i32 %conv7, %conv9
349   %cmp11 = icmp slt i32 %sub10, 0
350   %sub14 = sub nsw i32 0, %sub10
351   %v.1 = select i1 %cmp11, i32 %sub14, i32 %sub10
352   %add16 = add nsw i32 %add, %v.1
353   %arrayidx17 = getelementptr inbounds i8, i8* %p1.044, i64 2
354   %4 = load i8, i8* %arrayidx17, align 1
355   %conv18 = zext i8 %4 to i32
356   %arrayidx19 = getelementptr inbounds i8, i8* %p2.045, i64 2
357   %5 = load i8, i8* %arrayidx19, align 1
358   %conv20 = zext i8 %5 to i32
359   %sub21 = sub nsw i32 %conv18, %conv20
360   %cmp22 = icmp slt i32 %sub21, 0
361   %sub25 = sub nsw i32 0, %sub21
362   %sub25.sub21 = select i1 %cmp22, i32 %sub25, i32 %sub21
363   %add27 = add nsw i32 %add16, %sub25.sub21
364   %arrayidx28 = getelementptr inbounds i8, i8* %p1.044, i64 3
365   %6 = load i8, i8* %arrayidx28, align 1
366   %conv29 = zext i8 %6 to i32
367   %arrayidx30 = getelementptr inbounds i8, i8* %p2.045, i64 3
368   %7 = load i8, i8* %arrayidx30, align 1
369   %conv31 = zext i8 %7 to i32
370   %sub32 = sub nsw i32 %conv29, %conv31
371   %cmp33 = icmp slt i32 %sub32, 0
372   %sub36 = sub nsw i32 0, %sub32
373   %v.3 = select i1 %cmp33, i32 %sub36, i32 %sub32
374   %add38 = add nsw i32 %add27, %v.3
375   %arrayidx39 = getelementptr inbounds i8, i8* %p1.044, i64 4
376   %8 = load i8, i8* %arrayidx39, align 1
377   %conv40 = zext i8 %8 to i32
378   %arrayidx41 = getelementptr inbounds i8, i8* %p2.045, i64 4
379   %9 = load i8, i8* %arrayidx41, align 1
380   %conv42 = zext i8 %9 to i32
381   %sub43 = sub nsw i32 %conv40, %conv42
382   %cmp44 = icmp slt i32 %sub43, 0
383   %sub47 = sub nsw i32 0, %sub43
384   %sub47.sub43 = select i1 %cmp44, i32 %sub47, i32 %sub43
385   %add49 = add nsw i32 %add38, %sub47.sub43
386   %arrayidx50 = getelementptr inbounds i8, i8* %p1.044, i64 5
387   %10 = load i8, i8* %arrayidx50, align 1
388   %conv51 = zext i8 %10 to i32
389   %arrayidx52 = getelementptr inbounds i8, i8* %p2.045, i64 5
390   %11 = load i8, i8* %arrayidx52, align 1
391   %conv53 = zext i8 %11 to i32
392   %sub54 = sub nsw i32 %conv51, %conv53
393   %cmp55 = icmp slt i32 %sub54, 0
394   %sub58 = sub nsw i32 0, %sub54
395   %v.5 = select i1 %cmp55, i32 %sub58, i32 %sub54
396   %add60 = add nsw i32 %add49, %v.5
397   %arrayidx61 = getelementptr inbounds i8, i8* %p1.044, i64 6
398   %12 = load i8, i8* %arrayidx61, align 1
399   %conv62 = zext i8 %12 to i32
400   %arrayidx63 = getelementptr inbounds i8, i8* %p2.045, i64 6
401   %13 = load i8, i8* %arrayidx63, align 1
402   %conv64 = zext i8 %13 to i32
403   %sub65 = sub nsw i32 %conv62, %conv64
404   %cmp66 = icmp slt i32 %sub65, 0
405   %sub69 = sub nsw i32 0, %sub65
406   %sub69.sub65 = select i1 %cmp66, i32 %sub69, i32 %sub65
407   %add71 = add nsw i32 %add60, %sub69.sub65
408   %arrayidx72 = getelementptr inbounds i8, i8* %p1.044, i64 7
409   %14 = load i8, i8* %arrayidx72, align 1
410   %conv73 = zext i8 %14 to i32
411   %arrayidx74 = getelementptr inbounds i8, i8* %p2.045, i64 7
412   %15 = load i8, i8* %arrayidx74, align 1
413   %conv75 = zext i8 %15 to i32
414   %sub76 = sub nsw i32 %conv73, %conv75
415   %cmp77 = icmp slt i32 %sub76, 0
416   %sub80 = sub nsw i32 0, %sub76
417   %v.7 = select i1 %cmp77, i32 %sub80, i32 %sub76
418   %add82 = add nsw i32 %add71, %v.7
419   %cmp83 = icmp slt i32 %add82, %lim
420   br i1 %cmp83, label %if.end.86, label %for.end.loopexit
422 if.end.86:                                        ; preds = %for.body
423   %add.ptr = getelementptr inbounds i8, i8* %p1.044, i64 %idx.ext
424   %add.ptr88 = getelementptr inbounds i8, i8* %p2.045, i64 %idx.ext
425   %inc = add nuw nsw i32 %j.046, 1
426   %cmp = icmp slt i32 %inc, %h
427   br i1 %cmp, label %for.body, label %for.end.loopexit
429 for.end.loopexit:                                 ; preds = %for.body, %if.end.86
430   br label %for.end
432 for.end:                                          ; preds = %for.end.loopexit, %entry
433   %s.1 = phi i32 [ 0, %entry ], [ %add82, %for.end.loopexit ]
434   ret i32 %s.1