1; RUN: opt -S < %s -p loop-vectorize,'print<loops>' -disable-output -enable-early-exit-vectorization 2>&1 | FileCheck %s 2 3declare void @init_mem(ptr, i64); 4 5; Tests that the additional middle.split created for handling loops with 6; uncountable early exits is correctly adding to the outer loop at depth 1. 7define void @early_exit_in_outer_loop1() { 8; CHECK-LABEL: Loop info for function 'early_exit_in_outer_loop1': 9; CHECK: Loop at depth 1 containing: {{.*}}%middle.block,%scalar.ph,%vector.ph,%vector.body,%middle.split 10entry: 11 %p1 = alloca [1024 x i8] 12 %p2 = alloca [1024 x i8] 13 call void @init_mem(ptr %p1, i64 1024) 14 call void @init_mem(ptr %p2, i64 1024) 15 br label %loop.outer 16 17loop.outer: 18 %count = phi i64 [ 0, %entry ], [ %count.next, %loop.inner.end ] 19 br label %loop.inner 20 21loop.inner: 22 %index = phi i64 [ %index.next, %loop.inner.inc ], [ 3, %loop.outer ] 23 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index 24 %ld1 = load i8, ptr %arrayidx, align 1 25 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index 26 %ld2 = load i8, ptr %arrayidx1, align 1 27 %cmp3 = icmp eq i8 %ld1, %ld2 28 br i1 %cmp3, label %loop.inner.inc, label %loop.inner.found 29 30loop.inner.inc: 31 %index.next = add i64 %index, 1 32 %exitcond = icmp ne i64 %index.next, 67 33 br i1 %exitcond, label %loop.inner, label %loop.inner.end 34 35loop.inner.found: 36 br label %loop.inner.end 37 38loop.inner.end: 39 %count.next = phi i64 [ 0, %loop.inner.inc ], [ 1, %loop.inner.found ] 40 br label %loop.outer 41} 42 43; Tests that the additional middle.split created for handling loops with 44; uncountable early exits is correctly adding to both the outer and middle 45; loops at depths 1 and 2, respectively. 46define void @early_exit_in_outer_loop2() { 47; CHECK-LABEL: Loop info for function 'early_exit_in_outer_loop2': 48; CHECK: Loop at depth 1 containing: {{.*}}%middle.block,%scalar.ph,%vector.ph,%vector.body,%middle.split 49; CHECK: Loop at depth 2 containing: {{.*}}%middle.block,%scalar.ph,%vector.ph,%vector.body,%middle.split<exiting> 50entry: 51 %p1 = alloca [1024 x i8] 52 %p2 = alloca [1024 x i8] 53 call void @init_mem(ptr %p1, i64 1024) 54 call void @init_mem(ptr %p2, i64 1024) 55 br label %loop.outer 56 57loop.outer: 58 %count.outer = phi i64 [ 0, %entry ], [ %count.outer.next , %loop.outer.latch ] 59 br label %loop.middle 60 61loop.middle: 62 br label %loop.inner 63 64loop.inner: 65 %index = phi i64 [ %index.next, %loop.inner.inc ], [ 3, %loop.middle ] 66 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index 67 %ld1 = load i8, ptr %arrayidx, align 1 68 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index 69 %ld2 = load i8, ptr %arrayidx1, align 1 70 %cmp3 = icmp eq i8 %ld1, %ld2 71 br i1 %cmp3, label %loop.inner.inc, label %loop.inner.found 72 73loop.inner.inc: 74 %index.next = add i64 %index, 1 75 %exitcond = icmp ne i64 %index.next, 67 76 br i1 %exitcond, label %loop.inner, label %loop.inner.end 77 78loop.inner.end: 79 br i1 false, label %loop.middle, label %loop.middle.end 80 81loop.middle.end: 82 br label %loop.outer.latch 83 84loop.inner.found: 85 br label %loop.outer.latch 86 87loop.outer.latch: 88 %t = phi i64 [ 0, %loop.middle.end ], [ 1, %loop.inner.found ] 89 %count.outer.next = add i64 %count.outer, %t 90 br label %loop.outer 91} 92