600 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; REQUIRES: asserts3; RUN: opt -S < %s -p loop-vectorize -debug-only=loop-vectorize -force-vector-width=4 -disable-output 2>&1 | FileCheck %s4 5declare void @init_mem(ptr, i64);6 7; == SOME LEGAL EXAMPLES ==8 9; The form of the induction variables requires SCEV predicates.10define i32 @diff_exit_block_needs_scev_check(i32 %end) {11; CHECK-LABEL: LV: Checking a loop in 'diff_exit_block_needs_scev_check'12; CHECK: Found an early exit loop with symbolic max backedge taken count: (-1 + (1 umax (zext i10 (trunc i32 %end to i10) to i32)))<nsw>13; CHECK-NEXT: LV: We can vectorize this loop!14; CHECK-NOT: LV: Not vectorizing:15entry:16 %p1 = alloca [1024 x i32]17 %p2 = alloca [1024 x i32]18 call void @init_mem(ptr %p1, i64 1024)19 call void @init_mem(ptr %p2, i64 1024)20 %end.clamped = and i32 %end, 102321 br label %for.body22 23for.body:24 %ind = phi i8 [ %ind.next, %for.inc ], [ 0, %entry ]25 %gep.ind = phi i64 [ %gep.ind.next, %for.inc ], [ 0, %entry ]26 %arrayidx1 = getelementptr inbounds i32, ptr %p1, i64 %gep.ind27 %0 = load i32, ptr %arrayidx1, align 428 %arrayidx2 = getelementptr inbounds i32, ptr %p2, i64 %gep.ind29 %1 = load i32, ptr %arrayidx2, align 430 %cmp.early = icmp eq i32 %0, %131 br i1 %cmp.early, label %found, label %for.inc32 33for.inc:34 %ind.next = add i8 %ind, 135 %conv = zext i8 %ind.next to i3236 %gep.ind.next = add i64 %gep.ind, 137 %cmp = icmp ult i32 %conv, %end.clamped38 br i1 %cmp, label %for.body, label %exit39 40found:41 ret i32 142 43exit:44 ret i32 045}46 47 48define i64 @same_exit_block_pre_inc_use1() {49; CHECK-LABEL: LV: Checking a loop in 'same_exit_block_pre_inc_use1'50; CHECK: LV: Found an early exit loop with symbolic max backedge taken count: 6351; CHECK-NEXT: LV: We can vectorize this loop!52; CHECK-NOT: LV: Not vectorizing53entry:54 %p1 = alloca [1024 x i8]55 %p2 = alloca [1024 x i8]56 call void @init_mem(ptr %p1, i64 1024)57 call void @init_mem(ptr %p2, i64 1024)58 br label %loop59 60loop:61 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]62 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index63 %ld1 = load i8, ptr %arrayidx, align 164 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index65 %ld2 = load i8, ptr %arrayidx1, align 166 %cmp3 = icmp eq i8 %ld1, %ld267 br i1 %cmp3, label %loop.inc, label %loop.end68 69loop.inc:70 %index.next = add i64 %index, 171 %exitcond = icmp ne i64 %index.next, 6772 br i1 %exitcond, label %loop, label %loop.end73 74loop.end:75 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]76 ret i64 %retval77}78 79 80define i64 @loop_contains_safe_call() {81; CHECK-LABEL: LV: Checking a loop in 'loop_contains_safe_call'82; CHECK: LV: Found an early exit loop with symbolic max backedge taken count: 6383; CHECK-NEXT: LV: We can vectorize this loop!84entry:85 %p1 = alloca [1024 x i8]86 %p2 = alloca [1024 x i8]87 call void @init_mem(ptr %p1, i64 1024)88 call void @init_mem(ptr %p2, i64 1024)89 br label %loop90 91loop:92 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]93 %arrayidx = getelementptr inbounds float, ptr %p1, i64 %index94 %ld1 = load float, ptr %arrayidx, align 195 %sqrt = tail call fast float @llvm.sqrt.f32(float %ld1)96 %cmp = fcmp fast ult float %sqrt, 3.0e+0097 br i1 %cmp, label %loop.inc, label %loop.end98 99loop.inc:100 %index.next = add i64 %index, 1101 %exitcond = icmp ne i64 %index.next, 67102 br i1 %exitcond, label %loop, label %loop.end103 104loop.end:105 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]106 ret i64 %retval107}108 109 110define i64 @loop_contains_safe_div() {111; CHECK-LABEL: LV: Checking a loop in 'loop_contains_safe_div'112; CHECK: LV: Found an early exit loop with symbolic max backedge taken count: 63113; CHECK-NEXT: LV: We can vectorize this loop!114entry:115 %p1 = alloca [1024 x i8]116 %p2 = alloca [1024 x i8]117 call void @init_mem(ptr %p1, i64 1024)118 call void @init_mem(ptr %p2, i64 1024)119 br label %loop120 121loop:122 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]123 %arrayidx = getelementptr inbounds i32, ptr %p1, i64 %index124 %ld1 = load i32, ptr %arrayidx, align 1125 %div = udiv i32 %ld1, 20000126 %cmp = icmp eq i32 %div, 1127 br i1 %cmp, label %loop.inc, label %loop.end128 129loop.inc:130 %index.next = add i64 %index, 1131 %exitcond = icmp ne i64 %index.next, 67132 br i1 %exitcond, label %loop, label %loop.end133 134loop.end:135 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]136 ret i64 %retval137}138 139 140define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align(8) %p2) {141; CHECK-LABEL: LV: Checking a loop in 'loop_contains_load_after_early_exit'142; CHECK: LV: Found an early exit loop with symbolic max backedge taken count: 63143; CHECK-NEXT: LV: We can vectorize this loop!144; CHECK-NOT: LV: Not vectorizing145entry:146 %p1 = alloca [1024 x i8]147 call void @init_mem(ptr %p1, i64 1024)148 br label %loop149 150loop:151 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]152 %arrayidx = getelementptr inbounds i32, ptr %p1, i64 %index153 %ld1 = load i32, ptr %arrayidx, align 1154 %cmp = icmp eq i32 %ld1, 1155 br i1 %cmp, label %loop.inc, label %loop.end156 157loop.inc:158 %arrayidx2 = getelementptr inbounds i64, ptr %p2, i64 %index159 %ld2 = load i64, ptr %arrayidx2, align 8160 %index.next = add i64 %index, 1161 %exitcond = icmp ne i64 %index.next, 67162 br i1 %exitcond, label %loop, label %loop.end163 164loop.end:165 %retval = phi i64 [ %index, %loop ], [ %ld2, %loop.inc ]166 ret i64 %retval167}168 169 170define i64 @one_uncountable_two_countable_same_exit_phi_of_consts() {171; CHECK-LABEL: LV: Checking a loop in 'one_uncountable_two_countable_same_exit_phi_of_consts'172; CHECK: LV: Found an early exit loop with symbolic max backedge taken count: 61173; CHECK-NEXT: LV: We can vectorize this loop!174; CHECK-NEXT: LV: Not vectorizing: Auto-vectorization of early exit loops requiring a scalar epilogue is unsupported.175entry:176 %p1 = alloca [1024 x i8]177 %p2 = alloca [1024 x i8]178 call void @init_mem(ptr %p1, i64 1024)179 call void @init_mem(ptr %p2, i64 1024)180 br label %loop181 182loop:183 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]184 %cmp1 = icmp ne i64 %index, 64185 br i1 %cmp1, label %search, label %loop.end186 187search:188 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index189 %ld1 = load i8, ptr %arrayidx, align 1190 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index191 %ld2 = load i8, ptr %arrayidx1, align 1192 %cmp3 = icmp eq i8 %ld1, %ld2193 br i1 %cmp3, label %loop.end, label %loop.inc194 195loop.inc:196 %index.next = add i64 %index, 1197 %exitcond = icmp ne i64 %index.next, 128198 br i1 %exitcond, label %loop, label %loop.end199 200loop.end:201 %retval = phi i64 [ 0, %loop ], [ 1, %search ], [ 0, %loop.inc ]202 ret i64 %retval203}204 205 206; == SOME ILLEGAL EXAMPLES ==207 208 209define i64 @same_exit_block_pre_inc_use1_too_small_allocas() {210; CHECK-LABEL: LV: Checking a loop in 'same_exit_block_pre_inc_use1_too_small_allocas'211; CHECK: LV: Not vectorizing: Auto-vectorization of loops with potentially faulting load is not supported.212entry:213 %p1 = alloca [42 x i8]214 %p2 = alloca [42 x i8]215 call void @init_mem(ptr %p1, i64 1024)216 call void @init_mem(ptr %p2, i64 1024)217 br label %loop218 219loop:220 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]221 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index222 %ld1 = load i8, ptr %arrayidx, align 1223 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index224 %ld2 = load i8, ptr %arrayidx1, align 1225 %cmp3 = icmp eq i8 %ld1, %ld2226 br i1 %cmp3, label %loop.inc, label %loop.end227 228loop.inc:229 %index.next = add i64 %index, 1230 %exitcond = icmp ne i64 %index.next, 67231 br i1 %exitcond, label %loop, label %loop.end232 233loop.end:234 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]235 ret i64 %retval236}237 238 239define i64 @same_exit_block_pre_inc_use1_too_small_deref_ptrs(ptr dereferenceable(42) %p1, ptr dereferenceable(42) %p2) {240; CHECK-LABEL: LV: Checking a loop in 'same_exit_block_pre_inc_use1_too_small_deref_ptrs'241; CHECK: LV: Not vectorizing: Auto-vectorization of loops with potentially faulting load is not supported.242entry:243 br label %loop244 245loop:246 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]247 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index248 %ld1 = load i8, ptr %arrayidx, align 1249 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index250 %ld2 = load i8, ptr %arrayidx1, align 1251 %cmp3 = icmp eq i8 %ld1, %ld2252 br i1 %cmp3, label %loop.inc, label %loop.end253 254loop.inc:255 %index.next = add i64 %index, 1256 %exitcond = icmp ne i64 %index.next, 67257 br i1 %exitcond, label %loop, label %loop.end258 259loop.end:260 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]261 ret i64 %retval262}263 264 265define i64 @same_exit_block_pre_inc_use1_unknown_ptrs(ptr %p1, ptr %p2) {266; CHECK-LABEL: LV: Checking a loop in 'same_exit_block_pre_inc_use1_unknown_ptrs'267; CHECK: LV: Not vectorizing: Auto-vectorization of loops with potentially faulting load is not supported.268entry:269 br label %loop270 271loop:272 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]273 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index274 %ld1 = load i8, ptr %arrayidx, align 1275 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index276 %ld2 = load i8, ptr %arrayidx1, align 1277 %cmp3 = icmp eq i8 %ld1, %ld2278 br i1 %cmp3, label %loop.inc, label %loop.end279 280loop.inc:281 %index.next = add i64 %index, 1282 %exitcond = icmp ne i64 %index.next, 67283 br i1 %exitcond, label %loop, label %loop.end284 285loop.end:286 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]287 ret i64 %retval288}289 290define ptr @same_exit_block_strided_unknown_ptr(ptr %first, ptr %last, i32 %value) {291; CHECK-LABEL: LV: Checking a loop in 'same_exit_block_strided_unknown_ptr'292; CHECK: LV: Not vectorizing: Loop contains potentially faulting strided load.293entry:294 %cond = icmp eq ptr %first, %last295 br i1 %cond, label %return, label %for.body296 297for.body:298 %first.addr = phi ptr [ %first, %entry ], [ %first.next, %for.inc ]299 %1 = load i32, ptr %first.addr, align 4300 %cond2 = icmp eq i32 %1, %value301 br i1 %cond2, label %for.end, label %for.inc302 303for.inc:304 %first.next = getelementptr inbounds i32, ptr %first.addr, i64 2305 %cond3 = icmp eq ptr %first.next, %last306 br i1 %cond3, label %for.end, label %for.body307 308for.end:309 %retval.ph = phi ptr [ %first.addr, %for.body ], [ %last, %for.inc ]310 br label %return311 312return:313 %retval = phi ptr [ %first, %entry ], [ %retval.ph, %for.end ]314 ret ptr %retval315}316 317; The early exit (i.e. unknown exit-not-taken count) is the latch - we don't318; support this yet.319define i64 @uncountable_exit_on_last_block() {320; CHECK-LABEL: LV: Checking a loop in 'uncountable_exit_on_last_block'321; CHECK: LV: Not vectorizing: Early exit is not the latch predecessor.322entry:323 %p1 = alloca [1024 x i8]324 %p2 = alloca [1024 x i8]325 call void @init_mem(ptr %p1, i64 1024)326 call void @init_mem(ptr %p2, i64 1024)327 br label %loop328 329loop:330 %index = phi i64 [ %index.next, %search ], [ 3, %entry ]331 %index.next = add i64 %index, 1332 %exitcond = icmp ne i64 %index.next, 67333 br i1 %exitcond, label %search, label %loop.end334 335search:336 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index337 %ld1 = load i8, ptr %arrayidx, align 1338 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index339 %ld2 = load i8, ptr %arrayidx1, align 1340 %cmp3 = icmp eq i8 %ld1, %ld2341 br i1 %cmp3, label %loop.end, label %loop342 343loop.end:344 %retval = phi i64 [ 64, %loop ], [ %index, %search ]345 ret i64 %retval346}347 348 349; We don't currently support multiple uncountable early exits.350define i64 @multiple_uncountable_exits() {351; CHECK-LABEL: LV: Checking a loop in 'multiple_uncountable_exits'352; CHECK: LV: Not vectorizing: Loop has too many uncountable exits.353entry:354 %p1 = alloca [1024 x i8]355 %p2 = alloca [1024 x i8]356 call void @init_mem(ptr %p1, i64 1024)357 call void @init_mem(ptr %p2, i64 1024)358 br label %search1359 360search1:361 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]362 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index363 %ld1 = load i8, ptr %arrayidx, align 1364 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index365 %ld2 = load i8, ptr %arrayidx1, align 1366 %cmp1 = icmp eq i8 %ld1, %ld2367 br i1 %cmp1, label %loop.end, label %search2368 369search2:370 %cmp2 = icmp ult i8 %ld1, 34371 br i1 %cmp2, label %loop.end, label %loop.inc372 373loop.inc:374 %index.next = add i64 %index, 1375 %exitcond = icmp ne i64 %index.next, 67376 br i1 %exitcond, label %search1, label %loop.end377 378loop.end:379 %retval = phi i64 [ %index, %search1 ], [ 100, %search2 ], [ 43, %loop.inc ]380 ret i64 %retval381}382 383 384define i64 @uncountable_exit_infinite_loop() {385; CHECK-LABEL: LV: Checking a loop in 'uncountable_exit_infinite_loop'386; CHECK: LV: Not vectorizing: Cannot vectorize uncountable loop.387entry:388 %p1 = alloca [1024 x i8]389 %p2 = alloca [1024 x i8]390 call void @init_mem(ptr %p1, i64 1024)391 call void @init_mem(ptr %p2, i64 1024)392 br label %loop393 394loop:395 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]396 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index397 %ld1 = load i8, ptr %arrayidx, align 1398 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index399 %ld2 = load i8, ptr %arrayidx1, align 1400 %cmp3 = icmp eq i8 %ld1, %ld2401 br i1 %cmp3, label %loop.inc, label %loop.end402 403loop.inc:404 %index.next = add i64 %index, 1405 %exitcond = icmp ne i64 %index.next, 67406 br label %loop407 408loop.end:409 %retval = phi i64 [ %index, %loop ]410 ret i64 %retval411}412 413 414define i64 @loop_contains_unsafe_call() {415; CHECK-LABEL: LV: Checking a loop in 'loop_contains_unsafe_call'416; CHECK: LV: Not vectorizing: Early exit loop contains operations that cannot be speculatively executed.417entry:418 %p1 = alloca [1024 x i8]419 %p2 = alloca [1024 x i8]420 call void @init_mem(ptr %p1, i64 1024)421 call void @init_mem(ptr %p2, i64 1024)422 br label %loop423 424loop:425 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]426 %arrayidx = getelementptr inbounds i32, ptr %p1, i64 %index427 %ld1 = load i32, ptr %arrayidx, align 1428 %bad_call = call i32 @foo(i32 %ld1) #0429 %cmp = icmp eq i32 %bad_call, 34430 br i1 %cmp, label %loop.inc, label %loop.end431 432loop.inc:433 %index.next = add i64 %index, 1434 %exitcond = icmp ne i64 %index.next, 67435 br i1 %exitcond, label %loop, label %loop.end436 437loop.end:438 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]439 ret i64 %retval440}441 442 443define i64 @loop_contains_unsafe_div() {444; CHECK-LABEL: LV: Checking a loop in 'loop_contains_unsafe_div'445; CHECK: LV: Not vectorizing: Early exit loop contains operations that cannot be speculatively executed.446entry:447 %p1 = alloca [1024 x i8]448 %p2 = alloca [1024 x i8]449 call void @init_mem(ptr %p1, i64 1024)450 call void @init_mem(ptr %p2, i64 1024)451 br label %loop452 453loop:454 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]455 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index456 %ld1 = load i32, ptr %arrayidx, align 1457 %div = udiv i32 20000, %ld1458 %cmp = icmp eq i32 %div, 1459 br i1 %cmp, label %loop.inc, label %loop.end460 461loop.inc:462 %index.next = add i64 %index, 1463 %exitcond = icmp ne i64 %index.next, 67464 br i1 %exitcond, label %loop, label %loop.end465 466loop.end:467 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]468 ret i64 %retval469}470 471define void @exit_conditions_combined_in_single_branch(ptr noalias dereferenceable(40) %array, ptr readonly align 2 dereferenceable(40) %pred) {472; CHECK-LABEL: LV: Checking a loop in 'exit_conditions_combined_in_single_branch'473; CHECK: LV: Not vectorizing: Cannot vectorize uncountable loop.474entry:475 br label %for.body476 477for.body: ; preds = %for.body, %entry478 %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]479 %st.addr = getelementptr inbounds nuw i16, ptr %array, i64 %iv480 %data = load i16, ptr %st.addr, align 2481 %inc = add nsw i16 %data, 1482 store i16 %inc, ptr %st.addr, align 2483 %ee.addr = getelementptr inbounds nuw i16, ptr %pred, i64 %iv484 %ee.val = load i16, ptr %ee.addr, align 2485 %ee.cond = icmp sgt i16 %ee.val, 500486 %iv.next = add nuw nsw i64 %iv, 1487 %counted.cond = icmp eq i64 %iv.next, 20488 %or.cond = select i1 %ee.cond, i1 true, i1 %counted.cond489 br i1 %or.cond, label %exit, label %for.body490 491exit: ; preds = %for.body492 ret void493}494 495define i64 @uncountable_exit_in_conditional_block(ptr %mask) {496; CHECK-LABEL: LV: Checking a loop in 'uncountable_exit_in_conditional_block'497; CHECK: LV: Not vectorizing: Early exit is not the latch predecessor.498entry:499 %p1 = alloca [1024 x i8]500 %p2 = alloca [1024 x i8]501 call void @init_mem(ptr %p1, i64 1024)502 call void @init_mem(ptr %p2, i64 1024)503 br label %loop504 505loop:506 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]507 %arrayidx1 = getelementptr inbounds i8, ptr %mask, i64 %index508 %ld1 = load i8, ptr %arrayidx1, align 1509 %cmp1 = icmp ne i8 %ld1, 0510 br i1 %cmp1, label %loop.search, label %loop.inc511 512loop.search:513 %arrayidx2 = getelementptr inbounds i8, ptr %p1, i64 %index514 %ld2 = load i8, ptr %arrayidx2, align 1515 %arrayidx3 = getelementptr inbounds i8, ptr %p2, i64 %index516 %ld3 = load i8, ptr %arrayidx3, align 1517 %cmp2 = icmp eq i8 %ld2, %ld3518 br i1 %cmp2, label %loop.inc, label %loop.end519 520loop.inc:521 %index.next = add i64 %index, 1522 %exitcond = icmp ne i64 %index.next, 67523 br i1 %exitcond, label %loop, label %loop.end524 525loop.end:526 %retval = phi i64 [ %index, %loop.search ], [ 67, %loop.inc ]527 ret i64 %retval528}529 530 531define i64 @same_exit_block_pre_inc_use1_with_reduction() {532; CHECK-LABEL: LV: Checking a loop in 'same_exit_block_pre_inc_use1_with_reduction'533; CHECK: LV: Not vectorizing: Found reductions or recurrences in early-exit loop.534entry:535 %p1 = alloca [1024 x i8]536 %p2 = alloca [1024 x i8]537 call void @init_mem(ptr %p1, i64 1024)538 call void @init_mem(ptr %p2, i64 1024)539 br label %loop540 541loop:542 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]543 %red = phi i64 [ %red.next, %loop.inc ], [ 0, %entry ]544 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index545 %ld1 = load i8, ptr %arrayidx, align 1546 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index547 %ld2 = load i8, ptr %arrayidx1, align 1548 %ld2.zext = zext i8 %ld2 to i64549 %red.next = add i64 %red, %ld2.zext550 %cmp3 = icmp eq i8 %ld1, %ld2551 br i1 %cmp3, label %loop.inc, label %loop.end552 553loop.inc:554 %index.next = add i64 %index, 1555 %exitcond = icmp ne i64 %index.next, 67556 br i1 %exitcond, label %loop, label %loop.end557 558loop.end:559 %final.ind = phi i64 [ %index, %loop ], [ 67, %loop.inc ]560 %retval = add i64 %red.next, %final.ind561 ret i64 %retval562}563 564 565define i64 @uncountable_exit_has_multiple_outside_successors() {566; CHECK-LABEL: LV: Checking a loop in 'uncountable_exit_has_multiple_outside_successors'567; CHECK: LV: Not vectorizing: Loop contains an unsupported switch568entry:569 %p1 = alloca [1024 x i8]570 call void @init_mem(ptr %p1, i64 1024)571 br label %loop572 573loop:574 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]575 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index576 %ld1 = load i8, ptr %arrayidx, align 1577 switch i8 %ld1, label %loop.inc [578 i8 2, label %loop.end579 i8 3, label %loop.surprise580 ]581 582loop.inc:583 %index.next = add i64 %index, 1584 %exitcond = icmp ne i64 %index.next, 67585 br i1 %exitcond, label %loop, label %loop.end586 587loop.surprise:588 ret i64 3589 590loop.end:591 %retval = phi i64 [ %index, %loop ], [ 67, %loop.inc ]592 ret i64 %retval593}594 595 596declare i32 @foo(i32) readonly597declare <vscale x 4 x i32> @foo_vec(<vscale x 4 x i32>)598 599attributes #0 = { "vector-function-abi-variant"="_ZGVsNxv_foo(foo_vec)" }600