| ; Test the the loop nest depth is correctly calculated for basic blocks. |
| |
| ; REQUIRES: allow_dump |
| |
| ; Single threaded so that the dumps used for checking happen in order |
| ; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 --verbose=loop \ |
| ; RUN: --threads=0 | FileCheck %s |
| |
| define void @test_single_loop(i32 %a32) { |
| entry: |
| %a = trunc i32 %a32 to i1 |
| br label %loop0 |
| |
| loop0: ; <-+ |
| br label %loop1 ; | |
| loop1: ; | |
| br i1 %a, label %loop0, label %out ; --+ |
| |
| out: |
| ret void |
| } |
| |
| ; CHECK-LABEL: After loop nest depth analysis |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: loop0: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop1: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: out: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-LABEL: Before RMW |
| |
| define void @test_single_loop_with_continue(i32 %a32, i32 %b32) { |
| entry: |
| %a = trunc i32 %a32 to i1 |
| %b = trunc i32 %b32 to i1 |
| br label %loop0 |
| |
| loop0: ; <-+ |
| br label %loop1 ; | |
| loop1: ; | |
| br i1 %a, label %loop0, label %loop2 ; --+ |
| loop2: ; | |
| br i1 %b, label %loop0, label %out ; --+ |
| |
| out: |
| ret void |
| } |
| |
| ; CHECK-LABEL: After loop nest depth analysis |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: loop0: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop1: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop2: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: out: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-LABEL: Before RMW |
| |
| define void @test_multiple_exits(i32 %a32, i32 %b32) { |
| entry: |
| %a = trunc i32 %a32 to i1 |
| %b = trunc i32 %b32 to i1 |
| br label %loop0 |
| |
| loop0: ; <-+ |
| br label %loop1 ; | |
| loop1: ; | |
| br i1 %a, label %loop2, label %out ; --+-+ |
| loop2: ; | | |
| br i1 %b, label %loop0, label %out ; --+ | |
| ; | |
| out: ; <---+ |
| ret void |
| } |
| |
| ; CHECK-LABEL: After loop nest depth analysis |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: loop0: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop1: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop2: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: out: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-LABEL: Before RMW |
| |
| define void @test_two_nested_loops(i32 %a32, i32 %b32) { |
| entry: |
| %a = trunc i32 %a32 to i1 |
| %b = trunc i32 %b32 to i1 |
| br label %loop0_0 |
| |
| loop0_0: ; <---+ |
| br label %loop1_0 ; | |
| loop1_0: ; <-+ | |
| br label %loop1_1 ; | | |
| loop1_1: ; | | |
| br i1 %a, label %loop1_0, label %loop0_1 ; --+ | |
| loop0_1: ; | |
| br i1 %b, label %loop0_0, label %out ; ----+ |
| |
| out: |
| ret void |
| } |
| |
| ; CHECK-LABEL: After loop nest depth analysis |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: loop0_0: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop1_0: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop1_1: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop0_1: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: out: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-LABEL: Before RMW |
| |
| define void @test_two_nested_loops_with_continue(i32 %a32, i32 %b32, i32 %c32) { |
| entry: |
| %a = trunc i32 %a32 to i1 |
| %b = trunc i32 %b32 to i1 |
| %c = trunc i32 %c32 to i1 |
| br label %loop0_0 |
| |
| loop0_0: ; <---+ |
| br label %loop1_0 ; | |
| loop1_0: ; <-+ | |
| br label %loop1_1 ; | | |
| loop1_1: ; | | |
| br i1 %a, label %loop1_0, label %loop1_2 ; --+ | |
| loop1_2: ; | | |
| br i1 %a, label %loop1_0, label %loop0_1 ; --+ | |
| loop0_1: ; | |
| br i1 %b, label %loop0_0, label %out ; ----+ |
| |
| out: |
| ret void |
| } |
| |
| ; CHECK-LABEL: After loop nest depth analysis |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: loop0_0: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop1_0: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop1_1: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop1_2: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop0_1: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: out: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-LABEL: Before RMW |
| |
| define void @test_multiple_nested_loops(i32 %a32, i32 %b32) { |
| entry: |
| %a = trunc i32 %a32 to i1 |
| %b = trunc i32 %b32 to i1 |
| br label %loop0_0 |
| |
| loop0_0: ; <---+ |
| br label %loop1_0 ; | |
| loop1_0: ; <-+ | |
| br label %loop1_1 ; | | |
| loop1_1: ; | | |
| br i1 %a, label %loop1_0, label %loop0_1 ; --+ | |
| loop0_1: ; | |
| br label %loop2_0 ; | |
| loop2_0: ; <-+ | |
| br label %loop2_1 ; | | |
| loop2_1: ; | | |
| br i1 %a, label %loop2_0, label %loop0_2 ; --+ | |
| loop0_2: ; | |
| br i1 %b, label %loop0_0, label %out ; ----+ |
| |
| out: |
| ret void |
| } |
| |
| ; CHECK-LABEL: After loop nest depth analysis |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: loop0_0: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop1_0: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop1_1: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop0_1: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop2_0: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop2_1: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop0_2: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: out: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-LABEL: Before RMW |
| |
| define void @test_three_nested_loops(i32 %a32, i32 %b32, i32 %c32) { |
| entry: |
| %a = trunc i32 %a32 to i1 |
| %b = trunc i32 %b32 to i1 |
| %c = trunc i32 %c32 to i1 |
| br label %loop0_0 |
| |
| loop0_0: ; <-----+ |
| br label %loop1_0 ; | |
| loop1_0: ; <---+ | |
| br label %loop2_0 ; | | |
| loop2_0: ; <-+ | | |
| br label %loop2_1 ; | | | |
| loop2_1: ; | | | |
| br i1 %a, label %loop2_0, label %loop1_1 ; --+ | | |
| loop1_1: ; | | |
| br i1 %b, label %loop1_0, label %loop0_1 ; ----+ | |
| loop0_1: ; | |
| br i1 %c, label %loop0_0, label %out ; ------+ |
| |
| out: |
| ret void |
| } |
| |
| ; CHECK-LABEL: After loop nest depth analysis |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: loop0_0: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: loop1_0: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop2_0: |
| ; CHECK-NEXT: LoopNestDepth = 3 |
| ; CHECK-NEXT: loop2_1: |
| ; CHECK-NEXT: LoopNestDepth = 3 |
| ; CHECK-NEXT: loop1_1: |
| ; CHECK-NEXT: LoopNestDepth = 2 |
| ; CHECK-NEXT: loop0_1: |
| ; CHECK-NEXT: LoopNestDepth = 1 |
| ; CHECK-NEXT: out: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-LABEL: Before RMW |
| |
| define void @test_diamond(i32 %a32) { |
| entry: |
| %a = trunc i32 %a32 to i1 |
| br i1 %a, label %left, label %right |
| |
| left: |
| br label %out |
| |
| right: |
| br label %out |
| |
| out: |
| ret void |
| } |
| |
| ; CHECK-LABEL: After loop nest depth analysis |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: left: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: right: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-NEXT: out: |
| ; CHECK-NEXT: LoopNestDepth = 0 |
| ; CHECK-LABEL: Before RMW |