This issue was discovered during some downstream work around Vulkan CTS tests, specifically `dEQP-VK.subgroups.arithmetic.compute.subgroupadd_float` --------- Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
1068 lines
38 KiB
LLVM
1068 lines
38 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 4
|
|
; RUN: opt -S -mtriple=amdgcn-unknown-amdhsa -mcpu=gfx90a -passes=amdgpu-attributor %s | FileCheck %s
|
|
|
|
; Shrink result attribute list by preventing use of most attributes.
|
|
define internal void @use_most() {
|
|
; CHECK-LABEL: define internal void @use_most(
|
|
; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [256 x i8], align 1, addrspace(5)
|
|
; CHECK-NEXT: [[ALLOCA_CAST:%.*]] = addrspacecast ptr addrspace(5) [[ALLOCA]] to ptr
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.amdgcn.workitem.id.y()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.amdgcn.workitem.id.z()
|
|
; CHECK-NEXT: [[TMP4:%.*]] = call i32 @llvm.amdgcn.workgroup.id.x()
|
|
; CHECK-NEXT: [[TMP5:%.*]] = call i32 @llvm.amdgcn.workgroup.id.y()
|
|
; CHECK-NEXT: [[TMP6:%.*]] = call i32 @llvm.amdgcn.workgroup.id.z()
|
|
; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.amdgcn.cluster.id.x()
|
|
; CHECK-NEXT: [[TMP11:%.*]] = call i32 @llvm.amdgcn.cluster.id.y()
|
|
; CHECK-NEXT: [[TMP12:%.*]] = call i32 @llvm.amdgcn.cluster.id.z()
|
|
; CHECK-NEXT: [[TMP7:%.*]] = call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()
|
|
; CHECK-NEXT: [[TMP8:%.*]] = call ptr addrspace(4) @llvm.amdgcn.queue.ptr()
|
|
; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.amdgcn.dispatch.id()
|
|
; CHECK-NEXT: [[TMP13:%.*]] = call i32 @llvm.amdgcn.lds.kernel.id()
|
|
; CHECK-NEXT: [[IMPLICIT_ARG_PTR:%.*]] = call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()
|
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p4.i64(ptr [[ALLOCA_CAST]], ptr addrspace(4) [[IMPLICIT_ARG_PTR]], i64 256, i1 false)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%alloca = alloca [256 x i8], addrspace(5)
|
|
%alloca.cast = addrspacecast ptr addrspace(5) %alloca to ptr
|
|
call i32 @llvm.amdgcn.workitem.id.x()
|
|
call i32 @llvm.amdgcn.workitem.id.y()
|
|
call i32 @llvm.amdgcn.workitem.id.z()
|
|
call i32 @llvm.amdgcn.workgroup.id.x()
|
|
call i32 @llvm.amdgcn.workgroup.id.y()
|
|
call i32 @llvm.amdgcn.workgroup.id.z()
|
|
call i32 @llvm.amdgcn.cluster.id.x()
|
|
call i32 @llvm.amdgcn.cluster.id.y()
|
|
call i32 @llvm.amdgcn.cluster.id.z()
|
|
call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()
|
|
call ptr addrspace(4) @llvm.amdgcn.queue.ptr()
|
|
call i64 @llvm.amdgcn.dispatch.id()
|
|
call i32 @llvm.amdgcn.lds.kernel.id()
|
|
%implicit.arg.ptr = call ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr()
|
|
call void @llvm.memcpy.p0.p4(ptr %alloca.cast, ptr addrspace(4) %implicit.arg.ptr, i64 256, i1 false)
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg(
|
|
; CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a"(i32 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_def() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_def(
|
|
; CHECK-SAME: ) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call i32 asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call i32 asm sideeffect "; def $0", "=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_physreg_def_tuple() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_physreg_def_tuple(
|
|
; CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call i64 asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call i64 asm sideeffect "; def $0", "={a[0:1]}"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_second_arg() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_second_arg(
|
|
; CHECK-SAME: ) #[[ATTR1]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "v,a"(i32 poison, i32 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_non_agpr_asm() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_non_agpr_asm(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "v"(i32 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_physreg() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_physreg(
|
|
; CHECK-SAME: ) #[[ATTR1]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "{a0}"(i32 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_physreg_tuple() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_physreg_tuple(
|
|
; CHECK-SAME: ) #[[ATTR2]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "{a[0:1]}"(i64 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @func_uses_asm_virtreg_agpr() {
|
|
; CHECK-LABEL: define void @func_uses_asm_virtreg_agpr(
|
|
; CHECK-SAME: ) #[[ATTR1]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a"(i32 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @func_uses_asm_physreg_agpr() {
|
|
; CHECK-LABEL: define void @func_uses_asm_physreg_agpr(
|
|
; CHECK-SAME: ) #[[ATTR1]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "{a0}"(i32 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @func_uses_asm_physreg_agpr_tuple() {
|
|
; CHECK-LABEL: define void @func_uses_asm_physreg_agpr_tuple(
|
|
; CHECK-SAME: ) #[[ATTR2]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "{a[0:1]}"(i64 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
declare void @unknown()
|
|
|
|
define amdgpu_kernel void @kernel_calls_extern() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_calls_extern(
|
|
; CHECK-SAME: ) #[[ATTR3:[0-9]+]] {
|
|
; CHECK-NEXT: call void @unknown()
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @unknown()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_calls_extern_marked_callsite() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_calls_extern_marked_callsite(
|
|
; CHECK-SAME: ) #[[ATTR3]] {
|
|
; CHECK-NEXT: call void @unknown() #[[ATTR30:[0-9]+]]
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @unknown() #0
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_calls_indirect(ptr %indirect) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_calls_indirect(
|
|
; CHECK-SAME: ptr [[INDIRECT:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: call void [[INDIRECT]]()
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void %indirect()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_calls_indirect_marked_callsite(ptr %indirect) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_calls_indirect_marked_callsite(
|
|
; CHECK-SAME: ptr [[INDIRECT:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: call void [[INDIRECT]]() #[[ATTR30]]
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void %indirect() #0
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_transitively_uses_agpr_asm() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_transitively_uses_agpr_asm(
|
|
; CHECK-SAME: ) #[[ATTR1]] {
|
|
; CHECK-NEXT: call void @func_uses_asm_physreg_agpr()
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @func_uses_asm_physreg_agpr()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @empty() {
|
|
; CHECK-LABEL: define void @empty(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @also_empty() {
|
|
; CHECK-LABEL: define void @also_empty(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_calls_empty() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_calls_empty(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: call void @empty()
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @empty()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_calls_non_agpr_and_agpr() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_calls_non_agpr_and_agpr(
|
|
; CHECK-SAME: ) #[[ATTR1]] {
|
|
; CHECK-NEXT: call void @empty()
|
|
; CHECK-NEXT: call void @func_uses_asm_physreg_agpr()
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @empty()
|
|
call void @func_uses_asm_physreg_agpr()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_calls_generic_intrinsic(ptr %ptr0, ptr %ptr1, i64 %size) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_calls_generic_intrinsic(
|
|
; CHECK-SAME: ptr [[PTR0:%.*]], ptr [[PTR1:%.*]], i64 [[SIZE:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[PTR0]], ptr [[PTR1]], i64 [[SIZE]], i1 false)
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @llvm.memcpy.p0.p0.i64(ptr %ptr0, ptr %ptr1, i64 %size, i1 false)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
declare <32 x float> @llvm.amdgcn.mfma.f32.32x32x1f32(float, float, <32 x float>, i32 immarg, i32 immarg, i32 immarg)
|
|
|
|
define amdgpu_kernel void @kernel_calls_mfma.f32.32x32x1f32(ptr addrspace(1) %out, float %a, float %b, <32 x float> %c) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_calls_mfma.f32.32x32x1f32(
|
|
; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]], float [[A:%.*]], float [[B:%.*]], <32 x float> [[C:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call <32 x float> @llvm.amdgcn.mfma.f32.32x32x1f32(float [[A]], float [[B]], <32 x float> [[C]], i32 0, i32 0, i32 0)
|
|
; CHECK-NEXT: store <32 x float> [[RESULT]], ptr addrspace(1) [[OUT]], align 128
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%result = call <32 x float> @llvm.amdgcn.mfma.f32.32x32x1f32(float %a, float %b, <32 x float> %c, i32 0, i32 0, i32 0)
|
|
store <32 x float> %result, ptr addrspace(1) %out
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_calls_workitem_id_x(ptr addrspace(1) %out) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_calls_workitem_id_x(
|
|
; CHECK-SAME: ptr addrspace(1) [[OUT:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.amdgcn.workitem.id.x()
|
|
; CHECK-NEXT: store i32 [[RESULT]], ptr addrspace(1) [[OUT]], align 4
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%result = call i32 @llvm.amdgcn.workitem.id.x()
|
|
store i32 %result, ptr addrspace(1) %out
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @indirect_calls_none_agpr(i1 %cond) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @indirect_calls_none_agpr(
|
|
; CHECK-SAME: i1 [[COND:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: [[FPTR:%.*]] = select i1 [[COND]], ptr @empty, ptr @also_empty
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FPTR]], @also_empty
|
|
; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
|
|
; CHECK: 2:
|
|
; CHECK-NEXT: call void @also_empty()
|
|
; CHECK-NEXT: br label [[TMP6:%.*]]
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]
|
|
; CHECK: 4:
|
|
; CHECK-NEXT: call void @empty()
|
|
; CHECK-NEXT: br label [[TMP6]]
|
|
; CHECK: 5:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 6:
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%fptr = select i1 %cond, ptr @empty, ptr @also_empty
|
|
call void %fptr()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_def_struct_0() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_def_struct_0(
|
|
; CHECK-SAME: ) #[[ATTR2]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call { i32, i32 } asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call {i32, i32} asm sideeffect "; def $0", "=a,=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_use_struct_1() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_use_struct_1(
|
|
; CHECK-SAME: ) #[[ATTR5:[0-9]+]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call { i32, <2 x i32> } asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call {i32, <2 x i32>} asm sideeffect "; def $0", "=a,=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_use_struct_2() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_use_struct_2(
|
|
; CHECK-SAME: ) #[[ATTR1]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call { i32, <2 x i32> } asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call {i32, <2 x i32>} asm sideeffect "; def $0", "=a,=v"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_ptr_ty() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_ptr_ty(
|
|
; CHECK-SAME: ) #[[ATTR2]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a"(ptr poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_def_ptr_ty() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_def_ptr_ty(
|
|
; CHECK-SAME: ) #[[ATTR2]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call ptr asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call ptr asm sideeffect "; def $0", "=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_def_vector_ptr_ty() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_def_vector_ptr_ty(
|
|
; CHECK-SAME: ) #[[ATTR5]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call <2 x ptr> asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call <2 x ptr> asm sideeffect "; def $0", "=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_physreg_def_struct_0() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_physreg_def_struct_0(
|
|
; CHECK-SAME: ) #[[ATTR6:[0-9]+]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call { i32, i32 } asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call {i32, i32} asm sideeffect "; def $0", "={a0},={a[4:5]}"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_clobber() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_clobber(
|
|
; CHECK-SAME: ) #[[ATTR7:[0-9]+]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; clobber $0", "~{a4}"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_clobber_tuple() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_clobber_tuple(
|
|
; CHECK-SAME: ) #[[ATTR8:[0-9]+]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; clobber $0", "~{a[10:13]}"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_clobber_oob() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_clobber_oob(
|
|
; CHECK-SAME: ) #[[ATTR9:[0-9]+]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; clobber $0", "~{a256}"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_clobber_max() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_clobber_max(
|
|
; CHECK-SAME: ) #[[ATTR9]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; clobber $0", "~{a255}"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_physreg_oob() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_physreg_oob(
|
|
; CHECK-SAME: ) #[[ATTR9]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "{a256}"(i32 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_def_max_ty() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_def_max_ty(
|
|
; CHECK-SAME: ) #[[ATTR10:[0-9]+]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call <32 x i32> asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call <32 x i32> asm sideeffect "; def $0", "=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_use_max_ty() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_use_max_ty(
|
|
; CHECK-SAME: ) #[[ATTR10]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a"(<32 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_asm_virtreg_use_def_max_ty() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_asm_virtreg_use_def_max_ty(
|
|
; CHECK-SAME: ) #[[ATTR10]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call <32 x i32> asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call <32 x i32> asm sideeffect "; use $0", "=a,a"(<32 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @vreg_use_exceeds_register_file() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @vreg_use_exceeds_register_file(
|
|
; CHECK-SAME: ) #[[ATTR9]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a"(<257 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @vreg_def_exceeds_register_file() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @vreg_def_exceeds_register_file(
|
|
; CHECK-SAME: ) #[[ATTR9]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call <257 x i32> asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call <257 x i32> asm sideeffect "; def $0", "=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @multiple() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @multiple(
|
|
; CHECK-SAME: ) #[[ATTR10]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call { <16 x i32>, <8 x i32>, <8 x i32> } asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call {<16 x i32>, <8 x i32>, <8 x i32>} asm sideeffect "; def $0", "=a,=a,=a,a,a,a"(<4 x i32> splat (i32 0), <8 x i32> splat (i32 1), i64 999)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @earlyclobber_0() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @earlyclobber_0(
|
|
; CHECK-SAME: ) #[[ATTR11:[0-9]+]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call <8 x i32> asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call <8 x i32> asm sideeffect "; def $0", "=&a,a"(i32 0)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @earlyclobber_1() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @earlyclobber_1(
|
|
; CHECK-SAME: ) #[[ATTR12:[0-9]+]] {
|
|
; CHECK-NEXT: [[DEF:%.*]] = call { <8 x i32>, <16 x i32> } asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%def = call { <8 x i32>, <16 x i32 > } asm sideeffect "; def $0, $1", "=&a,=&a,a,a"(i32 0, <16 x i32> splat (i32 1))
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @physreg_a32__vreg_a256__vreg_a512() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @physreg_a32__vreg_a256__vreg_a512(
|
|
; CHECK-SAME: ) #[[ATTR13:[0-9]+]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0, $1, $2", "{a16},a,a"(i32 poison, <8 x i32> poison, <16 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @physreg_def_a32__def_vreg_a256__def_vreg_a512() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @physreg_def_a32__def_vreg_a256__def_vreg_a512(
|
|
; CHECK-SAME: ) #[[ATTR13]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call { i32, <8 x i32>, <16 x i32> } asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call {i32, <8 x i32>, <16 x i32>} asm sideeffect "; def $0, $1, $2", "={a16},=a,=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @physreg_def_a32___def_vreg_a512_use_vreg_a256() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @physreg_def_a32___def_vreg_a512_use_vreg_a256(
|
|
; CHECK-SAME: ) #[[ATTR14:[0-9]+]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call { i32, <16 x i32> } asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call {i32, <16 x i32>} asm sideeffect "; def $0, $1, $2", "={a16},=a,a"(<8 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @mixed_physreg_vreg_tuples_0() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @mixed_physreg_vreg_tuples_0(
|
|
; CHECK-SAME: ) #[[ATTR11]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0, $1", "{a[1:4]},a"(<4 x i32> poison, <4 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @mixed_physreg_vreg_tuples_1() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @mixed_physreg_vreg_tuples_1(
|
|
; CHECK-SAME: ) #[[ATTR15:[0-9]+]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0, $1", "a,{a[0:3]}"(<4 x i32> poison, <4 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @physreg_raises_limit() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @physreg_raises_limit(
|
|
; CHECK-SAME: ) #[[ATTR16:[0-9]+]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0, $1", "a,{a[5:8]}"(<4 x i32> poison, <4 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @physreg_tuple_alignment_raises_limit() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @physreg_tuple_alignment_raises_limit(
|
|
; CHECK-SAME: ) #[[ATTR11]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0, $1", "a,{a[1:4]}"(<4 x i32> poison, <4 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @align3_virtreg() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @align3_virtreg(
|
|
; CHECK-SAME: ) #[[ATTR6]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0, $1", "a,a"(<3 x i32> poison, <3 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @align3_align4_virtreg() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @align3_align4_virtreg(
|
|
; CHECK-SAME: ) #[[ATTR15]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0, $1", "a,a"(<3 x i32> poison, <4 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @align2_align4_virtreg() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @align2_align4_virtreg(
|
|
; CHECK-SAME: ) #[[ATTR15]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0, $1", "a,a"(<2 x i32> poison, <4 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_write_register_a55() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_write_register_a55(
|
|
; CHECK-SAME: ) #[[ATTR17:[0-9]+]] {
|
|
; CHECK-NEXT: call void @llvm.write_register.i32(metadata [[META0:![0-9]+]], i32 0)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @llvm.write_register.i64(metadata !0, i32 0)
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_write_register_v55() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_write_register_v55(
|
|
; CHECK-SAME: ) #[[ATTR0]] {
|
|
; CHECK-NEXT: call void @llvm.write_register.i32(metadata [[META1:![0-9]+]], i32 0)
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @llvm.write_register.i64(metadata !1, i32 0)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_write_register_a55_57() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_write_register_a55_57(
|
|
; CHECK-SAME: ) #[[ATTR18:[0-9]+]] {
|
|
; CHECK-NEXT: call void @llvm.write_register.i96(metadata [[META2:![0-9]+]], i96 0)
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @llvm.write_register.i64(metadata !2, i96 0)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_read_register_a55(ptr addrspace(1) %ptr) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_read_register_a55(
|
|
; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR19:[0-9]+]] {
|
|
; CHECK-NEXT: [[REG:%.*]] = call i32 @llvm.read_register.i32(metadata [[META0]])
|
|
; CHECK-NEXT: store i32 [[REG]], ptr addrspace(1) [[PTR]], align 4
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%reg = call i32 @llvm.read_register.i64(metadata !0)
|
|
store i32 %reg, ptr addrspace(1) %ptr
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_read_volatile_register_a55(ptr addrspace(1) %ptr) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_read_volatile_register_a55(
|
|
; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR20:[0-9]+]] {
|
|
; CHECK-NEXT: [[REG:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META0]])
|
|
; CHECK-NEXT: store i32 [[REG]], ptr addrspace(1) [[PTR]], align 4
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%reg = call i32 @llvm.read_volatile_register.i64(metadata !0)
|
|
store i32 %reg, ptr addrspace(1) %ptr
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_read_register_a56_59(ptr addrspace(1) %ptr) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_read_register_a56_59(
|
|
; CHECK-SAME: ptr addrspace(1) [[PTR:%.*]]) #[[ATTR21:[0-9]+]] {
|
|
; CHECK-NEXT: [[REG:%.*]] = call i128 @llvm.read_register.i128(metadata [[META3:![0-9]+]])
|
|
; CHECK-NEXT: store i128 [[REG]], ptr addrspace(1) [[PTR]], align 8
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%reg = call i128 @llvm.read_register.i64(metadata !3)
|
|
store i128 %reg, ptr addrspace(1) %ptr
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_write_register_out_of_bounds_a256() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_write_register_out_of_bounds_a256(
|
|
; CHECK-SAME: ) #[[ATTR9]] {
|
|
; CHECK-NEXT: call void @llvm.write_register.i32(metadata [[META4:![0-9]+]], i32 0)
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @llvm.write_register.i64(metadata !4, i32 0)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_multiple_uses() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_multiple_uses(
|
|
; CHECK-SAME: ) #[[ATTR5]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a"(i64 poison)
|
|
call void asm sideeffect "; use $0", "a"(i32 poison)
|
|
call void asm sideeffect "; use $0", "a"(i128 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_multiple_defs() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_multiple_defs(
|
|
; CHECK-SAME: ) #[[ATTR5]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i64 asm sideeffect "
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 asm sideeffect "
|
|
; CHECK-NEXT: [[TMP3:%.*]] = call i128 asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call i64 asm sideeffect "; def $0", "=a"()
|
|
call i32 asm sideeffect "; def $0", "=a"()
|
|
call i128 asm sideeffect "; def $0", "=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_multiple_use_defs() {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_multiple_use_defs(
|
|
; CHECK-SAME: ) #[[ATTR5]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i128 asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a"(i32 poison)
|
|
call i128 asm sideeffect "; def $0", "=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @callgraph_b() {
|
|
; CHECK-LABEL: define void @callgraph_b(
|
|
; CHECK-SAME: ) #[[ATTR15]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> asm sideeffect "
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call <4 x i32> asm sideeffect "; def $0", "=a"()
|
|
call void asm sideeffect "; use $0", "a"(<8 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @callgraph_c() {
|
|
; CHECK-LABEL: define void @callgraph_c(
|
|
; CHECK-SAME: ) #[[ATTR2]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 asm sideeffect "
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call i32 asm sideeffect "; def $0", "=a"()
|
|
call void asm sideeffect "; use $0", "a"(<2 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @callgraph_a(i1 %cond) {
|
|
; CHECK-LABEL: define void @callgraph_a(
|
|
; CHECK-SAME: i1 [[COND:%.*]]) #[[ATTR15]] {
|
|
; CHECK-NEXT: br i1 [[COND]], label [[A:%.*]], label [[B:%.*]]
|
|
; CHECK: a:
|
|
; CHECK-NEXT: call void @callgraph_b()
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: b:
|
|
; CHECK-NEXT: call void @callgraph_c()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
br i1 %cond, label %a, label %b
|
|
|
|
a:
|
|
call void @callgraph_b()
|
|
ret void
|
|
|
|
b:
|
|
call void @callgraph_c()
|
|
ret void
|
|
}
|
|
|
|
|
|
define void @kernel_max_callgraph(i1 %cond) {
|
|
; CHECK-LABEL: define void @kernel_max_callgraph(
|
|
; CHECK-SAME: i1 [[COND:%.*]]) #[[ATTR15]] {
|
|
; CHECK-NEXT: call void @callgraph_a(i1 [[COND]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @callgraph_a(i1 %cond)
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_all_virtregs() #1 {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_all_virtregs(
|
|
; CHECK-SAME: ) #[[ATTR22:[0-9]+]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a,a,a,a,a,a,a,a"(<32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @kernel_uses_all_virtregs_plus_1() #1 {
|
|
; CHECK-LABEL: define amdgpu_kernel void @kernel_uses_all_virtregs_plus_1(
|
|
; CHECK-SAME: ) #[[ATTR22]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a,a,a,a,a,a,a,a,a"(<32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison, <32 x i32> poison, i32 poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @recursive() {
|
|
; CHECK-LABEL: define void @recursive(
|
|
; CHECK-SAME: ) #[[ATTR23:[0-9]+]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: call void @recursive()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a"(<7 x i32> poison)
|
|
call void @use_most()
|
|
call void @recursive()
|
|
ret void
|
|
}
|
|
|
|
define void @indirect_0() {
|
|
; CHECK-LABEL: define void @indirect_0(
|
|
; CHECK-SAME: ) #[[ATTR23]] {
|
|
; CHECK-NEXT: call void asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void asm sideeffect "; use $0", "a"(<7 x i32> poison)
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define void @indirect_1() {
|
|
; CHECK-LABEL: define void @indirect_1(
|
|
; CHECK-SAME: ) #[[ATTR24:[0-9]+]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call <3 x i32> asm sideeffect "
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call <3 x i32> asm sideeffect "; def $0", "=a"()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @knowable_indirect_call(i1 %cond) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @knowable_indirect_call(
|
|
; CHECK-SAME: i1 [[COND:%.*]]) #[[ATTR23]] {
|
|
; CHECK-NEXT: [[FPTR:%.*]] = select i1 [[COND]], ptr @indirect_0, ptr @indirect_1
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FPTR]], @indirect_1
|
|
; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
|
|
; CHECK: 2:
|
|
; CHECK-NEXT: call void @indirect_1()
|
|
; CHECK-NEXT: br label [[TMP6:%.*]]
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]
|
|
; CHECK: 4:
|
|
; CHECK-NEXT: call void @indirect_0()
|
|
; CHECK-NEXT: br label [[TMP6]]
|
|
; CHECK: 5:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 6:
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%fptr = select i1 %cond, ptr @indirect_0, ptr @indirect_1
|
|
call void %fptr()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @calls_poison(i1 %cond) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @calls_poison(
|
|
; CHECK-SAME: i1 [[COND:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: call void poison()
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void poison()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @calls_null(i1 %cond) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @calls_null(
|
|
; CHECK-SAME: i1 [[COND:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: call void null()
|
|
; CHECK-NEXT: call void @use_most()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void null()
|
|
call void @use_most()
|
|
ret void
|
|
}
|
|
|
|
define amdgpu_kernel void @indirect_unknown(ptr %fptr) {
|
|
; CHECK-LABEL: define amdgpu_kernel void @indirect_unknown(
|
|
; CHECK-SAME: ptr [[FPTR:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: call void [[FPTR]]()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void %fptr()
|
|
ret void
|
|
}
|
|
|
|
attributes #0 = { "amdgpu-agpr-alloc"="0" }
|
|
attributes #1 = { "amdgpu-waves-per-eu"="1,1" }
|
|
|
|
!0 = !{!"a55"}
|
|
!1 = !{!"v55"}
|
|
!2 = !{!"a[55:57]"}
|
|
!3 = !{!"a[56:59]"}
|
|
!4 = !{!"a256"}
|
|
|
|
;.
|
|
; CHECK: attributes #[[ATTR0]] = { "amdgpu-agpr-alloc"="0" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR1]] = { "amdgpu-agpr-alloc"="1" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR2]] = { "amdgpu-agpr-alloc"="2" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR3]] = { "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR4:[0-9]+]] = { convergent nocallback nocreateundeforpoison nofree nosync nounwind willreturn memory(none) "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR5]] = { "amdgpu-agpr-alloc"="4" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR6]] = { "amdgpu-agpr-alloc"="6" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR7]] = { "amdgpu-agpr-alloc"="5" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR8]] = { "amdgpu-agpr-alloc"="14" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR9]] = { "amdgpu-agpr-alloc"="256" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR10]] = { "amdgpu-agpr-alloc"="32" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR11]] = { "amdgpu-agpr-alloc"="9" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR12]] = { "amdgpu-agpr-alloc"="64" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR13]] = { "amdgpu-agpr-alloc"="49" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR14]] = { "amdgpu-agpr-alloc"="33" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR15]] = { "amdgpu-agpr-alloc"="8" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR16]] = { "amdgpu-agpr-alloc"="13" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR17]] = { "amdgpu-agpr-alloc"="56" "amdgpu-no-cluster-id-x" "amdgpu-no-cluster-id-y" "amdgpu-no-cluster-id-z" "amdgpu-no-completion-action" "amdgpu-no-default-queue" "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-flat-scratch-init" "amdgpu-no-heap-ptr" "amdgpu-no-hostcall-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-lds-kernel-id" "amdgpu-no-multigrid-sync-arg" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR18]] = { "amdgpu-agpr-alloc"="58" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR19]] = { "amdgpu-agpr-alloc"="56" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR20]] = { "amdgpu-agpr-alloc"="56" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR21]] = { "amdgpu-agpr-alloc"="60" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR22]] = { "amdgpu-agpr-alloc"="256" "amdgpu-no-wwm" "amdgpu-waves-per-eu"="1,1" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR23]] = { "amdgpu-agpr-alloc"="7" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR24]] = { "amdgpu-agpr-alloc"="3" "amdgpu-no-wwm" "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR25:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR26:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR27:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(read) "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR28:[0-9]+]] = { nounwind "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR29:[0-9]+]] = { nocallback nounwind "target-cpu"="gfx90a" }
|
|
; CHECK: attributes #[[ATTR30]] = { "amdgpu-agpr-alloc"="0" }
|
|
;.
|
|
; CHECK: [[META0]] = !{!"a55"}
|
|
; CHECK: [[META1]] = !{!"v55"}
|
|
; CHECK: [[META2]] = !{!"a[55:57]"}
|
|
; CHECK: [[META3]] = !{!"a[56:59]"}
|
|
; CHECK: [[META4]] = !{!"a256"}
|
|
;.
|