1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt -S < %s -p loop-vectorize -enable-early-exit-vectorization | FileCheck %s
4 declare void @init_mem(ptr, i64);
6 ; There are multiple exit blocks - two of them have an exact representation for the
7 ; exit-not-taken counts and the other is unknown, i.e. the "early exit".
8 define i64 @one_uncountable_two_countable_same_exit() {
9 ; CHECK-LABEL: define i64 @one_uncountable_two_countable_same_exit() {
11 ; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1
12 ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1
13 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)
14 ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024)
15 ; CHECK-NEXT: br label [[LOOP:%.*]]
17 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
18 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i64 [[INDEX]], 64
19 ; CHECK-NEXT: br i1 [[CMP1]], label [[SEARCH:%.*]], label [[LOOP_END:%.*]]
21 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
22 ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
23 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
24 ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
25 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
26 ; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_END]], label [[LOOP_INC]]
28 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1
29 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 128
30 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]
32 ; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 64, [[LOOP]] ], [ [[INDEX]], [[SEARCH]] ], [ 128, [[LOOP_INC]] ]
33 ; CHECK-NEXT: ret i64 [[RETVAL]]
36 %p1 = alloca [1024 x i8]
37 %p2 = alloca [1024 x i8]
38 call void @init_mem(ptr %p1, i64 1024)
39 call void @init_mem(ptr %p2, i64 1024)
43 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
44 %cmp1 = icmp ne i64 %index, 64
45 br i1 %cmp1, label %search, label %loop.end
48 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
49 %ld1 = load i8, ptr %arrayidx, align 1
50 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
51 %ld2 = load i8, ptr %arrayidx1, align 1
52 %cmp3 = icmp eq i8 %ld1, %ld2
53 br i1 %cmp3, label %loop.end, label %loop.inc
56 %index.next = add i64 %index, 1
57 %exitcond = icmp ne i64 %index.next, 128
58 br i1 %exitcond, label %loop, label %loop.end
61 %retval = phi i64 [ 64, %loop ], [ %index, %search ], [ 128, %loop.inc ]
66 define i64 @one_uncountable_two_countable_diff_exit() {
67 ; CHECK-LABEL: define i64 @one_uncountable_two_countable_diff_exit() {
69 ; CHECK-NEXT: [[P1:%.*]] = alloca [1024 x i8], align 1
70 ; CHECK-NEXT: [[P2:%.*]] = alloca [1024 x i8], align 1
71 ; CHECK-NEXT: call void @init_mem(ptr [[P1]], i64 1024)
72 ; CHECK-NEXT: call void @init_mem(ptr [[P2]], i64 1024)
73 ; CHECK-NEXT: br label [[LOOP:%.*]]
75 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
76 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i64 [[INDEX]], 64
77 ; CHECK-NEXT: br i1 [[CMP1]], label [[SEARCH:%.*]], label [[LOOP_END:%.*]]
79 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
80 ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
81 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
82 ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
83 ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
84 ; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_END_EARLY:%.*]], label [[LOOP_INC]]
86 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1
87 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 128
88 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]
89 ; CHECK: loop.end.early:
90 ; CHECK-NEXT: [[RET_EARLY:%.*]] = phi i64 [ [[INDEX]], [[SEARCH]] ]
91 ; CHECK-NEXT: ret i64 [[RET_EARLY]]
93 ; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 64, [[LOOP]] ], [ 128, [[LOOP_INC]] ]
94 ; CHECK-NEXT: ret i64 [[RETVAL]]
97 %p1 = alloca [1024 x i8]
98 %p2 = alloca [1024 x i8]
99 call void @init_mem(ptr %p1, i64 1024)
100 call void @init_mem(ptr %p2, i64 1024)
104 %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
105 %cmp1 = icmp ne i64 %index, 64
106 br i1 %cmp1, label %search, label %loop.end
109 %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
110 %ld1 = load i8, ptr %arrayidx, align 1
111 %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
112 %ld2 = load i8, ptr %arrayidx1, align 1
113 %cmp3 = icmp eq i8 %ld1, %ld2
114 br i1 %cmp3, label %loop.end.early, label %loop.inc
117 %index.next = add i64 %index, 1
118 %exitcond = icmp ne i64 %index.next, 128
119 br i1 %exitcond, label %loop, label %loop.end
122 %ret.early = phi i64 [ %index, %search ]
126 %retval = phi i64 [ 64, %loop ], [ 128, %loop.inc ]