From eee2e8813f8113f23059a6a8757908c38e3099c5 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 20 Jan 2021 11:43:59 +0000 Subject: [PATCH] [LV] Add test cases with multiple exits which require versioning. This adds some test coverage for caafdf07bbccbe89219539e2b56043c2a98358f1, which relaxed an assertion to only require a unique exit block. --- .../LoopVectorize/multiple-exits-versioning.ll | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 llvm/test/Transforms/LoopVectorize/multiple-exits-versioning.ll diff --git a/llvm/test/Transforms/LoopVectorize/multiple-exits-versioning.ll b/llvm/test/Transforms/LoopVectorize/multiple-exits-versioning.ll new file mode 100644 index 0000000..7a2f044 --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/multiple-exits-versioning.ll @@ -0,0 +1,67 @@ +; RUN: opt -loop-vectorize -force-vector-width=2 -S %s | FileCheck %s + +; Test cases to make sure LV & loop versioning can handle loops with +; multiple exiting branches. + +; Multiple branches exiting the loop to a unique exit block. The loop should +; be vectorized with versioning & noalias metadata should be added. +define void @multiple_exits_unique_exit_block(i32* %A, i32* %B, i64 %N) { +; CHECK-LABEL: @multiple_exits_unique_exit_block +; CHECK: vector.memcheck: +; CHECK-LABEL: vector.body: +; CHECK: %wide.load = load <2 x i32>, <2 x i32>* {{.*}}, align 4, !alias.scope +; CHECK: store <2 x i32> %wide.load, <2 x i32>* {{.*}}, align 4, !alias.scope +; CHECK: br +; +entry: + br label %loop.header + +loop.header: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ] + %cond.0 = icmp eq i64 %iv, %N + br i1 %cond.0, label %exit, label %for.body + +for.body: + %A.gep = getelementptr inbounds i32, i32* %A, i64 %iv + %lv = load i32, i32* %A.gep, align 4 + %B.gep = getelementptr inbounds i32, i32* %B, i64 %iv + store i32 %lv, i32* %B.gep, align 4 + %iv.next = add nuw i64 %iv, 1 + %cond.1 = icmp ult i64 %iv.next, 1000 + br i1 %cond.1, label %loop.header, label %exit + +exit: + ret void +} + + +; Multiple branches exiting the loop to different blocks. Currently this is not supported. +define i32 @multiple_exits_multiple_exit_blocks(i32* %A, i32* %B, i64 %N) { +; CHECK-LABEL: @multiple_exits_multiple_exit_blocks +; CHECK-NEXT: entry: +; CHECK: br label %loop.header +; CHECK-NOT: <2 x i32> +; +entry: + br label %loop.header + +loop.header: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ] + %cond.0 = icmp eq i64 %iv, %N + br i1 %cond.0, label %exit.0, label %for.body + +for.body: + %A.gep = getelementptr inbounds i32, i32* %A, i64 %iv + %lv = load i32, i32* %A.gep, align 4 + %B.gep = getelementptr inbounds i32, i32* %B, i64 %iv + store i32 %lv, i32* %B.gep, align 4 + %iv.next = add nuw i64 %iv, 1 + %cond.1 = icmp ult i64 %iv.next, 1000 + br i1 %cond.1, label %loop.header, label %exit.1 + +exit.0: + ret i32 1 + +exit.1: + ret i32 2 +} -- 2.7.4