This switches everything to use the memory attribute proposed in https://discourse.llvm.org/t/rfc-unify-memory-effect-attributes/65579. The old argmemonly, inaccessiblememonly and inaccessiblemem_or_argmemonly attributes are dropped. The readnone, readonly and writeonly attributes are restricted to parameters only. The old attributes are auto-upgraded both in bitcode and IR. The bitcode upgrade is a policy requirement that has to be retained indefinitely. The IR upgrade is mainly there so it's not necessary to update all tests using memory attributes in this patch, which is already large enough. We could drop that part after migrating tests, or retain it longer term, to make it easier to import IR from older LLVM versions. High-level Function/CallBase APIs like doesNotAccessMemory() or setDoesNotAccessMemory() are mapped transparently to the memory attribute. Code that directly manipulates attributes (e.g. via AttributeList) on the other hand needs to switch to working with the memory attribute instead. Differential Revision: https://reviews.llvm.org/D135780
377 lines
17 KiB
LLVM
377 lines
17 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=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
|
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
|
|
|
|
target triple = "amdgcn-amd-amdhsa"
|
|
|
|
@ReachableKernel = internal addrspace(3) global i32 3, align 4
|
|
@UnreachableKernel = internal addrspace(3) global i32 42, align 4
|
|
@ReachableKernelAS0 = internal global i32 7, align 4
|
|
|
|
;.
|
|
; CHECK: @[[REACHABLEKERNEL:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 3, align 4
|
|
; CHECK: @[[UNREACHABLEKERNEL:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 42, align 4
|
|
; CHECK: @[[REACHABLEKERNELAS0:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 7, align 4
|
|
; CHECK: @[[REACHABLENONKERNEL:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 0, align 4
|
|
; CHECK: @[[UNREACHABLENONKERNEL:[a-zA-Z0-9_$"\\.-]+]] = internal addrspace(3) global i32 0, align 4
|
|
;.
|
|
define dso_local void @kernel(i32 %C) norecurse "kernel" {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@kernel
|
|
; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: call void @level1Kernel(i32 [[C]]) #[[ATTR3:[0-9]+]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@kernel
|
|
; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: call void @level1Kernel(i32 [[C]]) #[[ATTR4:[0-9]+]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
call void @level1Kernel(i32 %C)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level1Kernel(i32 %C) {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@level1Kernel
|
|
; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: call void @level2Kernelall_early() #[[ATTR4:[0-9]+]]
|
|
; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
|
|
; TUNIT-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
; TUNIT: if.then:
|
|
; TUNIT-NEXT: call void @level2Kernela() #[[ATTR3]]
|
|
; TUNIT-NEXT: br label [[IF_END:%.*]]
|
|
; TUNIT: if.else:
|
|
; TUNIT-NEXT: call void @level2Kernelb() #[[ATTR3]]
|
|
; TUNIT-NEXT: br label [[IF_END]]
|
|
; TUNIT: if.end:
|
|
; TUNIT-NEXT: call void @level2Kernelall_late() #[[ATTR3]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@level1Kernel
|
|
; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: call void @level2Kernelall_early() #[[ATTR5:[0-9]+]]
|
|
; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
|
|
; CGSCC-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
; CGSCC: if.then:
|
|
; CGSCC-NEXT: call void @level2Kernela() #[[ATTR4]]
|
|
; CGSCC-NEXT: br label [[IF_END:%.*]]
|
|
; CGSCC: if.else:
|
|
; CGSCC-NEXT: call void @level2Kernelb() #[[ATTR4]]
|
|
; CGSCC-NEXT: br label [[IF_END]]
|
|
; CGSCC: if.end:
|
|
; CGSCC-NEXT: call void @level2Kernelall_late() #[[ATTR4]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
call void @level2Kernelall_early()
|
|
%tobool = icmp ne i32 %C, 0
|
|
br i1 %tobool, label %if.then, label %if.else
|
|
|
|
if.then: ; preds = %entry
|
|
call void @level2Kernela()
|
|
br label %if.end
|
|
|
|
if.else: ; preds = %entry
|
|
call void @level2Kernelb()
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %if.else, %if.then
|
|
call void @level2Kernelall_late()
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2Kernelall_early() {
|
|
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
|
|
; CHECK-LABEL: define {{[^@]+}}@level2Kernelall_early
|
|
; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store i32 1, i32* @ReachableKernelAS0, align 4
|
|
; CHECK-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i32 1, i32* @ReachableKernelAS0, align 4
|
|
store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2Kernela() {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2Kernela
|
|
; TUNIT-SAME: () #[[ATTR1]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
|
|
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR5:[0-9]+]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2Kernela
|
|
; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
|
|
; CGSCC-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
|
|
; CGSCC-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR4]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
|
|
%1 = load i32, i32* @ReachableKernelAS0, align 4
|
|
%2 = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
|
|
call void @use(i32 %0, i32 %1, i32 %2)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2Kernelb() {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2Kernelb
|
|
; TUNIT-SAME: () #[[ATTR1]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
|
|
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef 42) #[[ATTR5]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2Kernelb
|
|
; CGSCC-SAME: () #[[ATTR3]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
|
|
; CGSCC-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
|
|
; CGSCC-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR4]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
|
|
%1 = load i32, i32* @ReachableKernelAS0, align 4
|
|
%2 = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
|
|
call void @use(i32 %0, i32 %1, i32 %2)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2Kernelall_late() {
|
|
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2Kernelall_late
|
|
; TUNIT-SAME: () #[[ATTR2]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2Kernelall_late
|
|
; CGSCC-SAME: () #[[ATTR2]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i32 1, i32 *addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
|
|
ret void
|
|
}
|
|
|
|
@ReachableNonKernel = internal addrspace(3) global i32 0, align 4
|
|
@UnreachableNonKernel = internal addrspace(3) global i32 0, align 4
|
|
|
|
define dso_local void @non_kernel(i32 %C) norecurse {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@non_kernel
|
|
; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: call void @level1(i32 [[C]]) #[[ATTR3]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@non_kernel
|
|
; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: call void @level1(i32 [[C]]) #[[ATTR4]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
call void @level1(i32 %C)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level1(i32 %C) {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@level1
|
|
; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: [[LOCAL:%.*]] = alloca i32, align 4
|
|
; TUNIT-NEXT: call void @level2all_early(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]]
|
|
; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
|
|
; TUNIT-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
; TUNIT: if.then:
|
|
; TUNIT-NEXT: call void @level2a() #[[ATTR3]]
|
|
; TUNIT-NEXT: br label [[IF_END:%.*]]
|
|
; TUNIT: if.else:
|
|
; TUNIT-NEXT: call void @level2b() #[[ATTR3]]
|
|
; TUNIT-NEXT: br label [[IF_END]]
|
|
; TUNIT: if.end:
|
|
; TUNIT-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR3]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: norecurse nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@level1
|
|
; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[LOCAL:%.*]] = alloca i32, align 4
|
|
; CGSCC-NEXT: call void @level2all_early(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR5]]
|
|
; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
|
|
; CGSCC-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
; CGSCC: if.then:
|
|
; CGSCC-NEXT: call void @level2a(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]]
|
|
; CGSCC-NEXT: br label [[IF_END:%.*]]
|
|
; CGSCC: if.else:
|
|
; CGSCC-NEXT: call void @level2b(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]]
|
|
; CGSCC-NEXT: br label [[IF_END]]
|
|
; CGSCC: if.end:
|
|
; CGSCC-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
%local = alloca i32
|
|
call void @level2all_early(i32* %local)
|
|
%tobool = icmp ne i32 %C, 0
|
|
br i1 %tobool, label %if.then, label %if.else
|
|
|
|
if.then: ; preds = %entry
|
|
call void @level2a(i32* %local)
|
|
br label %if.end
|
|
|
|
if.else: ; preds = %entry
|
|
call void @level2b(i32* %local)
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %if.else, %if.then
|
|
call void @level2all_late(i32* %local)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2all_early(i32* %addr) {
|
|
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2all_early
|
|
; TUNIT-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2all_early
|
|
; CGSCC-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
|
|
; CGSCC-NEXT: store i32 17, i32* [[ADDR]], align 4
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
|
|
store i32 17, i32* %addr, align 4
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2a(i32* %addr) {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2a
|
|
; TUNIT-SAME: () #[[ATTR1]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
|
|
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR5]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2a
|
|
; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR3]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
|
|
; CGSCC-NEXT: [[QQQQ2:%.*]] = load i32, i32* [[ADDR]], align 4
|
|
; CGSCC-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[QQQQ2]]) #[[ATTR4]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
|
|
%1 = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
|
|
%qqqq2 = load i32, i32* %addr
|
|
call void @use(i32 %0, i32 %1, i32 %qqqq2)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2b(i32* %addr) {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2b
|
|
; TUNIT-SAME: () #[[ATTR1]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
|
|
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR5]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2b
|
|
; CGSCC-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR3]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
|
|
; CGSCC-NEXT: [[TMP2:%.*]] = load i32, i32* [[ADDR]], align 4
|
|
; CGSCC-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[TMP2]]) #[[ATTR4]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
|
|
%1 = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
|
|
%2 = load i32, i32* %addr
|
|
call void @use(i32 %0, i32 %1, i32 %2)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2all_late(i32* %addr) {
|
|
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2all_late
|
|
; TUNIT-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(write)
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2all_late
|
|
; CGSCC-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
|
|
; CGSCC-NEXT: store i32 5, i32* [[ADDR]], align 4
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
|
|
store i32 5, i32* %addr, align 4
|
|
ret void
|
|
}
|
|
|
|
declare dso_local void @use(i32, i32, i32) nosync norecurse nounwind
|
|
|
|
;.
|
|
; TUNIT: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" }
|
|
; TUNIT: attributes #[[ATTR1]] = { norecurse nosync nounwind }
|
|
; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(write) }
|
|
; TUNIT: attributes #[[ATTR3]] = { nosync nounwind }
|
|
; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn }
|
|
; TUNIT: attributes #[[ATTR5]] = { nounwind }
|
|
;.
|
|
; CGSCC: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" }
|
|
; CGSCC: attributes #[[ATTR1]] = { norecurse nosync nounwind }
|
|
; CGSCC: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn memory(write) }
|
|
; CGSCC: attributes #[[ATTR3]] = { nosync nounwind }
|
|
; CGSCC: attributes #[[ATTR4]] = { nounwind }
|
|
; CGSCC: attributes #[[ATTR5]] = { nounwind willreturn }
|
|
;.
|