The KernelEnvironment is for compile time information about a kernel. It allows the compiler to feed information to the runtime. The KernelLaunchEnvironment is for dynamic information *per* kernel launch. It allows the rutime to feed information to the kernel that is not shared with other invocations of the kernel. The first use case is to replace the globals that synchronize teams reductions with per-launch versions. This allows concurrent teams reductions. More uses cases will follow, e.g., per launch memory pools. Fixes: https://github.com/llvm/llvm-project/issues/70249
893 lines
31 KiB
LLVM
893 lines
31 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
|
; RUN: opt -aa-pipeline=basic-aa -passes=openmp-opt -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
|
|
; RUN: opt -aa-pipeline=basic-aa -passes=openmp-opt-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
|
|
|
|
target triple = "amdgcn-amd-amdhsa"
|
|
|
|
%struct.ConfigurationEnvironmentTy = type { i8, i8, i8, i32, i32, i32, i32 }
|
|
%struct.KernelEnvironmentTy = type { %struct.ConfigurationEnvironmentTy, ptr, ptr }
|
|
|
|
@G = internal addrspace(3) global i32 undef, align 4
|
|
@H = internal addrspace(3) global i32 undef, align 4
|
|
@X = internal addrspace(3) global i32 undef, align 4
|
|
@QA1 = internal addrspace(3) global i32 undef, align 4
|
|
@QB1 = internal addrspace(3) global i32 undef, align 4
|
|
@QC1 = internal addrspace(3) global i32 undef, align 4
|
|
@QD1 = internal addrspace(3) global i32 undef, align 4
|
|
@QA2 = internal addrspace(3) global i32 undef, align 4
|
|
@QB2 = internal addrspace(3) global i32 undef, align 4
|
|
@QC2 = internal addrspace(3) global i32 undef, align 4
|
|
@QD2 = internal addrspace(3) global i32 undef, align 4
|
|
@QA3 = internal addrspace(3) global i32 undef, align 4
|
|
@QB3 = internal addrspace(3) global i32 undef, align 4
|
|
@QC3 = internal addrspace(3) global i32 undef, align 4
|
|
@QD3 = internal addrspace(3) global i32 undef, align 4
|
|
@UAA1 = internal addrspace(3) global i32 undef, align 4
|
|
@UAA2 = internal addrspace(3) global i32 undef, align 4
|
|
@UAA3 = internal addrspace(3) global i32 undef, align 4
|
|
@UANA1 = internal addrspace(3) global i32 undef, align 4
|
|
@str = private unnamed_addr addrspace(4) constant [1 x i8] c"\00", align 1
|
|
@kernel_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 0, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null }
|
|
|
|
; Make sure we do not delete the stores to @G without also replacing the load with `1`.
|
|
;.
|
|
; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[H:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[X:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QA1:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QB1:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QC1:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QD1:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QA2:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QB2:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QC2:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QD2:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QA3:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QB3:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QC3:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[QD3:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[UAA1:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[UAA2:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[UAA3:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[UANA1:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 undef, align 4
|
|
; CHECK: @[[STR:[a-zA-Z0-9_$"\\.-]+]] = private unnamed_addr addrspace(4) constant [1 x i8] zeroinitializer, align 1
|
|
; CHECK: @[[KERNEL_KERNEL_ENVIRONMENT:[a-zA-Z0-9_$"\\.-]+]] = local_unnamed_addr constant [[STRUCT_KERNELENVIRONMENTTY:%.*]] { [[STRUCT_CONFIGURATIONENVIRONMENTTY:%.*]] { i8 0, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null }
|
|
;.
|
|
define void @kernel(ptr %dyn) "kernel" {
|
|
;
|
|
; TUNIT: Function Attrs: norecurse
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel
|
|
; TUNIT-SAME: (ptr [[DYN:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; TUNIT-NEXT: [[CALL:%.*]] = call i32 @__kmpc_target_init(ptr @kernel_kernel_environment, ptr [[DYN]])
|
|
; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], -1
|
|
; TUNIT-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
; TUNIT: if.then:
|
|
; TUNIT-NEXT: br label [[IF_MERGE:%.*]]
|
|
; TUNIT: if.else:
|
|
; TUNIT-NEXT: call void @barrier() #[[ATTR6:[0-9]+]]
|
|
; TUNIT-NEXT: call void @use1(i32 1) #[[ATTR7:[0-9]+]]
|
|
; TUNIT-NEXT: call void @llvm.assume(i1 true)
|
|
; TUNIT-NEXT: call void @barrier() #[[ATTR6]]
|
|
; TUNIT-NEXT: br label [[IF_MERGE]]
|
|
; TUNIT: if.merge:
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: br i1 [[CMP]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
|
|
; TUNIT: if.then2:
|
|
; TUNIT-NEXT: call void @barrier() #[[ATTR6]]
|
|
; TUNIT-NEXT: br label [[IF_END]]
|
|
; TUNIT: if.end:
|
|
; TUNIT-NEXT: call void @__kmpc_target_deinit()
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel
|
|
; CGSCC-SAME: (ptr [[DYN:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CGSCC-NEXT: [[CALL:%.*]] = call i32 @__kmpc_target_init(ptr @kernel_kernel_environment, ptr [[DYN]])
|
|
; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], -1
|
|
; CGSCC-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
; CGSCC: if.then:
|
|
; CGSCC-NEXT: br label [[IF_MERGE:%.*]]
|
|
; CGSCC: if.else:
|
|
; CGSCC-NEXT: call void @barrier() #[[ATTR6:[0-9]+]]
|
|
; CGSCC-NEXT: call void @use1(i32 1) #[[ATTR6]]
|
|
; CGSCC-NEXT: call void @llvm.assume(i1 true)
|
|
; CGSCC-NEXT: call void @barrier() #[[ATTR6]]
|
|
; CGSCC-NEXT: br label [[IF_MERGE]]
|
|
; CGSCC: if.merge:
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: br i1 [[CMP]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
|
|
; CGSCC: if.then2:
|
|
; CGSCC-NEXT: call void @barrier() #[[ATTR6]]
|
|
; CGSCC-NEXT: br label [[IF_END]]
|
|
; CGSCC: if.end:
|
|
; CGSCC-NEXT: call void @__kmpc_target_deinit()
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
%call = call i32 @__kmpc_target_init(ptr @kernel_kernel_environment, ptr %dyn)
|
|
%cmp = icmp eq i32 %call, -1
|
|
br i1 %cmp, label %if.then, label %if.else
|
|
if.then:
|
|
store i32 1, ptr addrspace(3) @G
|
|
store i32 2, ptr addrspace(3) @H
|
|
br label %if.merge
|
|
if.else:
|
|
call void @barrier();
|
|
%l = load i32, ptr addrspace(3) @G
|
|
call void @use1(i32 %l)
|
|
%hv = load i32, ptr addrspace(3) @H
|
|
%hc = icmp eq i32 %hv, 2
|
|
call void @llvm.assume(i1 %hc)
|
|
call void @barrier();
|
|
br label %if.merge
|
|
if.merge:
|
|
%hreload = load i32, ptr addrspace(3) @H
|
|
call void @use1(i32 %hreload)
|
|
br i1 %cmp, label %if.then2, label %if.end
|
|
if.then2:
|
|
store i32 2, ptr addrspace(3) @G
|
|
call void @barrier();
|
|
br label %if.end
|
|
if.end:
|
|
call void @__kmpc_target_deinit()
|
|
ret void
|
|
}
|
|
|
|
define void @test_assume() {
|
|
; CHECK-LABEL: define {{[^@]+}}@test_assume() {
|
|
; CHECK-NEXT: call void @llvm.assume(i1 icmp ne (ptr addrspacecast (ptr addrspace(4) @str to ptr), ptr null))
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @llvm.assume(i1 icmp ne (ptr addrspacecast (ptr addrspace(4) @str to ptr), ptr null))
|
|
ret void
|
|
}
|
|
|
|
; We can't ignore the sync, hence this might store 2 into %p
|
|
define void @kernel2(ptr %p) "kernel" {
|
|
; CHECK-LABEL: define {{[^@]+}}@kernel2
|
|
; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
; CHECK-NEXT: store i32 1, ptr addrspace(3) @X, align 4
|
|
; CHECK-NEXT: call void @sync()
|
|
; CHECK-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @X, align 4
|
|
; CHECK-NEXT: store i32 2, ptr addrspace(3) @X, align 4
|
|
; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
store i32 1, ptr addrspace(3) @X
|
|
call void @sync()
|
|
%v = load i32, ptr addrspace(3) @X
|
|
store i32 2, ptr addrspace(3) @X
|
|
store i32 %v, ptr %p
|
|
ret void
|
|
}
|
|
|
|
; We can't ignore the sync, hence this might store 2 into %p
|
|
define void @kernel3(ptr %p) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel3
|
|
; TUNIT-SAME: (ptr [[P:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: store i32 1, ptr addrspace(3) @X, align 4
|
|
; TUNIT-NEXT: call void @sync_def.internalized()
|
|
; TUNIT-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @X, align 4
|
|
; TUNIT-NEXT: store i32 2, ptr addrspace(3) @X, align 4
|
|
; TUNIT-NEXT: store i32 [[V]], ptr [[P]], align 4
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel3
|
|
; CGSCC-SAME: (ptr [[P:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: store i32 1, ptr addrspace(3) @X, align 4
|
|
; CGSCC-NEXT: call void @sync_def()
|
|
; CGSCC-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @X, align 4
|
|
; CGSCC-NEXT: store i32 2, ptr addrspace(3) @X, align 4
|
|
; CGSCC-NEXT: store i32 [[V]], ptr [[P]], align 4
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
store i32 1, ptr addrspace(3) @X
|
|
call void @sync_def()
|
|
%v = load i32, ptr addrspace(3) @X
|
|
store i32 2, ptr addrspace(3) @X
|
|
store i32 %v, ptr %p
|
|
ret void
|
|
}
|
|
|
|
define void @sync_def() {
|
|
; CHECK-LABEL: define {{[^@]+}}@sync_def() {
|
|
; CHECK-NEXT: call void @sync()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @sync()
|
|
ret void
|
|
}
|
|
|
|
define void @kernel4a1(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4a1
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: store i32 0, ptr addrspace(3) @QA1, align 4
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QA1, align 4
|
|
; TUNIT-NEXT: call void @use1(i32 [[V]]) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: store i32 2, ptr addrspace(3) @QA1, align 4
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4a1
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: store i32 0, ptr addrspace(3) @QA1, align 4
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QA1, align 4
|
|
; CGSCC-NEXT: call void @use1(i32 [[V]]) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: store i32 2, ptr addrspace(3) @QA1, align 4
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
store i32 0, ptr addrspace(3) @QA1
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @sync();
|
|
%v = load i32, ptr addrspace(3) @QA1
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QA1
|
|
call void @sync();
|
|
ret void
|
|
}
|
|
|
|
; We should not replace the load or delete the second store.
|
|
define void @kernel4b1(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4b1
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: store i32 0, ptr addrspace(3) @QB1, align 4
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QB1, align 4
|
|
; TUNIT-NEXT: call void @use1(i32 [[V]]) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: store i32 2, ptr addrspace(3) @QB1, align 4
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4b1
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: store i32 0, ptr addrspace(3) @QB1, align 4
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QB1, align 4
|
|
; CGSCC-NEXT: call void @use1(i32 [[V]]) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: store i32 2, ptr addrspace(3) @QB1, align 4
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
store i32 0, ptr addrspace(3) @QB1
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @sync();
|
|
%v = load i32, ptr addrspace(3) @QB1
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QB1
|
|
ret void
|
|
}
|
|
|
|
define void @kernel4a2(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4a2
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4a2
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @sync();
|
|
%v = load i32, ptr addrspace(3) @QA2
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QA2
|
|
call void @sync();
|
|
ret void
|
|
}
|
|
|
|
; FIXME: We should not replace the load with undef.
|
|
define void @kernel4b2(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4b2
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4b2
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @sync();
|
|
%v = load i32, ptr addrspace(3) @QB2
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QB2
|
|
ret void
|
|
}
|
|
|
|
define void @kernel4a3(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4a3
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: store i32 0, ptr addrspace(3) @QA3, align 4
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QA3, align 4
|
|
; TUNIT-NEXT: call void @use1(i32 [[V]]) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: store i32 2, ptr addrspace(3) @QA3, align 4
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4a3
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: store i32 0, ptr addrspace(3) @QA3, align 4
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QA3, align 4
|
|
; CGSCC-NEXT: call void @use1(i32 [[V]]) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: store i32 2, ptr addrspace(3) @QA3, align 4
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
store i32 0, ptr addrspace(3) @QA3
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @sync();
|
|
%v = load i32, ptr addrspace(3) @QA3
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QA3
|
|
call void @sync();
|
|
call void @sync();
|
|
call void @sync();
|
|
call void @sync();
|
|
ret void
|
|
}
|
|
|
|
; The load of QB3 should not be simplified to 0.
|
|
define void @kernel4b3(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4b3
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: store i32 0, ptr addrspace(3) @QB3, align 4
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QB3, align 4
|
|
; TUNIT-NEXT: call void @use1(i32 [[V]]) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: store i32 2, ptr addrspace(3) @QB3, align 4
|
|
; TUNIT-NEXT: call void @use1(i32 0) #[[ATTR7]]
|
|
; TUNIT-NEXT: call void @use1(i32 1) #[[ATTR7]]
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: call void @use1(i32 3) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4b3
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: store i32 0, ptr addrspace(3) @QB3, align 4
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QB3, align 4
|
|
; CGSCC-NEXT: call void @use1(i32 [[V]]) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: store i32 2, ptr addrspace(3) @QB3, align 4
|
|
; CGSCC-NEXT: call void @use1(i32 0) #[[ATTR6]]
|
|
; CGSCC-NEXT: call void @use1(i32 1) #[[ATTR6]]
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: call void @use1(i32 3) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
store i32 0, ptr addrspace(3) @QB3
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @sync();
|
|
%v = load i32, ptr addrspace(3) @QB3
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QB3
|
|
call void @use1(i32 0)
|
|
call void @use1(i32 1)
|
|
call void @use1(i32 2)
|
|
call void @use1(i32 3)
|
|
ret void
|
|
}
|
|
|
|
|
|
define void @kernel4c1(i1 %c) "kernel" {
|
|
; TUNIT: Function Attrs: norecurse
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4c1
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @use1(i32 0) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4c1
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @use1(i32 0) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
store i32 0, ptr addrspace(3) @QC1
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @barrier();
|
|
%v = load i32, ptr addrspace(3) @QC1
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QC1
|
|
call void @barrier();
|
|
ret void
|
|
}
|
|
|
|
; We should not replace the load or delete the second store.
|
|
define void @kernel4d1(i1 %c) "kernel" {
|
|
; TUNIT: Function Attrs: norecurse
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4d1
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; TUNIT-NEXT: store i32 0, ptr addrspace(3) @QD1, align 4
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @barrier() #[[ATTR7]]
|
|
; TUNIT-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QD1, align 4
|
|
; TUNIT-NEXT: call void @use1(i32 [[V]]) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: store i32 2, ptr addrspace(3) @QD1, align 4
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4d1
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; CGSCC-NEXT: store i32 0, ptr addrspace(3) @QD1, align 4
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @barrier() #[[ATTR6]]
|
|
; CGSCC-NEXT: [[V:%.*]] = load i32, ptr addrspace(3) @QD1, align 4
|
|
; CGSCC-NEXT: call void @use1(i32 [[V]]) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: store i32 2, ptr addrspace(3) @QD1, align 4
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
store i32 0, ptr addrspace(3) @QD1
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @barrier();
|
|
%v = load i32, ptr addrspace(3) @QD1
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QD1
|
|
ret void
|
|
}
|
|
|
|
define void @kernel4c2(i1 %c) "kernel" {
|
|
; TUNIT: Function Attrs: norecurse
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4c2
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @use1(i32 undef) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4c2
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @use1(i32 undef) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @barrier();
|
|
%v = load i32, ptr addrspace(3) @QC2
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QC2
|
|
call void @barrier();
|
|
ret void
|
|
}
|
|
|
|
; We should not replace the load with undef.
|
|
define void @kernel4d2(i1 %c) "kernel" {
|
|
; TUNIT: Function Attrs: norecurse
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4d2
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4d2
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @barrier();
|
|
%v = load i32, ptr addrspace(3) @QD2
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QD2
|
|
ret void
|
|
}
|
|
|
|
define void @kernel4c3(i1 %c) "kernel" {
|
|
; TUNIT: Function Attrs: norecurse
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4c3
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @use1(i32 undef) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4c3
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @use1(i32 undef) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @barrier();
|
|
%v = load i32, ptr addrspace(3) @QC3
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QC3
|
|
call void @barrier();
|
|
ret void
|
|
}
|
|
|
|
; We should not replace the load with undef.
|
|
define void @kernel4d3(i1 %c) "kernel" {
|
|
; TUNIT: Function Attrs: norecurse
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel4d3
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel4d3
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @barrier();
|
|
%v = load i32, ptr addrspace(3) @QD3
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
store i32 2, ptr addrspace(3) @QD3
|
|
ret void
|
|
}
|
|
|
|
define void @kernel_unknown_and_aligned1(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel_unknown_and_aligned1
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @barrier() #[[ATTR7]]
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel_unknown_and_aligned1
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @barrier() #[[ATTR6]]
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @barrier();
|
|
%v = load i32, ptr addrspace(3) @UAA1
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
call void @sync();
|
|
store i32 2, ptr addrspace(3) @UAA1
|
|
call void @barrier();
|
|
call void @sync();
|
|
ret void
|
|
}
|
|
|
|
define void @kernel_unknown_and_aligned2(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel_unknown_and_aligned2
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @barrier() #[[ATTR7]]
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel_unknown_and_aligned2
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @barrier() #[[ATTR6]]
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @sync();
|
|
%v = load i32, ptr addrspace(3) @UAA2
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
call void @sync();
|
|
store i32 2, ptr addrspace(3) @UAA2
|
|
call void @barrier();
|
|
call void @sync();
|
|
ret void
|
|
}
|
|
|
|
define void @kernel_unknown_and_aligned3(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel_unknown_and_aligned3
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: call void @barrier() #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel_unknown_and_aligned3
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: call void @barrier() #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @sync();
|
|
%v = load i32, ptr addrspace(3) @UAA3
|
|
call void @use1(i32 %v)
|
|
call void @barrier();
|
|
ret void
|
|
S:
|
|
call void @sync();
|
|
store i32 2, ptr addrspace(3) @UAA3
|
|
call void @sync();
|
|
ret void
|
|
}
|
|
|
|
define void @kernel_unknown_and_not_aligned1(i1 %c) "kernel" {
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel_unknown_and_not_aligned1
|
|
; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; TUNIT: L:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @use1(i32 2) #[[ATTR7]]
|
|
; TUNIT-NEXT: ret void
|
|
; TUNIT: S:
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: call void @sync()
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel_unknown_and_not_aligned1
|
|
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: br i1 [[C]], label [[S:%.*]], label [[L:%.*]]
|
|
; CGSCC: L:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @use1(i32 2) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
; CGSCC: S:
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: call void @sync()
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
br i1 %c, label %S, label %L
|
|
L:
|
|
call void @sync();
|
|
%v = load i32, ptr addrspace(3) @UANA1
|
|
call void @use1(i32 %v)
|
|
ret void
|
|
S:
|
|
call void @sync();
|
|
store i32 2, ptr addrspace(3) @UANA1
|
|
call void @sync();
|
|
ret void
|
|
}
|
|
|
|
declare void @sync()
|
|
declare void @barrier() norecurse nounwind nocallback "llvm.assume"="ompx_aligned_barrier"
|
|
declare void @use1(i32) nosync norecurse nounwind nocallback
|
|
declare i32 @__kmpc_target_init(ptr, ptr) nocallback
|
|
declare void @__kmpc_target_deinit() nocallback
|
|
declare void @llvm.assume(i1)
|
|
|
|
!llvm.module.flags = !{!0, !1}
|
|
!nvvm.annotations = !{!2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20}
|
|
|
|
!0 = !{i32 7, !"openmp", i32 50}
|
|
!1 = !{i32 7, !"openmp-device", i32 50}
|
|
!2 = !{ptr @kernel, !"kernel", i32 1}
|
|
!3 = !{ptr @kernel2, !"kernel", i32 1}
|
|
!4 = !{ptr @kernel3, !"kernel", i32 1}
|
|
!5 = !{ptr @kernel4a1, !"kernel", i32 1}
|
|
!6 = !{ptr @kernel4b1, !"kernel", i32 1}
|
|
!7 = !{ptr @kernel4a2, !"kernel", i32 1}
|
|
!8 = !{ptr @kernel4b2, !"kernel", i32 1}
|
|
!9 = !{ptr @kernel4a3, !"kernel", i32 1}
|
|
!10 = !{ptr @kernel4b3, !"kernel", i32 1}
|
|
!11 = !{ptr @kernel4c1, !"kernel", i32 1}
|
|
!12 = !{ptr @kernel4d1, !"kernel", i32 1}
|
|
!13 = !{ptr @kernel4c2, !"kernel", i32 1}
|
|
!14 = !{ptr @kernel4d2, !"kernel", i32 1}
|
|
!15 = !{ptr @kernel4c3, !"kernel", i32 1}
|
|
!16 = !{ptr @kernel4d3, !"kernel", i32 1}
|
|
!17 = !{ptr @kernel_unknown_and_aligned1, !"kernel", i32 1}
|
|
!18 = !{ptr @kernel_unknown_and_aligned2, !"kernel", i32 1}
|
|
!19 = !{ptr @kernel_unknown_and_aligned3, !"kernel", i32 1}
|
|
!20 = !{ptr @kernel_unknown_and_not_aligned1, !"kernel", i32 1}
|
|
|
|
;.
|
|
; TUNIT: attributes #[[ATTR0]] = { norecurse "kernel" }
|
|
; TUNIT: attributes #[[ATTR1]] = { "kernel" }
|
|
; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nocallback norecurse nounwind "llvm.assume"="ompx_aligned_barrier" }
|
|
; TUNIT: attributes #[[ATTR3:[0-9]+]] = { nocallback norecurse nosync nounwind }
|
|
; TUNIT: attributes #[[ATTR4:[0-9]+]] = { nocallback }
|
|
; TUNIT: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
|
|
; TUNIT: attributes #[[ATTR6]] = { nounwind "llvm.assume"="ompx_aligned_barrier" }
|
|
; TUNIT: attributes #[[ATTR7]] = { nounwind }
|
|
;.
|
|
; CGSCC: attributes #[[ATTR0]] = { norecurse "kernel" }
|
|
; CGSCC: attributes #[[ATTR1]] = { "kernel" }
|
|
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nocallback norecurse nounwind "llvm.assume"="ompx_aligned_barrier" }
|
|
; CGSCC: attributes #[[ATTR3:[0-9]+]] = { nocallback norecurse nosync nounwind }
|
|
; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nocallback }
|
|
; CGSCC: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
|
|
; CGSCC: attributes #[[ATTR6]] = { nounwind }
|
|
;.
|
|
; CHECK: [[META0:![0-9]+]] = !{i32 7, !"openmp", i32 50}
|
|
; CHECK: [[META1:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
|
|
; CHECK: [[META2:![0-9]+]] = !{ptr @kernel, !"kernel", i32 1}
|
|
; CHECK: [[META3:![0-9]+]] = !{ptr @kernel2, !"kernel", i32 1}
|
|
; CHECK: [[META4:![0-9]+]] = !{ptr @kernel3, !"kernel", i32 1}
|
|
; CHECK: [[META5:![0-9]+]] = !{ptr @kernel4a1, !"kernel", i32 1}
|
|
; CHECK: [[META6:![0-9]+]] = !{ptr @kernel4b1, !"kernel", i32 1}
|
|
; CHECK: [[META7:![0-9]+]] = !{ptr @kernel4a2, !"kernel", i32 1}
|
|
; CHECK: [[META8:![0-9]+]] = !{ptr @kernel4b2, !"kernel", i32 1}
|
|
; CHECK: [[META9:![0-9]+]] = !{ptr @kernel4a3, !"kernel", i32 1}
|
|
; CHECK: [[META10:![0-9]+]] = !{ptr @kernel4b3, !"kernel", i32 1}
|
|
; CHECK: [[META11:![0-9]+]] = !{ptr @kernel4c1, !"kernel", i32 1}
|
|
; CHECK: [[META12:![0-9]+]] = !{ptr @kernel4d1, !"kernel", i32 1}
|
|
; CHECK: [[META13:![0-9]+]] = !{ptr @kernel4c2, !"kernel", i32 1}
|
|
; CHECK: [[META14:![0-9]+]] = !{ptr @kernel4d2, !"kernel", i32 1}
|
|
; CHECK: [[META15:![0-9]+]] = !{ptr @kernel4c3, !"kernel", i32 1}
|
|
; CHECK: [[META16:![0-9]+]] = !{ptr @kernel4d3, !"kernel", i32 1}
|
|
; CHECK: [[META17:![0-9]+]] = !{ptr @kernel_unknown_and_aligned1, !"kernel", i32 1}
|
|
; CHECK: [[META18:![0-9]+]] = !{ptr @kernel_unknown_and_aligned2, !"kernel", i32 1}
|
|
; CHECK: [[META19:![0-9]+]] = !{ptr @kernel_unknown_and_aligned3, !"kernel", i32 1}
|
|
; CHECK: [[META20:![0-9]+]] = !{ptr @kernel_unknown_and_not_aligned1, !"kernel", i32 1}
|
|
;.
|