llvm.org GIT mirror llvm / 531d8c4
[IRBuilder] Fold consistently for or/and whether constant is LHS or RHS Without this, we have the unfortunate property that tests are dependent on the order of operads passed the CreateOr and CreateAnd functions. In actual usage, we'd promptly optimize them away, but it made tests slightly more verbose than they should have been. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365260 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 2 months ago
10 changed file(s) with 85 addition(s) and 103 deletion(s). Raw diff Collapse all Expand all
11961196 }
11971197
11981198 Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
1199 if (auto *LC = dyn_cast(LHS))
1200 if (LC->isMinusOne())
1201 return RHS; // -1 & RHS = RHS
11991202 if (auto *RC = dyn_cast(RHS)) {
12001203 if (isa(RC) && cast(RC)->isMinusOne())
12011204 return LHS; // LHS & -1 -> LHS
12221225 }
12231226
12241227 Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
1228 if (auto *LC = dyn_cast(LHS))
1229 if (LC->isNullValue())
1230 return RHS; // 0 | RHS -> RHS
12251231 if (auto *RC = dyn_cast(RHS)) {
12261232 if (RC->isNullValue())
12271233 return LHS; // LHS | 0 -> LHS
5252 ; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
5353 ; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
5454
55 ; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
56
5755 ; LV-NEXT: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE]])
5856 ; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
5957 ; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
6462 ; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg1]], i1 [[CmpPos1]]
6563 ; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
6664
67 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
65 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[PredCheck0]], [[PredCheck1]]
6866 ; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
6967 define void @f1(i16* noalias %a,
7068 i16* noalias %b, i64 %N) {
146144 ; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
147145 ; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
148146 ; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
149
150 ; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
151
152147 ; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE]])
153148 ; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
154149 ; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
159154 ; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg1]], i1 [[CmpPos1]]
160155 ; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
161156
162 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
157 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[PredCheck0]], [[PredCheck1]]
163158 ; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
164159 define void @f2(i16* noalias %a,
165160 i16* noalias %b, i64 %N) {
226221 ; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
227222 ; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
228223 ; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
229
230 ; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
231
232224 ; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]])
233225 ; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
234226 ; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
239231 ; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg1]], i1 [[CmpPos1]]
240232 ; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
241233
242 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
234 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[PredCheck0]], [[PredCheck1]]
243235 ; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
244236 define void @f3(i16* noalias %a,
245237 i16* noalias %b, i64 %N) {
302294 ; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
303295 ; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
304296 ; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
305
306 ; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
307
308297 ; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]])
309298 ; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
310299 ; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
315304 ; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg1]], i1 [[CmpPos1]]
316305 ; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
317306
318 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
307 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[PredCheck0]], [[PredCheck1]]
319308 ; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
320309 define void @f4(i16* noalias %a,
321310 i16* noalias %b, i64 %N) {
380369 ; LV-NEXT: [[BECheck:%[^ ]*]] = icmp ugt i64 [[BE]], 4294967295
381370 ; LV-NEXT: [[CheckOr0:%[^ ]*]] = or i1 [[Cmp]], [[BECheck]]
382371 ; LV-NEXT: [[PredCheck0:%[^ ]*]] = or i1 [[CheckOr0]], [[OFMulOverflow]]
383
384 ; LV-NEXT: [[Or0:%[^ ]*]] = or i1 false, [[PredCheck0]]
385
386372 ; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]])
387373 ; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0
388374 ; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1
393379 ; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 true, i1 [[CmpNeg1]], i1 [[CmpPos1]]
394380 ; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]]
395381
396 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[Or0]], [[PredCheck1]]
382 ; LV: [[FinalCheck:%[^ ]*]] = or i1 [[PredCheck0]], [[PredCheck1]]
397383 ; LV: br i1 [[FinalCheck]], label %for.body.ph.lver.orig, label %for.body.ph
398384 define void @f5(i16* noalias %a,
399385 i16* noalias %b, i64 %N) {
4949 ; CHECK: mul i64 {{.*}}, 4
5050 ; CHECK: sub i64 4000, %
5151 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
52 ; CHECK-NEXT: or i1
5352 ; CHECK: trap
5453 %1 = load i32, i32* %arrayidx.i, align 4
5554 %add.i = add nsw i32 %1, %sum.01.i
242241 ; CHECK: add i64
243242 ; CHECK: sub i64 16, %
244243 ; CHECK-NEXT: icmp ult i64 {{.*}}, 4
245 ; CHECK-NEXT: or i1
246244 ; CHECK: trap
247245 %1 = load i32, i32* %arrayidx7, align 4
248246 %add = add nsw i32 %1, %sum.119
2424 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i64 [[TMP0]], 4294967295
2525 ; CHECK-NEXT: [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
2626 ; CHECK-NEXT: [[TMP9:%.*]] = or i1 [[TMP8]], [[MUL_OVERFLOW]]
27 ; CHECK-NEXT: [[TMP10:%.*]] = or i1 false, [[TMP9]]
2827 ; CHECK-NEXT: [[MUL3:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 8, i64 [[TMP0]])
2928 ; CHECK-NEXT: [[MUL_RESULT4:%.*]] = extractvalue { i64, i1 } [[MUL3]], 0
3029 ; CHECK-NEXT: [[MUL_OVERFLOW5:%.*]] = extractvalue { i64, i1 } [[MUL3]], 1
31 ; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[A2]], [[MUL_RESULT4]]
32 ; CHECK-NEXT: [[TMP12:%.*]] = sub i64 [[A2]], [[MUL_RESULT4]]
33 ; CHECK-NEXT: [[TMP13:%.*]] = icmp ugt i64 [[TMP12]], [[A2]]
34 ; CHECK-NEXT: [[TMP14:%.*]] = icmp ult i64 [[TMP11]], [[A2]]
35 ; CHECK-NEXT: [[TMP15:%.*]] = select i1 false, i1 [[TMP13]], i1 [[TMP14]]
36 ; CHECK-NEXT: [[TMP16:%.*]] = or i1 [[TMP15]], [[MUL_OVERFLOW5]]
37 ; CHECK-NEXT: [[TMP17:%.*]] = or i1 [[TMP10]], [[TMP16]]
38 ; CHECK-NEXT: br i1 [[TMP17]], label [[FOR_BODY_PH_LVER_ORIG:%.*]], label [[FOR_BODY_PH_LDIST1:%.*]]
30 ; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[A2]], [[MUL_RESULT4]]
31 ; CHECK-NEXT: [[TMP11:%.*]] = sub i64 [[A2]], [[MUL_RESULT4]]
32 ; CHECK-NEXT: [[TMP12:%.*]] = icmp ugt i64 [[TMP11]], [[A2]]
33 ; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i64 [[TMP10]], [[A2]]
34 ; CHECK-NEXT: [[TMP14:%.*]] = select i1 false, i1 [[TMP12]], i1 [[TMP13]]
35 ; CHECK-NEXT: [[TMP15:%.*]] = or i1 [[TMP14]], [[MUL_OVERFLOW5]]
36 ; CHECK-NEXT: [[TMP16:%.*]] = or i1 [[TMP9]], [[TMP15]]
37 ; CHECK-NEXT: br i1 [[TMP16]], label [[FOR_BODY_PH_LVER_ORIG:%.*]], label [[FOR_BODY_PH_LDIST1:%.*]]
3938 ; CHECK: for.body.ph.lver.orig:
4039 ; CHECK-NEXT: br label [[FOR_BODY_LVER_ORIG:%.*]]
4140 ; CHECK: for.body.lver.orig:
6968 ; CHECK-NEXT: [[MUL_LDIST1:%.*]] = mul i32 [[IND1_LDIST1]], 2
7069 ; CHECK-NEXT: [[MUL_EXT_LDIST1:%.*]] = zext i32 [[MUL_LDIST1]] to i64
7170 ; CHECK-NEXT: [[ARRAYIDXA_LDIST1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[MUL_EXT_LDIST1]]
72 ; CHECK-NEXT: [[LOADA_LDIST1:%.*]] = load i32, i32* [[ARRAYIDXA_LDIST1]], align 4
71 ; CHECK-NEXT: [[LOADA_LDIST1:%.*]] = load i32, i32* [[ARRAYIDXA_LDIST1]], align 4, !alias.scope !0
7372 ; CHECK-NEXT: [[ARRAYIDXB_LDIST1:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[MUL_EXT_LDIST1]]
74 ; CHECK-NEXT: [[LOADB_LDIST1:%.*]] = load i32, i32* [[ARRAYIDXB_LDIST1]], align 4
73 ; CHECK-NEXT: [[LOADB_LDIST1:%.*]] = load i32, i32* [[ARRAYIDXB_LDIST1]], align 4, !alias.scope !3
7574 ; CHECK-NEXT: [[MULA_LDIST1:%.*]] = mul i32 [[LOADB_LDIST1]], [[LOADA_LDIST1]]
7675 ; CHECK-NEXT: [[ADD_LDIST1]] = add nuw nsw i64 [[IND_LDIST1]], 1
7776 ; CHECK-NEXT: [[INC1_LDIST1]] = add i32 [[IND1_LDIST1]], 1
7877 ; CHECK-NEXT: [[ARRAYIDXA_PLUS_4_LDIST1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[ADD_LDIST1]]
79 ; CHECK-NEXT: store i32 [[MULA_LDIST1]], i32* [[ARRAYIDXA_PLUS_4_LDIST1]], align 4
78 ; CHECK-NEXT: store i32 [[MULA_LDIST1]], i32* [[ARRAYIDXA_PLUS_4_LDIST1]], align 4, !alias.scope !5
8079 ; CHECK-NEXT: [[EXITCOND_LDIST1:%.*]] = icmp eq i64 [[ADD_LDIST1]], [[N]]
8180 ; CHECK-NEXT: br i1 [[EXITCOND_LDIST1]], label [[FOR_BODY_PH:%.*]], label [[FOR_BODY_LDIST1]]
8281 ; CHECK: for.body.ph:
8988 ; CHECK-NEXT: [[ADD]] = add nuw nsw i64 [[IND]], 1
9089 ; CHECK-NEXT: [[INC1]] = add i32 [[IND1]], 1
9190 ; CHECK-NEXT: [[ARRAYIDXD:%.*]] = getelementptr inbounds i32, i32* [[D]], i64 [[MUL_EXT]]
92 ; CHECK-NEXT: [[LOADD:%.*]] = load i32, i32* [[ARRAYIDXD]], align 4
91 ; CHECK-NEXT: [[LOADD:%.*]] = load i32, i32* [[ARRAYIDXD]], align 4, !alias.scope !7
9392 ; CHECK-NEXT: [[ARRAYIDXE:%.*]] = getelementptr inbounds i32, i32* [[E]], i64 [[MUL_EXT]]
94 ; CHECK-NEXT: [[LOADE:%.*]] = load i32, i32* [[ARRAYIDXE]], align 4
93 ; CHECK-NEXT: [[LOADE:%.*]] = load i32, i32* [[ARRAYIDXE]], align 4, !alias.scope !9
9594 ; CHECK-NEXT: [[MULC:%.*]] = mul i32 [[LOADD]], [[LOADE]]
9695 ; CHECK-NEXT: [[ARRAYIDXC:%.*]] = getelementptr inbounds i32, i32* [[C]], i64 [[MUL_EXT]]
97 ; CHECK-NEXT: store i32 [[MULC]], i32* [[ARRAYIDXC]], align 4
96 ; CHECK-NEXT: store i32 [[MULC]], i32* [[ARRAYIDXC]], align 4, !alias.scope !11
9897 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[ADD]], [[N]]
9998 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]]
10099 ; CHECK: for.end:
231231 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
232232 ; CHECK: loop.preheader:
233233 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
234 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]]
235 ; CHECK-NEXT: br label [[LOOP:%.*]]
236 ; CHECK: loop:
237 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
238 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
239 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
234 ; CHECK-NEXT: br label [[LOOP:%.*]]
235 ; CHECK: loop:
236 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
237 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
238 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP0]], i32 9) [ "deopt"() ]
240239 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
241240 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
242241 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
281281 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
282282 ; CHECK: loop.preheader:
283283 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
284 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]]
285 ; CHECK-NEXT: br label [[LOOP:%.*]]
286 ; CHECK: loop:
287 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
288 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
289 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
290 ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
291 ; CHECK-NEXT: br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
284 ; CHECK-NEXT: br label [[LOOP:%.*]]
285 ; CHECK: loop:
286 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
287 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
288 ; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
289 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[WIDENABLE_COND]]
290 ; CHECK-NEXT: br i1 [[TMP1]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
292291 ; CHECK: deopt:
293292 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
294293 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
384384 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
385385 ; CHECK: loop.preheader:
386386 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], 20
387 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]]
388 ; CHECK-NEXT: br label [[LOOP:%.*]]
389 ; CHECK: loop:
390 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
391 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
392 ; CHECK-NEXT: [[UNKNOWN:%.*]] = load volatile i1, i1* @UNKNOWN
393 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[UNKNOWN]]) [ "deopt"() ]
394 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
387 ; CHECK-NEXT: br label [[LOOP:%.*]]
388 ; CHECK: loop:
389 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
390 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
391 ; CHECK-NEXT: [[UNKNOWN:%.*]] = load volatile i1, i1* @UNKNOWN
392 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[UNKNOWN]]) [ "deopt"() ]
393 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP0]], i32 9) [ "deopt"() ]
395394 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
396395 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
397396 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
7070 ; CHECK-NEXT: [[TMP13:%.*]] = icmp slt i32 [[TMP10]], [[TMP8]]
7171 ; CHECK-NEXT: [[TMP14:%.*]] = select i1 false, i1 [[TMP12]], i1 [[TMP13]]
7272 ; CHECK-NEXT: [[TMP15:%.*]] = or i1 [[TMP14]], [[MUL_OVERFLOW]]
73 ; CHECK-NEXT: [[TMP16:%.*]] = or i1 false, [[TMP15]]
74 ; CHECK-NEXT: br i1 [[TMP16]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
73 ; CHECK-NEXT: br i1 [[TMP15]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
7574 ; CHECK: vector.ph:
7675 ; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 4
7776 ; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
7877 ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
7978 ; CHECK: vector.body:
8079 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
81 ; CHECK-NEXT: [[TMP17:%.*]] = trunc i64 [[INDEX]] to i32
82 ; CHECK-NEXT: [[TMP18:%.*]] = add i32 [[TMP17]], 0
83 ; CHECK-NEXT: [[TMP19:%.*]] = add i32 [[ADD_US]], [[TMP18]]
84 ; CHECK-NEXT: [[TMP20:%.*]] = sext i32 [[TMP19]] to i64
85 ; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[TMP20]]
86 ; CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds i32, i32* [[TMP21]], i32 0
87 ; CHECK-NEXT: [[TMP23:%.*]] = bitcast i32* [[TMP22]] to <4 x i32>*
88 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP23]], align 4
89 ; CHECK-NEXT: [[TMP24:%.*]] = add nsw <4 x i32> [[WIDE_LOAD]],
90 ; CHECK-NEXT: [[TMP25:%.*]] = extractelement <4 x i32> [[TMP24]], i32 0
80 ; CHECK-NEXT: [[TMP16:%.*]] = trunc i64 [[INDEX]] to i32
81 ; CHECK-NEXT: [[TMP17:%.*]] = add i32 [[TMP16]], 0
82 ; CHECK-NEXT: [[TMP18:%.*]] = add i32 [[ADD_US]], [[TMP17]]
83 ; CHECK-NEXT: [[TMP19:%.*]] = sext i32 [[TMP18]] to i64
84 ; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[TMP19]]
85 ; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds i32, i32* [[TMP20]], i32 0
86 ; CHECK-NEXT: [[TMP22:%.*]] = bitcast i32* [[TMP21]] to <4 x i32>*
87 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP22]], align 4
88 ; CHECK-NEXT: [[TMP23:%.*]] = add nsw <4 x i32> [[WIDE_LOAD]],
89 ; CHECK-NEXT: [[TMP24:%.*]] = extractelement <4 x i32> [[TMP23]], i32 0
90 ; CHECK-NEXT: store i32 [[TMP24]], i32* [[ARRAYIDX7_US]], align 4, !llvm.mem.parallel_loop_access !0
91 ; CHECK-NEXT: [[TMP25:%.*]] = extractelement <4 x i32> [[TMP23]], i32 1
9192 ; CHECK-NEXT: store i32 [[TMP25]], i32* [[ARRAYIDX7_US]], align 4, !llvm.mem.parallel_loop_access !0
92 ; CHECK-NEXT: [[TMP26:%.*]] = extractelement <4 x i32> [[TMP24]], i32 1
93 ; CHECK-NEXT: [[TMP26:%.*]] = extractelement <4 x i32> [[TMP23]], i32 2
9394 ; CHECK-NEXT: store i32 [[TMP26]], i32* [[ARRAYIDX7_US]], align 4, !llvm.mem.parallel_loop_access !0
94 ; CHECK-NEXT: [[TMP27:%.*]] = extractelement <4 x i32> [[TMP24]], i32 2
95 ; CHECK-NEXT: [[TMP27:%.*]] = extractelement <4 x i32> [[TMP23]], i32 3
9596 ; CHECK-NEXT: store i32 [[TMP27]], i32* [[ARRAYIDX7_US]], align 4, !llvm.mem.parallel_loop_access !0
96 ; CHECK-NEXT: [[TMP28:%.*]] = extractelement <4 x i32> [[TMP24]], i32 3
97 ; CHECK-NEXT: store i32 [[TMP28]], i32* [[ARRAYIDX7_US]], align 4, !llvm.mem.parallel_loop_access !0
9897 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 4
99 ; CHECK-NEXT: [[TMP29:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
100 ; CHECK-NEXT: br i1 [[TMP29]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !5
98 ; CHECK-NEXT: [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
99 ; CHECK-NEXT: br i1 [[TMP28]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !5
101100 ; CHECK: middle.block:
102101 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
103102 ; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END_US]], label [[SCALAR_PH]]
3939 ; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32
4040 ; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], 1
4141 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i32 [[TMP2]], [[TMP4]]
42 ; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP6]], i32 [[TMP2]], i32 [[TMP4]]
43 ; CHECK-NEXT: [[TMP7:%.*]] = sub i32 [[TMP5]], [[UMAX]]
42 ; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP6]], i32 [[TMP2]], i32 [[TMP4]]
43 ; CHECK-NEXT: [[TMP7:%.*]] = sub i32 [[TMP5]], [[UMIN]]
4444 ; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP7]], 8
4545 ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_SCEVCHECK:%.*]]
4646 ; CHECK: vector.scevcheck:
4747 ; CHECK-NEXT: [[TMP8:%.*]] = add i8 [[CONV3]], -1
4848 ; CHECK-NEXT: [[TMP9:%.*]] = zext i8 [[TMP8]] to i32
4949 ; CHECK-NEXT: [[TMP10:%.*]] = icmp ult i32 [[TMP2]], [[TMP9]]
50 ; CHECK-NEXT: [[UMAX1:%.*]] = select i1 [[TMP10]], i32 [[TMP2]], i32 [[TMP9]]
51 ; CHECK-NEXT: [[TMP11:%.*]] = sub i32 [[TMP9]], [[UMAX1]]
50 ; CHECK-NEXT: [[UMIN1:%.*]] = select i1 [[TMP10]], i32 [[TMP2]], i32 [[TMP9]]
51 ; CHECK-NEXT: [[TMP11:%.*]] = sub i32 [[TMP9]], [[UMIN1]]
5252 ; CHECK-NEXT: [[TMP12:%.*]] = trunc i32 [[TMP11]] to i8
5353 ; CHECK-NEXT: [[MUL:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 1, i8 [[TMP12]])
5454 ; CHECK-NEXT: [[MUL_RESULT:%.*]] = extractvalue { i8, i1 } [[MUL]], 0
6161 ; CHECK-NEXT: [[TMP18:%.*]] = icmp ugt i32 [[TMP11]], 255
6262 ; CHECK-NEXT: [[TMP19:%.*]] = or i1 [[TMP17]], [[TMP18]]
6363 ; CHECK-NEXT: [[TMP20:%.*]] = or i1 [[TMP19]], [[MUL_OVERFLOW]]
64 ; CHECK-NEXT: [[TMP21:%.*]] = or i1 false, [[TMP20]]
65 ; CHECK-NEXT: br i1 [[TMP21]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
64 ; CHECK-NEXT: br i1 [[TMP20]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
6665 ; CHECK: vector.ph:
6766 ; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP7]], 8
6867 ; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP7]], [[N_MOD_VF]]
6968 ; CHECK-NEXT: [[CAST_CRD:%.*]] = trunc i32 [[N_VEC]] to i8
7069 ; CHECK-NEXT: [[IND_END:%.*]] = sub i8 [[CONV3]], [[CAST_CRD]]
71 ; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i32> zeroinitializer, i32 [[DOTPROMOTED]], i32 0
70 ; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i32> zeroinitializer, i32 [[DOTPROMOTED]], i32 0
7271 ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
7372 ; CHECK: vector.body:
7473 ; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
75 ; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ [[TMP22]], [[VECTOR_PH]] ], [ [[TMP26:%.*]], [[VECTOR_BODY]] ]
76 ; CHECK-NEXT: [[VEC_PHI2:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP27:%.*]], [[VECTOR_BODY]] ]
77 ; CHECK-NEXT: [[TMP23:%.*]] = trunc i32 [[INDEX]] to i8
78 ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = sub i8 [[CONV3]], [[TMP23]]
74 ; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ [[TMP21]], [[VECTOR_PH]] ], [ [[TMP25:%.*]], [[VECTOR_BODY]] ]
75 ; CHECK-NEXT: [[VEC_PHI2:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP26:%.*]], [[VECTOR_BODY]] ]
76 ; CHECK-NEXT: [[TMP22:%.*]] = trunc i32 [[INDEX]] to i8
77 ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = sub i8 [[CONV3]], [[TMP22]]
7978 ; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i8> undef, i8 [[OFFSET_IDX]], i32 0
8079 ; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i8> [[BROADCAST_SPLATINSERT]], <4 x i8> undef, <4 x i32> zeroinitializer
8180 ; CHECK-NEXT: [[INDUCTION:%.*]] = add <4 x i8> [[BROADCAST_SPLAT]],
8281 ; CHECK-NEXT: [[INDUCTION3:%.*]] = add <4 x i8> [[BROADCAST_SPLAT]],
83 ; CHECK-NEXT: [[TMP24:%.*]] = add i8 [[OFFSET_IDX]], 0
84 ; CHECK-NEXT: [[TMP25:%.*]] = add i8 [[OFFSET_IDX]], -4
85 ; CHECK-NEXT: [[TMP26]] = add <4 x i32> [[VEC_PHI]],
86 ; CHECK-NEXT: [[TMP27]] = add <4 x i32> [[VEC_PHI2]],
82 ; CHECK-NEXT: [[TMP23:%.*]] = add i8 [[OFFSET_IDX]], 0
83 ; CHECK-NEXT: [[TMP24:%.*]] = add i8 [[OFFSET_IDX]], -4
84 ; CHECK-NEXT: [[TMP25]] = add <4 x i32> [[VEC_PHI]],
85 ; CHECK-NEXT: [[TMP26]] = add <4 x i32> [[VEC_PHI2]],
86 ; CHECK-NEXT: [[TMP27:%.*]] = add i8 [[TMP23]], -1
8787 ; CHECK-NEXT: [[TMP28:%.*]] = add i8 [[TMP24]], -1
88 ; CHECK-NEXT: [[TMP29:%.*]] = add i8 [[TMP25]], -1
88 ; CHECK-NEXT: [[TMP29:%.*]] = zext i8 [[TMP27]] to i32
8989 ; CHECK-NEXT: [[TMP30:%.*]] = zext i8 [[TMP28]] to i32
90 ; CHECK-NEXT: [[TMP31:%.*]] = zext i8 [[TMP29]] to i32
9190 ; CHECK-NEXT: [[INDEX_NEXT]] = add i32 [[INDEX]], 8
92 ; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
93 ; CHECK-NEXT: br i1 [[TMP32]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !0
91 ; CHECK-NEXT: [[TMP31:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
92 ; CHECK-NEXT: br i1 [[TMP31]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !0
9493 ; CHECK: middle.block:
95 ; CHECK-NEXT: [[BIN_RDX:%.*]] = add <4 x i32> [[TMP27]], [[TMP26]]
94 ; CHECK-NEXT: [[BIN_RDX:%.*]] = add <4 x i32> [[TMP26]], [[TMP25]]
9695 ; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <4 x i32> [[BIN_RDX]], <4 x i32> undef, <4 x i32>
9796 ; CHECK-NEXT: [[BIN_RDX4:%.*]] = add <4 x i32> [[BIN_RDX]], [[RDX_SHUF]]
9897 ; CHECK-NEXT: [[RDX_SHUF5:%.*]] = shufflevector <4 x i32> [[BIN_RDX4]], <4 x i32> undef, <4 x i32>
9998 ; CHECK-NEXT: [[BIN_RDX6:%.*]] = add <4 x i32> [[BIN_RDX4]], [[RDX_SHUF5]]
100 ; CHECK-NEXT: [[TMP33:%.*]] = extractelement <4 x i32> [[BIN_RDX6]], i32 0
99 ; CHECK-NEXT: [[TMP32:%.*]] = extractelement <4 x i32> [[BIN_RDX6]], i32 0
101100 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP7]], [[N_VEC]]
102101 ; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_COND4_FOR_INC9_CRIT_EDGE:%.*]], label [[SCALAR_PH]]
103102 ; CHECK: scalar.ph:
104103 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i8 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[CONV3]], [[FOR_BODY8_LR_PH]] ], [ [[CONV3]], [[VECTOR_SCEVCHECK]] ]
105 ; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ [[DOTPROMOTED]], [[FOR_BODY8_LR_PH]] ], [ [[DOTPROMOTED]], [[VECTOR_SCEVCHECK]] ], [ [[TMP33]], [[MIDDLE_BLOCK]] ]
104 ; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ [[DOTPROMOTED]], [[FOR_BODY8_LR_PH]] ], [ [[DOTPROMOTED]], [[VECTOR_SCEVCHECK]] ], [ [[TMP32]], [[MIDDLE_BLOCK]] ]
106105 ; CHECK-NEXT: br label [[FOR_BODY8:%.*]]
107106 ; CHECK: for.body8:
108107 ; CHECK-NEXT: [[INC5:%.*]] = phi i32 [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY8]] ]
113112 ; CHECK-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP2]], [[CONV5]]
114113 ; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY8]], label [[FOR_COND4_FOR_INC9_CRIT_EDGE]], !llvm.loop !2
115114 ; CHECK: for.cond4.for.inc9_crit_edge:
116 ; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_BODY8]] ], [ [[TMP33]], [[MIDDLE_BLOCK]] ]
115 ; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_BODY8]] ], [ [[TMP32]], [[MIDDLE_BLOCK]] ]
117116 ; CHECK-NEXT: store i32 [[INC_LCSSA]], i32* getelementptr inbounds ([192 x [192 x i32]], [192 x [192 x i32]]* @a, i64 0, i64 0, i64 0), align 16
118117 ; CHECK-NEXT: br label [[FOR_INC9]]
119118 ; CHECK: for.inc9:
3232 ; CHECK: %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 {{.*}}, i8 {{.*}})
3333 ; CHECK-NOT: %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 {{.*}}, i8 {{.*}})
3434 ; CHECK: %[[TEST:[0-9]+]] = or i1 {{.*}}, %mul.overflow
35 ; CHECK: %[[NTEST:[0-9]+]] = or i1 false, %[[TEST]]
3635 ; CHECK: %ident.check = icmp ne i32 {{.*}}, %{{.*}}
37 ; CHECK: %{{.*}} = or i1 %[[NTEST]], %ident.check
36 ; CHECK: %{{.*}} = or i1 %[[TEST]], %ident.check
3837 ; CHECK-NOT: %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 {{.*}}, i8 {{.*}})
3938 ; CHECK: vector.body:
4039 ; CHECK: <4 x i32>
9190 ; CHECK: %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 {{.*}}, i8 {{.*}})
9291 ; CHECK-NOT: %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 {{.*}}, i8 {{.*}})
9392 ; CHECK: %[[TEST:[0-9]+]] = or i1 {{.*}}, %mul.overflow
94 ; CHECK: %[[NTEST:[0-9]+]] = or i1 false, %[[TEST]]
9593 ; CHECK: %[[EXT:[0-9]+]] = sext i8 {{.*}} to i32
9694 ; CHECK: %ident.check = icmp ne i32 {{.*}}, %[[EXT]]
97 ; CHECK: %{{.*}} = or i1 %[[NTEST]], %ident.check
95 ; CHECK: %{{.*}} = or i1 %[[TEST]], %ident.check
9896 ; CHECK-NOT: %mul = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 {{.*}}, i8 {{.*}})
9997 ; CHECK: vector.body:
10098 ; CHECK: <4 x i32>