Files
clang-p2996/llvm/test/Transforms/Attributor/value-simplify-gpu.ll
Johannes Doerfert a265cf22af [Attributor] Introduce the AA::isPotentiallyReachable helper APIs
To make usage easier (compared to the many reachability related AAs),
this patch introduces a helper API, `AA::isPotentiallyReachable`, which
performs all the necessary steps. It also does the "backwards"
reachability (see D106720) as that simplifies the AA a lot (backwards
queries were somewhat different from the other query resolvers), and
ensures we use cached values in every stage.

To test inter-procedural reachability in a reasonable way this patch
includes an extension to `AAPointerInfo::forallInterferingWrites`.
Basically, we can exclude writes if they cannot reach a load "during the
lifetime" of the allocation. That is, we need to go up the call graph to
determine reachability until we can determine the allocation would be
dead in the caller. This leads to new constant propagations (through
memory) in `value-simplify-pointer-info-gpu.ll`.

Note: The new code contains plenty debug output to determine how
reachability queries are resolved.

Parts extracted from D110078.

Differential Revision: https://reviews.llvm.org/D118673
2022-02-01 01:40:45 -06:00

429 lines
22 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
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" {
; IS__TUNIT____: Function Attrs: norecurse nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@kernel
; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: call void @level1Kernel(i32 [[C]]) #[[ATTR3:[0-9]+]]
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: norecurse nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@kernel
; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: call void @level1Kernel(i32 [[C]]) #[[ATTR4:[0-9]+]]
; IS__CGSCC____-NEXT: ret void
;
entry:
call void @level1Kernel(i32 %C)
ret void
}
define internal void @level1Kernel(i32 %C) {
; IS__TUNIT____: Function Attrs: norecurse nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@level1Kernel
; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: call void @level2Kernelall_early() #[[ATTR4:[0-9]+]]
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; IS__TUNIT____: if.then:
; IS__TUNIT____-NEXT: call void @level2Kernela() #[[ATTR3]]
; IS__TUNIT____-NEXT: br label [[IF_END:%.*]]
; IS__TUNIT____: if.else:
; IS__TUNIT____-NEXT: call void @level2Kernelb() #[[ATTR3]]
; IS__TUNIT____-NEXT: br label [[IF_END]]
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: call void @level2Kernelall_late() #[[ATTR5:[0-9]+]]
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: norecurse nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@level1Kernel
; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: call void @level2Kernelall_early() #[[ATTR5:[0-9]+]]
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; IS__CGSCC____: if.then:
; IS__CGSCC____-NEXT: call void @level2Kernela() #[[ATTR4]]
; IS__CGSCC____-NEXT: br label [[IF_END:%.*]]
; IS__CGSCC____: if.else:
; IS__CGSCC____-NEXT: call void @level2Kernelb() #[[ATTR4]]
; IS__CGSCC____-NEXT: br label [[IF_END]]
; IS__CGSCC____: if.end:
; IS__CGSCC____-NEXT: call void @level2Kernelall_late() #[[ATTR6:[0-9]+]]
; IS__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 writeonly
; 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() {
; IS__TUNIT____: Function Attrs: norecurse nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@level2Kernela
; IS__TUNIT____-SAME: () #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
; IS__TUNIT____-NEXT: call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 noundef 42) #[[ATTR6:[0-9]+]]
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: norecurse nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@level2Kernela
; IS__CGSCC____-SAME: () #[[ATTR1]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
; IS__CGSCC____-NEXT: call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 noundef 42) #[[ATTR4]]
; IS__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() {
; IS__TUNIT____: Function Attrs: norecurse nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@level2Kernelb
; IS__TUNIT____-SAME: () #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
; IS__TUNIT____-NEXT: call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 noundef 42) #[[ATTR6]]
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: norecurse nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@level2Kernelb
; IS__CGSCC____-SAME: () #[[ATTR1]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableKernel to i32*), align 4
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* @ReachableKernelAS0, align 4
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableKernel to i32*), align 4
; IS__CGSCC____-NEXT: call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 noundef 42) #[[ATTR4]]
; IS__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() {
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@level2Kernelall_late
; IS__TUNIT____-SAME: () #[[ATTR2]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@level2Kernelall_late
; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] {
; IS__CGSCC____-NEXT: entry:
; IS__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 {
; IS__TUNIT____: Function Attrs: norecurse nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@non_kernel
; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: call void @level1(i32 [[C]]) #[[ATTR3]]
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: norecurse nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@non_kernel
; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: call void @level1(i32 [[C]]) #[[ATTR4]]
; IS__CGSCC____-NEXT: ret void
;
entry:
call void @level1(i32 %C)
ret void
}
define internal void @level1(i32 %C) {
; IS__TUNIT____: Function Attrs: norecurse nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@level1
; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[LOCAL:%.*]] = alloca i32, align 4
; IS__TUNIT____-NEXT: call void @level2all_early(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR4]]
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; IS__TUNIT____: if.then:
; IS__TUNIT____-NEXT: call void @level2a() #[[ATTR3]]
; IS__TUNIT____-NEXT: br label [[IF_END:%.*]]
; IS__TUNIT____: if.else:
; IS__TUNIT____-NEXT: call void @level2b() #[[ATTR3]]
; IS__TUNIT____-NEXT: br label [[IF_END]]
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: call void @level2all_late(i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[LOCAL]]) #[[ATTR5]]
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC_OPM: Function Attrs: norecurse nosync nounwind
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@level1
; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[LOCAL:%.*]] = alloca i32, align 4
; IS__CGSCC_OPM-NEXT: call void @level2all_early(i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef) #[[ATTR5]]
; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; IS__CGSCC_OPM: if.then:
; IS__CGSCC_OPM-NEXT: call void @level2a(i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef) #[[ATTR4]]
; IS__CGSCC_OPM-NEXT: br label [[IF_END:%.*]]
; IS__CGSCC_OPM: if.else:
; IS__CGSCC_OPM-NEXT: call void @level2b(i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef) #[[ATTR4]]
; IS__CGSCC_OPM-NEXT: br label [[IF_END]]
; IS__CGSCC_OPM: if.end:
; IS__CGSCC_OPM-NEXT: call void @level2all_late(i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef) #[[ATTR7:[0-9]+]]
; IS__CGSCC_OPM-NEXT: ret void
;
; IS__CGSCC_NPM: Function Attrs: norecurse nosync nounwind
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@level1
; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[LOCAL:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: call void @level2all_early(i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef) #[[ATTR5]]
; IS__CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; IS__CGSCC_NPM: if.then:
; IS__CGSCC_NPM-NEXT: call void @level2a(i32 undef) #[[ATTR4]]
; IS__CGSCC_NPM-NEXT: br label [[IF_END:%.*]]
; IS__CGSCC_NPM: if.else:
; IS__CGSCC_NPM-NEXT: call void @level2b(i32 undef) #[[ATTR7:[0-9]+]]
; IS__CGSCC_NPM-NEXT: br label [[IF_END]]
; IS__CGSCC_NPM: if.end:
; IS__CGSCC_NPM-NEXT: call void @level2all_late(i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) undef) #[[ATTR8:[0-9]+]]
; IS__CGSCC_NPM-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) {
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@level2all_early
; IS__TUNIT____-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@level2all_early
; IS__CGSCC____-SAME: (i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; IS__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) {
; IS__TUNIT____: Function Attrs: norecurse nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@level2a
; IS__TUNIT____-SAME: () #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; IS__TUNIT____-NEXT: call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 17) #[[ATTR6]]
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC_OPM: Function Attrs: norecurse nosync nounwind
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@level2a
; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR1]] {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* undef, align 4
; IS__CGSCC_OPM-NEXT: call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 17) #[[ATTR4]]
; IS__CGSCC_OPM-NEXT: ret void
;
; IS__CGSCC_NPM: Function Attrs: norecurse nosync nounwind
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@level2a
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[ADDR_PRIV:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[ADDR_PRIV]], align 4
; IS__CGSCC_NPM-NEXT: call void @use(i32 [[TMP1]], i32 [[TMP2]], i32 17) #[[ATTR4]]
; IS__CGSCC_NPM-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 @level2b(i32* %addr) {
; IS__TUNIT____: Function Attrs: norecurse nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@level2b
; IS__TUNIT____-SAME: () #[[ATTR1]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; IS__TUNIT____-NEXT: call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 17) #[[ATTR6]]
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC_OPM: Function Attrs: norecurse nosync nounwind
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@level2b
; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR1]] {
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* undef, align 4
; IS__CGSCC_OPM-NEXT: call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 17) #[[ATTR4]]
; IS__CGSCC_OPM-NEXT: ret void
;
; IS__CGSCC_NPM: Function Attrs: norecurse nosync nounwind
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@level2b
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] {
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[ADDR_PRIV:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[ADDR_PRIV]], align 4
; IS__CGSCC_NPM-NEXT: call void @use(i32 [[TMP1]], i32 [[TMP2]], i32 17) #[[ATTR4]]
; IS__CGSCC_NPM-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) {
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@level2all_late
; IS__TUNIT____-SAME: (i32* noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; IS__TUNIT____-NEXT: ret void
;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@level2all_late
; IS__CGSCC____-SAME: (i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: store i32 1, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
; IS__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
;.
; IS__TUNIT____: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" }
; IS__TUNIT____: attributes #[[ATTR1]] = { norecurse nosync nounwind }
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn writeonly }
; IS__TUNIT____: attributes #[[ATTR3]] = { nosync nounwind }
; IS__TUNIT____: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn writeonly }
; IS__TUNIT____: attributes #[[ATTR5]] = { nosync nounwind writeonly }
; IS__TUNIT____: attributes #[[ATTR6]] = { nounwind }
;.
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" }
; IS__CGSCC_OPM: attributes #[[ATTR1]] = { norecurse nosync nounwind }
; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn writeonly }
; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nounwind }
; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nounwind willreturn writeonly }
; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nounwind readnone }
; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind writeonly }
;.
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" }
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { norecurse nosync nounwind }
; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind willreturn writeonly }
; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readnone willreturn }
; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nounwind }
; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nounwind willreturn writeonly }
; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind readnone }
; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nosync nounwind }
; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nosync nounwind writeonly }
;.