If a function had at most one return block, the pass would return false regardless if an unified unreachable block was created. This patch fixes that by refactoring runOnFunction into two separate helper functions for handling the unreachable blocks respectively the return blocks, as suggested by @bjope in a review comment. This was caught using the check introduced by D80916. Reviewed By: serge-sans-paille Differential Revision: https://reviews.llvm.org/D85818
68 lines
2.0 KiB
LLVM
68 lines
2.0 KiB
LLVM
; RUN: opt -mergereturn -S < %s | FileCheck %s
|
|
|
|
; The pass did previously not report the correct Modified status in the case
|
|
; where a function had at most one return block, and an unified unreachable
|
|
; block was created. This was caught by the pass return status check that is
|
|
; hidden under EXPENSIVE_CHECKS.
|
|
|
|
; CHECK: for.foo.body2:
|
|
; CHECK-NEXT: br label %UnifiedUnreachableBlock
|
|
|
|
; CHECK: for.foo.end:
|
|
; CHECK-NEXT: br label %UnifiedUnreachableBlock
|
|
|
|
; CHECK: UnifiedUnreachableBlock:
|
|
; CHECK-NEXT: unreachable
|
|
|
|
define i32 @foo() {
|
|
entry:
|
|
br label %for.foo.cond
|
|
|
|
for.foo.cond: ; preds = %entry
|
|
br i1 false, label %for.foo.body, label %for.foo.end3
|
|
|
|
for.foo.body: ; preds = %for.foo.cond
|
|
br label %for.foo.cond1
|
|
|
|
for.foo.cond1: ; preds = %for.foo.body
|
|
br i1 false, label %for.foo.body2, label %for.foo.end
|
|
|
|
for.foo.body2: ; preds = %for.foo.cond1
|
|
unreachable
|
|
|
|
for.foo.end: ; preds = %for.foo.cond1
|
|
unreachable
|
|
|
|
for.foo.end3: ; preds = %for.foo.cond
|
|
ret i32 undef
|
|
}
|
|
|
|
; CHECK: for.bar.body2:
|
|
; CHECK-NEXT: br label %UnifiedUnreachableBlock
|
|
|
|
; CHECK: for.bar.end:
|
|
; CHECK-NEXT: br label %UnifiedUnreachableBlock
|
|
|
|
; CHECK: UnifiedUnreachableBlock:
|
|
; CHECK-NEXT: unreachable
|
|
|
|
define void @bar() {
|
|
entry:
|
|
br label %for.bar.cond
|
|
|
|
for.bar.cond: ; preds = %entry
|
|
br i1 false, label %for.bar.body, label %for.bar.end
|
|
|
|
for.bar.body: ; preds = %for.bar.cond
|
|
br label %for.bar.cond1
|
|
|
|
for.bar.cond1: ; preds = %for.bar.body
|
|
br i1 false, label %for.bar.body2, label %for.bar.end
|
|
|
|
for.bar.body2: ; preds = %for.bar.cond1
|
|
unreachable
|
|
|
|
for.bar.end: ; preds = %for.bar.cond1
|
|
unreachable
|
|
}
|