xref: /llvm-project/llvm/test/Transforms/LoopVectorize/multiple-exits-versioning.ll (revision 7d7577256b76e4293f455b8093504d5f7044ab4b)
1be51fa45SRoman Lebedev; RUN: opt -passes=loop-vectorize -force-vector-width=2 -S %s | FileCheck %s
2eee2e881SFlorian Hahn
3eee2e881SFlorian Hahn; Test cases to make sure LV & loop versioning can handle loops with
4eee2e881SFlorian Hahn; multiple exiting branches.
5eee2e881SFlorian Hahn
6eee2e881SFlorian Hahn; Multiple branches exiting the loop to a unique exit block. The loop should
7b7315ffcSFlorian Hahn; be vectorized with versioning.
8*7d757725SNikita Popovdefine void @multiple_exits_unique_exit_block(ptr %A, ptr %B, i64 %N) {
9872f7000SDávid Bolvanský; CHECK-LABEL: @multiple_exits_unique_exit_block
10eee2e881SFlorian Hahn; CHECK:       vector.memcheck:
11872f7000SDávid Bolvanský; CHECK-LABEL: vector.body:
12*7d757725SNikita Popov; CHECK:         %wide.load = load <2 x i32>, ptr {{.*}}, align 4
13*7d757725SNikita Popov; CHECK:         store <2 x i32> %wide.load, ptr {{.*}}, align 4
14872f7000SDávid Bolvanský; CHECK:         br
15eee2e881SFlorian Hahn;
16eee2e881SFlorian Hahnentry:
17eee2e881SFlorian Hahn  br label %loop.header
18eee2e881SFlorian Hahn
19eee2e881SFlorian Hahnloop.header:
20eee2e881SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
21eee2e881SFlorian Hahn  %cond.0 = icmp eq i64 %iv, %N
22eee2e881SFlorian Hahn  br i1 %cond.0, label %exit, label %for.body
23eee2e881SFlorian Hahn
24eee2e881SFlorian Hahnfor.body:
25*7d757725SNikita Popov  %A.gep = getelementptr inbounds i32, ptr %A, i64 %iv
26*7d757725SNikita Popov  %lv = load i32, ptr %A.gep, align 4
27*7d757725SNikita Popov  %B.gep = getelementptr inbounds i32, ptr %B, i64 %iv
28*7d757725SNikita Popov  store i32 %lv, ptr %B.gep, align 4
29eee2e881SFlorian Hahn  %iv.next = add nuw i64 %iv, 1
30eee2e881SFlorian Hahn  %cond.1 = icmp ult i64 %iv.next, 1000
31eee2e881SFlorian Hahn  br i1 %cond.1, label %loop.header, label %exit
32eee2e881SFlorian Hahn
33eee2e881SFlorian Hahnexit:
34eee2e881SFlorian Hahn  ret void
35eee2e881SFlorian Hahn}
36eee2e881SFlorian Hahn
37eee2e881SFlorian Hahn
38eee2e881SFlorian Hahn; Multiple branches exiting the loop to different blocks. Currently this is not supported.
39*7d757725SNikita Popovdefine i32 @multiple_exits_multiple_exit_blocks(ptr %A, ptr %B, i64 %N) {
40872f7000SDávid Bolvanský; CHECK-LABEL: @multiple_exits_multiple_exit_blocks
41eee2e881SFlorian Hahn; CHECK-NEXT:    entry:
42872f7000SDávid Bolvanský; CHECK:           br label %loop.header
43872f7000SDávid Bolvanský; CHECK-NOT:      <2 x i32>
44eee2e881SFlorian Hahn;
45eee2e881SFlorian Hahnentry:
46eee2e881SFlorian Hahn  br label %loop.header
47eee2e881SFlorian Hahn
48eee2e881SFlorian Hahnloop.header:
49eee2e881SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
50eee2e881SFlorian Hahn  %cond.0 = icmp eq i64 %iv, %N
51eee2e881SFlorian Hahn  br i1 %cond.0, label %exit.0, label %for.body
52eee2e881SFlorian Hahn
53eee2e881SFlorian Hahnfor.body:
54*7d757725SNikita Popov  %A.gep = getelementptr inbounds i32, ptr %A, i64 %iv
55*7d757725SNikita Popov  %lv = load i32, ptr %A.gep, align 4
56*7d757725SNikita Popov  %B.gep = getelementptr inbounds i32, ptr %B, i64 %iv
57*7d757725SNikita Popov  store i32 %lv, ptr %B.gep, align 4
58eee2e881SFlorian Hahn  %iv.next = add nuw i64 %iv, 1
59eee2e881SFlorian Hahn  %cond.1 = icmp ult i64 %iv.next, 1000
60eee2e881SFlorian Hahn  br i1 %cond.1, label %loop.header, label %exit.1
61eee2e881SFlorian Hahn
62eee2e881SFlorian Hahnexit.0:
63eee2e881SFlorian Hahn  ret i32 1
64eee2e881SFlorian Hahn
65eee2e881SFlorian Hahnexit.1:
66eee2e881SFlorian Hahn  ret i32 2
67eee2e881SFlorian Hahn}
68