[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / multi_early_exit_live_outs.ll
blob4027f6a0f5dfdc9e2815aeefbeffb435a06f2f6b
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() {
10 ; CHECK-NEXT:  entry:
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:%.*]]
16 ; CHECK:       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:%.*]]
20 ; CHECK:       search:
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]]
27 ; CHECK:       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]]
31 ; CHECK:       loop.end:
32 ; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ 64, [[LOOP]] ], [ [[INDEX]], [[SEARCH]] ], [ 128, [[LOOP_INC]] ]
33 ; CHECK-NEXT:    ret i64 [[RETVAL]]
35 entry:
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)
40   br label %loop
42 loop:
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
47 search:
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
55 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
60 loop.end:
61   %retval = phi i64 [ 64, %loop ], [ %index, %search ], [ 128, %loop.inc ]
62   ret i64 %retval
66 define i64 @one_uncountable_two_countable_diff_exit() {
67 ; CHECK-LABEL: define i64 @one_uncountable_two_countable_diff_exit() {
68 ; CHECK-NEXT:  entry:
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:%.*]]
74 ; CHECK:       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:%.*]]
78 ; CHECK:       search:
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]]
85 ; CHECK:       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]]
92 ; CHECK:       loop.end:
93 ; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ 64, [[LOOP]] ], [ 128, [[LOOP_INC]] ]
94 ; CHECK-NEXT:    ret i64 [[RETVAL]]
96 entry:
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)
101   br label %loop
103 loop:
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
108 search:
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
116 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
121 loop.end.early:
122   %ret.early = phi i64 [ %index, %search ]
123   ret i64 %ret.early
125 loop.end:
126   %retval = phi i64 [ 64, %loop ], [ 128, %loop.inc ]
127   ret i64 %retval