This patch adds initial support for the `AAAddressSpace` abstract attributor interface to deduce and query address space information for a pointer. We simply query the underlying objects that a pointer can point to and find a common address space if they exist. This is the minimal support for the interface, we currently manifest changes on loads and stores. Additionally we should use the target transform information to deduce if an address space transformation is a no-op for the target machine when calculating compatibility. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D120586
376 lines
16 KiB
LLVM
376 lines
16 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-annotate-decl-cs -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"
|
|
|
|
%struct.ident_t = type { i32, i32, i32, i32, ptr }
|
|
@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]]) #[[ATTR1:[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]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: call void @level2Kernelall_early() #[[ATTR3:[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() #[[ATTR4:[0-9]+]]
|
|
; TUNIT-NEXT: br label [[IF_END:%.*]]
|
|
; TUNIT: if.else:
|
|
; TUNIT-NEXT: call void @level2Kernelb() #[[ATTR4]]
|
|
; TUNIT-NEXT: br label [[IF_END]]
|
|
; TUNIT: if.end:
|
|
; TUNIT-NEXT: call void @level2Kernelall_late() #[[ATTR5:[0-9]+]]
|
|
; 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() #[[ATTR6:[0-9]+]]
|
|
; 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: mustprogress 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, ptr @ReachableKernelAS0, align 4
|
|
; CHECK-NEXT: store i32 1, ptr addrspace(3) @ReachableKernel, align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i32 1, ptr @ReachableKernelAS0, align 4
|
|
store i32 1, ptr addrspacecast (ptr addrspace(3) @ReachableKernel to ptr), 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, ptr addrspace(3) @ReachableKernel, align 4
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr @ReachableKernelAS0, align 4
|
|
; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(3) @UnreachableKernel, align 4
|
|
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR6:[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, ptr addrspace(3) @ReachableKernel, align 4
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr @ReachableKernelAS0, align 4
|
|
; CGSCC-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(3) @UnreachableKernel, 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, ptr addrspacecast (ptr addrspace(3) @ReachableKernel to ptr), align 4
|
|
%1 = load i32, ptr @ReachableKernelAS0, align 4
|
|
%2 = load i32, ptr addrspacecast (ptr addrspace(3) @UnreachableKernel to ptr), 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, ptr addrspace(3) @ReachableKernel, align 4
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr @ReachableKernelAS0, align 4
|
|
; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(3) @UnreachableKernel, align 4
|
|
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR6]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2Kernelb
|
|
; CGSCC-SAME: () #[[ATTR3]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableKernel, align 4
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr @ReachableKernelAS0, align 4
|
|
; CGSCC-NEXT: [[TMP2:%.*]] = load i32, ptr addrspace(3) @UnreachableKernel, 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, ptr addrspacecast (ptr addrspace(3) @ReachableKernel to ptr), align 4
|
|
%1 = load i32, ptr @ReachableKernelAS0, align 4
|
|
%2 = load i32, ptr addrspacecast (ptr addrspace(3) @UnreachableKernel to ptr), align 4
|
|
call void @use(i32 %0, i32 %1, i32 %2)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2Kernelall_late() {
|
|
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
|
|
; CHECK-LABEL: define {{[^@]+}}@level2Kernelall_late
|
|
; CHECK-SAME: () #[[ATTR2]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store i32 1, ptr addrspace(3) @UnreachableKernel, align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i32 1, ptr addrspacecast (ptr addrspace(3) @UnreachableKernel to ptr), 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]]) #[[ATTR1]]
|
|
; 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(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR3]]
|
|
; 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() #[[ATTR4]]
|
|
; TUNIT-NEXT: br label [[IF_END:%.*]]
|
|
; TUNIT: if.else:
|
|
; TUNIT-NEXT: call void @level2b() #[[ATTR4]]
|
|
; TUNIT-NEXT: br label [[IF_END]]
|
|
; TUNIT: if.end:
|
|
; TUNIT-NEXT: call void @level2all_late(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR5]]
|
|
; 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(ptr 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(ptr 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(ptr 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(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR6]]
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
%local = alloca i32
|
|
call void @level2all_early(ptr %local)
|
|
%tobool = icmp ne i32 %C, 0
|
|
br i1 %tobool, label %if.then, label %if.else
|
|
|
|
if.then: ; preds = %entry
|
|
call void @level2a(ptr %local)
|
|
br label %if.end
|
|
|
|
if.else: ; preds = %entry
|
|
call void @level2b(ptr %local)
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %if.else, %if.then
|
|
call void @level2all_late(ptr %local)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2all_early(ptr %addr) {
|
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2all_early
|
|
; TUNIT-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: store i32 1, ptr addrspace(3) @ReachableNonKernel, align 4
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2all_early
|
|
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: store i32 1, ptr addrspace(3) @ReachableNonKernel, align 4
|
|
; CGSCC-NEXT: store i32 17, ptr [[ADDR]], align 4
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i32 1, ptr addrspacecast (ptr addrspace(3) @ReachableNonKernel to ptr), align 4
|
|
store i32 17, ptr %addr, align 4
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2a(ptr %addr) {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2a
|
|
; TUNIT-SAME: () #[[ATTR1]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableNonKernel, align 4
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(3) @UnreachableNonKernel, align 4
|
|
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR6]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2a
|
|
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR3]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableNonKernel, align 4
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(3) @UnreachableNonKernel, align 4
|
|
; CGSCC-NEXT: [[QQQQ2:%.*]] = load i32, ptr [[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, ptr addrspacecast (ptr addrspace(3) @ReachableNonKernel to ptr), align 4
|
|
%1 = load i32, ptr addrspacecast (ptr addrspace(3) @UnreachableNonKernel to ptr), align 4
|
|
%qqqq2 = load i32, ptr %addr
|
|
call void @use(i32 %0, i32 %1, i32 %qqqq2)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2b(ptr %addr) {
|
|
; TUNIT: Function Attrs: norecurse nosync nounwind
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2b
|
|
; TUNIT-SAME: () #[[ATTR1]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableNonKernel, align 4
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(3) @UnreachableNonKernel, align 4
|
|
; TUNIT-NEXT: call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR6]]
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: nosync nounwind
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2b
|
|
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR3]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableNonKernel, align 4
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr addrspace(3) @UnreachableNonKernel, align 4
|
|
; CGSCC-NEXT: [[TMP2:%.*]] = load i32, ptr [[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, ptr addrspacecast (ptr addrspace(3) @ReachableNonKernel to ptr), align 4
|
|
%1 = load i32, ptr addrspacecast (ptr addrspace(3) @UnreachableNonKernel to ptr), align 4
|
|
%2 = load i32, ptr %addr
|
|
call void @use(i32 %0, i32 %1, i32 %2)
|
|
ret void
|
|
}
|
|
|
|
define internal void @level2all_late(ptr %addr) {
|
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
|
|
; TUNIT-LABEL: define {{[^@]+}}@level2all_late
|
|
; TUNIT-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: store i32 1, ptr addrspace(3) @UnreachableNonKernel, align 4
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
|
|
; CGSCC-LABEL: define {{[^@]+}}@level2all_late
|
|
; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: store i32 1, ptr addrspace(3) @UnreachableNonKernel, align 4
|
|
; CGSCC-NEXT: store i32 5, ptr [[ADDR]], align 4
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i32 1, ptr addrspacecast (ptr addrspace(3) @UnreachableNonKernel to ptr), align 4
|
|
store i32 5, ptr %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]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
|
|
; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(write) }
|
|
; TUNIT: attributes #[[ATTR4]] = { nosync nounwind }
|
|
; TUNIT: attributes #[[ATTR5]] = { nosync nounwind memory(write) }
|
|
; TUNIT: attributes #[[ATTR6]] = { nounwind }
|
|
;.
|
|
; CGSCC: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" }
|
|
; CGSCC: attributes #[[ATTR1]] = { norecurse nosync nounwind }
|
|
; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
|
|
; CGSCC: attributes #[[ATTR3]] = { nosync nounwind }
|
|
; CGSCC: attributes #[[ATTR4]] = { nounwind }
|
|
; CGSCC: attributes #[[ATTR5]] = { nofree nounwind willreturn memory(write) }
|
|
; CGSCC: attributes #[[ATTR6]] = { nounwind memory(write) }
|
|
;.
|