From 38c3cebd7d5aab0a27fb78d10bf3c783d760b186 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 16 Aug 2021 11:48:25 +0100 Subject: [PATCH] [LoopPeel] Add test with multiple exit blocks branching to unreachable. Add test as suggested by @ebedev.ri in D108108. --- .../LoopUnroll/peel-multiple-unreachable-exits.ll | 86 ++++++++++++++++++++-- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/llvm/test/Transforms/LoopUnroll/peel-multiple-unreachable-exits.ll b/llvm/test/Transforms/LoopUnroll/peel-multiple-unreachable-exits.ll index 0a56290..435a801 100644 --- a/llvm/test/Transforms/LoopUnroll/peel-multiple-unreachable-exits.ll +++ b/llvm/test/Transforms/LoopUnroll/peel-multiple-unreachable-exits.ll @@ -3,8 +3,8 @@ declare void @foo() -define void @unroll_unreachable_exit_and_latch_exit(i32* %ptr, i32 %N, i32 %x) { -; CHECK-LABEL: @unroll_unreachable_exit_and_latch_exit( +define void @peel_unreachable_exit_and_latch_exit(i32* %ptr, i32 %N, i32 %x) { +; CHECK-LABEL: @peel_unreachable_exit_and_latch_exit( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: @@ -60,8 +60,8 @@ unreachable.exit: unreachable } -define void @unroll_unreachable_exit_and_header_exit(i32* %ptr, i32 %N, i32 %x) { -; CHECK-LABEL: @unroll_unreachable_exit_and_header_exit( +define void @peel_unreachable_exit_and_header_exit(i32* %ptr, i32 %N, i32 %x) { +; CHECK-LABEL: @peel_unreachable_exit_and_header_exit( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: @@ -105,8 +105,8 @@ unreachable.exit: unreachable } -define void @unroll_unreachable_and_multiple_reachable_exits(i32* %ptr, i32 %N, i32 %x) { -; CHECK-LABEL: @unroll_unreachable_and_multiple_reachable_exits( +define void @peel_unreachable_and_multiple_reachable_exits(i32* %ptr, i32 %N, i32 %x) { +; CHECK-LABEL: @peel_unreachable_and_multiple_reachable_exits( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: @@ -163,3 +163,77 @@ unreachable.exit: call void @foo() unreachable } + +define void @peel_exits_to_blocks_branch_to_unreachable_block(i32* %ptr, i32 %N, i32 %x, i1 %c.1) { +; CHECK-LABEL: @peel_exits_to_blocks_branch_to_unreachable_block( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] +; CHECK: loop.header: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], 2 +; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] +; CHECK: then: +; CHECK-NEXT: br i1 [[C_1:%.*]], label [[EXIT_1:%.*]], label [[LOOP_LATCH]] +; CHECK: else: +; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[IV]], [[X:%.*]] +; CHECK-NEXT: br i1 [[C_2]], label [[EXIT_2:%.*]], label [[LOOP_LATCH]] +; CHECK: loop.latch: +; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ] +; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 [[IV]] +; CHECK-NEXT: store i32 [[M]], i32* [[GEP]], align 4 +; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 +; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 +; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; CHECK: exit.1: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[UNREACHABLE_TERM:%.*]] +; CHECK: exit.2: +; CHECK-NEXT: call void @bar() +; CHECK-NEXT: br label [[UNREACHABLE_TERM]] +; CHECK: unreachable.term: +; CHECK-NEXT: call void @baz() +; CHECK-NEXT: unreachable +; +entry: + br label %loop.header + +loop.header: + %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] + %c = icmp ult i32 %iv, 2 + br i1 %c, label %then, label %else + +then: + br i1 %c.1, label %exit.1, label %loop.latch + +else: + %c.2 = icmp eq i32 %iv, %x + br i1 %c.2, label %exit.2, label %loop.latch + +loop.latch: + %m = phi i32 [ 0, %then ], [ %x, %else ] + %gep = getelementptr i32, i32* %ptr, i32 %iv + store i32 %m, i32* %gep + %iv.next = add nuw nsw i32 %iv, 1 + %c.3 = icmp ult i32 %iv, 1000 + br i1 %c.3, label %loop.header, label %exit + +exit: + ret void + +exit.1: + call void @foo() + br label %unreachable.term + +exit.2: + call void @bar() + br label %unreachable.term + +unreachable.term: + call void @baz() + unreachable +} + +declare void @bar() +declare void @baz() -- 2.7.4