blob: 88cf0d1d7d86e3574d2622ff41adde6c219d6094 [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -mtriple=amdgpu9.00-amd-amdhsa -passes='simplifycfg<no-keep-loops>' < %s | FileCheck %s
declare void @barrier() convergent
declare void @plain()
define void @preserve_loop_header_branch(i1 %cond, ptr %ptr) convergent {
; CHECK-LABEL: define void @preserve_loop_header_branch(
; CHECK-SAME: i1 [[COND:%.*]], ptr [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: call void @barrier() #[[ATTR0]]
; CHECK-NEXT: br i1 [[COND]], label %[[PRE_THEN:.*]], label %[[LOOP_HEADER:.*]]
; CHECK: [[PRE_THEN]]:
; CHECK-NEXT: store i32 1, ptr [[PTR]], align 4
; CHECK-NEXT: br label %[[LOOP_HEADER]]
; CHECK: [[LOOP_HEADER]]:
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP_BODY:.*]], label %[[LOOP_LATCH:.*]]
; CHECK: [[LOOP_BODY]]:
; CHECK-NEXT: store i32 2, ptr [[PTR]], align 4
; CHECK-NEXT: br label %[[LOOP_LATCH]]
; CHECK: [[LOOP_LATCH]]:
; CHECK-NEXT: call void @barrier() #[[ATTR0]]
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP_HEADER]], label %[[EXIT:.*]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %pre
pre:
call void @barrier() convergent
br i1 %cond, label %pre.then, label %loop.header
pre.then:
store i32 1, ptr %ptr, align 4
br label %loop.header
loop.header:
br i1 %cond, label %loop.body, label %loop.latch
loop.body:
store i32 2, ptr %ptr, align 4
br label %loop.latch
loop.latch:
call void @barrier() convergent
br i1 %cond, label %loop.header, label %exit
exit:
ret void
}
define void @thread_non_convergent_loop_header_branch(i1 %cond, ptr %ptr) {
; CHECK-LABEL: define void @thread_non_convergent_loop_header_branch(
; CHECK-SAME: i1 [[COND:%.*]], ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: call void @plain()
; CHECK-NEXT: br i1 [[COND]], label %[[PRE_THEN:.*]], label %[[EXIT_CRITEDGE:.*]]
; CHECK: [[PRE_THEN]]:
; CHECK-NEXT: store i32 1, ptr [[PTR]], align 4
; CHECK-NEXT: br label %[[LOOP_BODY:.*]]
; CHECK: [[LOOP_BODY]]:
; CHECK-NEXT: store i32 2, ptr [[PTR]], align 4
; CHECK-NEXT: call void @plain()
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP_BODY]], label %[[EXIT:.*]]
; CHECK: [[EXIT_CRITEDGE]]:
; CHECK-NEXT: call void @plain()
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %pre
pre:
call void @plain()
br i1 %cond, label %pre.then, label %loop.header
pre.then:
store i32 1, ptr %ptr, align 4
br label %loop.header
loop.header:
br i1 %cond, label %loop.body, label %loop.latch
loop.body:
store i32 2, ptr %ptr, align 4
br label %loop.latch
loop.latch:
call void @plain()
br i1 %cond, label %loop.header, label %exit
exit:
ret void
}
define void @thread_convergent_only_on_exit_path(i1 %cond, ptr %ptr) convergent {
; CHECK-LABEL: define void @thread_convergent_only_on_exit_path(
; CHECK-SAME: i1 [[COND:%.*]], ptr [[PTR:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: call void @plain()
; CHECK-NEXT: br i1 [[COND]], label %[[PRE_THEN:.*]], label %[[EXIT_CRITEDGE:.*]]
; CHECK: [[PRE_THEN]]:
; CHECK-NEXT: store i32 1, ptr [[PTR]], align 4
; CHECK-NEXT: br label %[[LOOP_BODY:.*]]
; CHECK: [[LOOP_BODY]]:
; CHECK-NEXT: store i32 2, ptr [[PTR]], align 4
; CHECK-NEXT: call void @plain()
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP_BODY]], label %[[EXIT:.*]]
; CHECK: [[EXIT_CRITEDGE]]:
; CHECK-NEXT: call void @plain()
; CHECK-NEXT: br label %[[EXIT]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: call void @barrier() #[[ATTR0]]
; CHECK-NEXT: ret void
;
entry:
br label %pre
pre:
call void @plain()
br i1 %cond, label %pre.then, label %loop.header
pre.then:
store i32 1, ptr %ptr, align 4
br label %loop.header
loop.header:
br i1 %cond, label %loop.body, label %loop.latch
loop.body:
store i32 2, ptr %ptr, align 4
br label %loop.latch
loop.latch:
call void @plain()
br i1 %cond, label %loop.header, label %exit
exit:
call void @barrier() convergent
ret void
}