-
Notifications
You must be signed in to change notification settings - Fork 12.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NFC] Add tests that demonstrate that MustExecute is fundamentally br…
…oken llvm-svn: 339417
- Loading branch information
Max Kazantsev
committed
Aug 10, 2018
1 parent
1793bc9
commit 4e9def5
Showing
2 changed files
with
160 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | ||
; RUN: opt -disable-output -print-mustexecute %s 2>&1 | FileCheck %s | ||
|
||
; Infinite loop. | ||
; TODO: backedge is provably mustexecute, but the analysis does not know this. | ||
define void @test_no_exit_block(i1 %cond, i32 %a, i32 %b) { | ||
; CHECK-LABEL: @test_no_exit_block( | ||
; CHECK-NEXT: entry: | ||
; CHECK-NEXT: br label [[LOOP:%.*]] | ||
; CHECK: loop: | ||
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] ; (mustexec in: loop) | ||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[MAYBE_TAKEN:%.*]], label [[BACKEDGE]] ; (mustexec in: loop) | ||
|
||
; FIXME: Should be mustexec in backedge. The current analysis does not handle | ||
; loops without exit blocks at all. | ||
; CHECK-NOT: ; (mustexec in: loop) | ||
|
||
; CHECK: maybe_taken: | ||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]] | ||
; CHECK-NEXT: br label [[BACKEDGE]] | ||
; CHECK: backedge: | ||
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 | ||
; CHECK-NEXT: br label [[LOOP]] | ||
; | ||
entry: | ||
br label %loop | ||
|
||
loop: | ||
%iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] | ||
br i1 %cond, label %maybe_taken, label %backedge | ||
|
||
maybe_taken: | ||
%div = sdiv i32 %a, %b | ||
br label %backedge | ||
|
||
backedge: | ||
%iv.next = add i32 %iv, 1 | ||
br label %loop | ||
} | ||
|
||
; Unlike the test before, we can say that backedge is mustexec, which is the | ||
; correct behavior. | ||
define void @test_impossible_exit_on_latch(i1 %cond, i32 %a, i32 %b) { | ||
; CHECK-LABEL: @test_impossible_exit_on_latch( | ||
; CHECK-NEXT: entry: | ||
; CHECK-NEXT: br label [[LOOP:%.*]] | ||
; CHECK: loop: | ||
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] ; (mustexec in: loop) | ||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[MAYBE_TAKEN:%.*]], label [[BACKEDGE]] ; (mustexec in: loop) | ||
; CHECK: maybe_taken: | ||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]] | ||
; CHECK-NEXT: br label [[BACKEDGE]] | ||
; CHECK: backedge: | ||
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 ; (mustexec in: loop) | ||
; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT:%.*]] ; (mustexec in: loop) | ||
; CHECK: exit: | ||
; CHECK-NEXT: ret void | ||
; | ||
entry: | ||
br label %loop | ||
|
||
loop: | ||
%iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] | ||
br i1 %cond, label %maybe_taken, label %backedge | ||
|
||
maybe_taken: | ||
%div = sdiv i32 %a, %b | ||
br label %backedge | ||
|
||
backedge: | ||
%iv.next = add i32 %iv, 1 | ||
br i1 true, label %loop, label %exit | ||
|
||
exit: | ||
ret void | ||
} | ||
|
||
; FIXME: This code demonstrates a bug. %div should not be mustexec. | ||
define void @test_impossible_exit_in_untaken_block(i1 %cond, i32 %a, i32 %b, i32* %p) { | ||
; CHECK-LABEL: @test_impossible_exit_in_untaken_block( | ||
; CHECK-NEXT: entry: | ||
; CHECK-NEXT: br label [[LOOP:%.*]] | ||
; CHECK: loop: | ||
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] ; (mustexec in: loop) | ||
; CHECK-NEXT: br i1 [[COND:%.*]], label [[MAYBE_TAKEN:%.*]], label [[BACKEDGE]] ; (mustexec in: loop) | ||
; CHECK: maybe_taken: | ||
|
||
; FIXME: The block below is NOT always taken!!! Current this example demonstrates a | ||
; bug in current mustexecute analysis. | ||
|
||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]] ; (mustexec in: loop) | ||
; CHECK-NEXT: store i32 [[DIV]], i32* [[P:%.*]] ; (mustexec in: loop) | ||
; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[EXIT:%.*]] ; (mustexec in: loop) | ||
; CHECK: backedge: | ||
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 ; (mustexec in: loop) | ||
; CHECK-NEXT: br label [[LOOP]] ; (mustexec in: loop) | ||
; CHECK: exit: | ||
; CHECK-NEXT: ret void | ||
; | ||
entry: | ||
br label %loop | ||
|
||
loop: | ||
%iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] | ||
br i1 %cond, label %maybe_taken, label %backedge | ||
|
||
maybe_taken: | ||
%div = sdiv i32 %a, %b | ||
store i32 %div, i32* %p | ||
br i1 true, label %backedge, label %exit | ||
|
||
backedge: | ||
%iv.next = add i32 %iv, 1 | ||
br label %loop | ||
|
||
exit: | ||
ret void | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | ||
; RUN: opt -S -basicaa -licm < %s | FileCheck %s | ||
; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s | ||
|
||
; FIXME: This test demonstrates a bug in MustExecute analysis. We hoist sdiv | ||
; which can be a division by zero from a block which is never taken. | ||
define void @test_impossible_exit_in_untaken_block(i32 %a, i32 %b, i32* %p) { | ||
; CHECK-LABEL: @test_impossible_exit_in_untaken_block( | ||
; CHECK-NEXT: entry: | ||
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]] | ||
; CHECK-NEXT: br label [[LOOP:%.*]] | ||
; CHECK: loop: | ||
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] | ||
; CHECK-NEXT: br i1 false, label [[NEVER_TAKEN:%.*]], label [[BACKEDGE]] | ||
; CHECK: never_taken: | ||
; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[EXIT:%.*]] | ||
; CHECK: backedge: | ||
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 | ||
; CHECK-NEXT: br label [[LOOP]] | ||
; CHECK: exit: | ||
; CHECK-NEXT: store i32 [[DIV]], i32* [[P:%.*]], align 4 | ||
; CHECK-NEXT: ret void | ||
; | ||
entry: | ||
br label %loop | ||
|
||
loop: | ||
%iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] | ||
br i1 false, label %never_taken, label %backedge | ||
|
||
never_taken: | ||
%div = sdiv i32 %a, %b | ||
store i32 %div, i32* %p | ||
br i1 true, label %backedge, label %exit | ||
|
||
backedge: | ||
%iv.next = add i32 %iv, 1 | ||
br label %loop | ||
|
||
exit: | ||
ret void | ||
} |