xref: /llvm-project/llvm/test/Transforms/LoopVectorize/multi_early_exit.ll (revision 13107cb09441dfeab24fcbcae9f4d3ba4cfc2703)
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
3
4declare void @init_mem(ptr, i64);
5
6define i64 @one_uncountable_two_countable_same_exit_phi_of_consts() {
7; CHECK-LABEL: define i64 @one_uncountable_two_countable_same_exit_phi_of_consts() {
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
10; CHECK-NEXT:    [[P2:%.*]] = alloca [1024 x i8], align 1
11; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
12; CHECK-NEXT:    call void @init_mem(ptr [[P2]], i64 1024)
13; CHECK-NEXT:    br label [[LOOP:%.*]]
14; CHECK:       loop:
15; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
16; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i64 [[INDEX]], 64
17; CHECK-NEXT:    br i1 [[CMP1]], label [[SEARCH:%.*]], label [[LOOP_END:%.*]]
18; CHECK:       search:
19; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
20; CHECK-NEXT:    [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
21; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
22; CHECK-NEXT:    [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
23; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
24; CHECK-NEXT:    br i1 [[CMP3]], label [[LOOP_END]], label [[LOOP_INC]]
25; CHECK:       loop.inc:
26; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
27; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 128
28; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]
29; CHECK:       loop.end:
30; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ 0, [[LOOP]] ], [ 1, [[SEARCH]] ], [ 0, [[LOOP_INC]] ]
31; CHECK-NEXT:    ret i64 [[RETVAL]]
32;
33entry:
34  %p1 = alloca [1024 x i8]
35  %p2 = alloca [1024 x i8]
36  call void @init_mem(ptr %p1, i64 1024)
37  call void @init_mem(ptr %p2, i64 1024)
38  br label %loop
39
40loop:
41  %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
42  %cmp1 = icmp ne i64 %index, 64
43  br i1 %cmp1, label %search, label %loop.end
44
45search:
46  %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
47  %ld1 = load i8, ptr %arrayidx, align 1
48  %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
49  %ld2 = load i8, ptr %arrayidx1, align 1
50  %cmp3 = icmp eq i8 %ld1, %ld2
51  br i1 %cmp3, label %loop.end, label %loop.inc
52
53loop.inc:
54  %index.next = add i64 %index, 1
55  %exitcond = icmp ne i64 %index.next, 128
56  br i1 %exitcond, label %loop, label %loop.end
57
58loop.end:
59  %retval = phi i64 [ 0, %loop ], [ 1, %search ], [ 0, %loop.inc ]
60  ret i64 %retval
61}
62
63
64define i64 @one_uncountable_two_countable_diff_exit_no_phis() {
65; CHECK-LABEL: define i64 @one_uncountable_two_countable_diff_exit_no_phis() {
66; CHECK-NEXT:  entry:
67; CHECK-NEXT:    [[P1:%.*]] = alloca [1024 x i8], align 1
68; CHECK-NEXT:    [[P2:%.*]] = alloca [1024 x i8], align 1
69; CHECK-NEXT:    call void @init_mem(ptr [[P1]], i64 1024)
70; CHECK-NEXT:    call void @init_mem(ptr [[P2]], i64 1024)
71; CHECK-NEXT:    br label [[LOOP:%.*]]
72; CHECK:       loop:
73; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 3, [[ENTRY:%.*]] ]
74; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i64 [[INDEX]], 64
75; CHECK-NEXT:    br i1 [[CMP1]], label [[SEARCH:%.*]], label [[LOOP_END:%.*]]
76; CHECK:       search:
77; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
78; CHECK-NEXT:    [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
79; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
80; CHECK-NEXT:    [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
81; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
82; CHECK-NEXT:    br i1 [[CMP3]], label [[LOOP_END_EARLY:%.*]], label [[LOOP_INC]]
83; CHECK:       loop.inc:
84; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 1
85; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 128
86; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END]]
87; CHECK:       loop.end.early:
88; CHECK-NEXT:    ret i64 1
89; CHECK:       loop.end:
90; CHECK-NEXT:    ret i64 0
91;
92entry:
93  %p1 = alloca [1024 x i8]
94  %p2 = alloca [1024 x i8]
95  call void @init_mem(ptr %p1, i64 1024)
96  call void @init_mem(ptr %p2, i64 1024)
97  br label %loop
98
99loop:
100  %index = phi i64 [ %index.next, %loop.inc ], [ 3, %entry ]
101  %cmp1 = icmp ne i64 %index, 64
102  br i1 %cmp1, label %search, label %loop.end
103
104search:
105  %arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
106  %ld1 = load i8, ptr %arrayidx, align 1
107  %arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
108  %ld2 = load i8, ptr %arrayidx1, align 1
109  %cmp3 = icmp eq i8 %ld1, %ld2
110  br i1 %cmp3, label %loop.end.early, label %loop.inc
111
112loop.inc:
113  %index.next = add i64 %index, 1
114  %exitcond = icmp ne i64 %index.next, 128
115  br i1 %exitcond, label %loop, label %loop.end
116
117loop.end.early:
118  ret i64 1
119
120loop.end:
121  ret i64 0
122}
123