AANonNull is now the first AA that is always queried via the new APIs and not created manually. Others will follow shortly to avoid trivial AAs whenever possible. This commit introduced some helper logic that will make it simpler to port the next one. It also untangles AADereferenceable and AANonNull such that the former does not keep a handle on the latter. Finally, we stop deducing `nonnull` for `undef`, which was incorrect.
720 lines
41 KiB
LLVM
720 lines
41 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
|
|
; RUN: opt -S -passes='attributor,cgscc(openmp-opt-cgscc)' < %s | FileCheck %s
|
|
;
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
%struct.ident_t = type { i32, i32, i32, i32, ptr }
|
|
|
|
@.str = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
|
|
@0 = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0, i32 0, ptr @.str }, align 8
|
|
@1 = private unnamed_addr global %struct.ident_t { i32 0, i32 322, i32 0, i32 0, ptr @.str }, align 8
|
|
@.gomp_critical_user_.reduction.var = common global [8 x i32] zeroinitializer
|
|
@2 = private unnamed_addr global %struct.ident_t { i32 0, i32 18, i32 0, i32 0, ptr @.str }, align 8
|
|
|
|
; void delete_parallel_0(void) {
|
|
; #pragma omp parallel
|
|
; { unknown_willreturn(); }
|
|
; #pragma omp parallel
|
|
; { readonly_willreturn(); }
|
|
; #pragma omp parallel
|
|
; { readnone_willreturn(); }
|
|
; #pragma omp parallel
|
|
; {}
|
|
; }
|
|
;
|
|
; We delete all but the first of the parallel regions in this test.
|
|
define void @delete_parallel_0() {
|
|
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0() {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, ptr noundef nonnull @.omp_outlined.willreturn)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_0() {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, ptr noundef @.omp_outlined.willreturn)
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@delete_parallel_0() {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, ptr noundef @.omp_outlined.willreturn)
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.willreturn)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.willreturn.0)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.willreturn.1)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.willreturn.2)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined.willreturn(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @unknown() #[[ATTR14:[0-9]+]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: call void @unknown() #[[ATTR0]]
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: call void @unknown() #[[ATTR0]]
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
call void @unknown() willreturn
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined.willreturn.0(ptr noalias %.global_tid., ptr noalias %.bound_tid.) willreturn {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @readonly() #[[ATTR4:[0-9]+]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: call void @readonly() #[[ATTR4:[0-9]+]]
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: call void @readonly() #[[ATTR4:[0-9]+]]
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
call void @readonly()
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined.willreturn.1(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @readnone() #[[ATTR14]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: call void @readnone() #[[ATTR0]]
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: call void @readnone() #[[ATTR0]]
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
call void @readnone() willreturn
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined.willreturn.2(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; void delete_parallel_1(void) {
|
|
; #pragma omp parallel
|
|
; { unknown(); }
|
|
; #pragma omp parallel
|
|
; { readonly(); }
|
|
; #pragma omp parallel
|
|
; { readnone(); }
|
|
; #pragma omp parallel
|
|
; {}
|
|
; }
|
|
;
|
|
; We delete only the last parallel regions in this test because the others might not return.
|
|
define void @delete_parallel_1() {
|
|
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1() {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef nonnull @.omp_outlined.)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef nonnull @.omp_outlined..0)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef nonnull @.omp_outlined..1)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_1() {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined.)
|
|
; CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined..0)
|
|
; CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined..1)
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@delete_parallel_1() {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined.)
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined..0)
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined..1)
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined..0)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined..1)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined..2)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined.(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @unknown()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: call void @unknown()
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: call void @unknown()
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
call void @unknown()
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..0(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..0
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @readonly() #[[ATTR4]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..0
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: call void @readonly() #[[ATTR4]]
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..0
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: call void @readonly() #[[ATTR4]]
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
call void @readonly()
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..1(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: call void @readnone()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: call void @readnone()
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: call void @readnone()
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
call void @readnone()
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..2(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..2
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..2
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
; void delete_parallel_2(void) {
|
|
; int a = 0;
|
|
; #pragma omp parallel
|
|
; {
|
|
; if (omp_get_thread_num() == 0)
|
|
; ++a;
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; #pragma omp master
|
|
; ++a;
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; #pragma omp single
|
|
; ++a;
|
|
; }
|
|
; #pragma omp parallel reduction(+: a)
|
|
; {
|
|
; ++a;
|
|
; }
|
|
; }
|
|
;
|
|
; FIXME: We do not realize that `a` is dead and all accesses to it can be removed
|
|
; making the parallel regions readonly and deletable.
|
|
define void @delete_parallel_2() {
|
|
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR15:[0-9]+]]
|
|
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..3, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..5, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..6, ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_2() {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR0]]
|
|
; CHECK1-NEXT: store i32 0, ptr [[A]], align 4
|
|
; CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..3, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..5, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..6, ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A]])
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@delete_parallel_2() {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR0]]
|
|
; CHECK2-NEXT: store i32 0, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..3, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..5, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..6, ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
|
|
; CHECK2-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A]])
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
%a = alloca i32, align 4
|
|
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %a)
|
|
store i32 0, ptr %a, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 1, ptr @.omp_outlined..3, ptr nonnull %a)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 1, ptr @.omp_outlined..4, ptr nonnull %a)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 1, ptr @.omp_outlined..5, ptr nonnull %a)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 1, ptr @.omp_outlined..6, ptr nonnull %a)
|
|
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %a)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..3(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR16:[0-9]+]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1
|
|
; CHECK-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..3
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR14:[0-9]+]]
|
|
; CHECK1-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
|
; CHECK1-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK1: if.then:
|
|
; CHECK1-NEXT: [[TMP:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1
|
|
; CHECK1-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
|
; CHECK1-NEXT: br label [[IF_END]]
|
|
; CHECK1: if.end:
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..3
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR14:[0-9]+]]
|
|
; CHECK2-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
|
; CHECK2-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
; CHECK2: if.then:
|
|
; CHECK2-NEXT: [[TMP:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1
|
|
; CHECK2-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
|
; CHECK2-NEXT: br label [[IF_END]]
|
|
; CHECK2: if.end:
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
%call = call i32 @omp_get_thread_num()
|
|
%cmp = icmp eq i32 %call, 0
|
|
br i1 %cmp, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %entry
|
|
%tmp = load i32, ptr %a, align 4
|
|
%inc = add nsw i32 %tmp, 1
|
|
store i32 %inc, ptr %a, align 4
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %if.then, %entry
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..4(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4
|
|
; CHECK-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
|
|
; CHECK: omp_if.then:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK-NEXT: br label [[OMP_IF_END]]
|
|
; CHECK: omp_if.end:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..4
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK1-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
|
; CHECK1-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
|
|
; CHECK1: omp_if.then:
|
|
; CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK1-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
|
; CHECK1-NEXT: call void @__kmpc_end_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK1-NEXT: br label [[OMP_IF_END]]
|
|
; CHECK1: omp_if.end:
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..4
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
|
|
; CHECK2: omp_if.then:
|
|
; CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK2-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @__kmpc_end_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK2-NEXT: br label [[OMP_IF_END]]
|
|
; CHECK2: omp_if.end:
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
%tmp = load i32, ptr %.global_tid., align 4
|
|
%tmp1 = call i32 @__kmpc_master(ptr nonnull @0, i32 %tmp)
|
|
%tmp2 = icmp eq i32 %tmp1, 0
|
|
br i1 %tmp2, label %omp_if.end, label %omp_if.then
|
|
|
|
omp_if.then: ; preds = %entry
|
|
%tmp3 = load i32, ptr %a, align 4
|
|
%inc = add nsw i32 %tmp3, 1
|
|
store i32 %inc, ptr %a, align 4
|
|
call void @__kmpc_end_master(ptr nonnull @0, i32 %tmp)
|
|
br label %omp_if.end
|
|
|
|
omp_if.end: ; preds = %entry, %omp_if.then
|
|
ret void
|
|
}
|
|
|
|
declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
|
|
|
|
declare i32 @omp_get_thread_num() inaccessiblememonly nofree nosync nounwind readonly
|
|
|
|
declare i32 @__kmpc_master(ptr, i32)
|
|
|
|
declare void @__kmpc_end_master(ptr, i32)
|
|
|
|
define internal void @.omp_outlined..5(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR16]]
|
|
; CHECK-NEXT: [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
|
|
; CHECK: omp_if.then:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_end_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK-NEXT: br label [[OMP_IF_END]]
|
|
; CHECK: omp_if.end:
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..5
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR14]]
|
|
; CHECK1-NEXT: [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK1-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
|
; CHECK1-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
|
|
; CHECK1: omp_if.then:
|
|
; CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK1-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK1-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
|
; CHECK1-NEXT: call void @__kmpc_end_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK1-NEXT: br label [[OMP_IF_END]]
|
|
; CHECK1: omp_if.end:
|
|
; CHECK1-NEXT: call void @__kmpc_barrier(ptr noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..5
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR14]]
|
|
; CHECK2-NEXT: [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
|
|
; CHECK2: omp_if.then:
|
|
; CHECK2-NEXT: [[TMP3:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK2-NEXT: store i32 [[INC]], ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @__kmpc_end_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
|
|
; CHECK2-NEXT: br label [[OMP_IF_END]]
|
|
; CHECK2: omp_if.end:
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
%omp_global_thread_num = call i32 @__kmpc_global_thread_num(ptr nonnull @0)
|
|
%tmp = load i32, ptr %.global_tid., align 4
|
|
%tmp1 = call i32 @__kmpc_single(ptr nonnull @0, i32 %tmp)
|
|
%tmp2 = icmp eq i32 %tmp1, 0
|
|
br i1 %tmp2, label %omp_if.end, label %omp_if.then
|
|
|
|
omp_if.then: ; preds = %entry
|
|
%tmp3 = load i32, ptr %a, align 4
|
|
%inc = add nsw i32 %tmp3, 1
|
|
store i32 %inc, ptr %a, align 4
|
|
call void @__kmpc_end_single(ptr nonnull @0, i32 %tmp)
|
|
br label %omp_if.end
|
|
|
|
omp_if.end: ; preds = %entry, %omp_if.then
|
|
call void @__kmpc_barrier(ptr nonnull @1, i32 %omp_global_thread_num) #6
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..6(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
|
|
; CHECK-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A1:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 [[A1]]) #[[ATTR17:[0-9]+]]
|
|
; CHECK-NEXT: store i32 1, ptr [[A1]], align 4
|
|
; CHECK-NEXT: store ptr [[A1]], ptr [[DOTOMP_REDUCTION_RED_LIST]], align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(ptr noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, ptr noundef nonnull align 8 [[DOTOMP_REDUCTION_RED_LIST]], ptr noundef nonnull @.omp.reduction.reduction_func, ptr noundef nonnull @.gomp_critical_user_.reduction.var)
|
|
; CHECK-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
|
|
; CHECK-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
|
|
; CHECK-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
|
|
; CHECK-NEXT: ]
|
|
; CHECK: .omp.reduction.case1:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[A1]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_end_reduce_nowait(ptr noundef nonnull @[[GLOB2]], i32 [[TMP2]], ptr noundef nonnull @.gomp_critical_user_.reduction.var)
|
|
; CHECK-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
|
|
; CHECK: .omp.reduction.case2:
|
|
; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[A1]], align 4
|
|
; CHECK-NEXT: [[TMP8:%.*]] = atomicrmw add ptr [[A]], i32 [[TMP7]] monotonic, align 4
|
|
; CHECK-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
|
|
; CHECK: .omp.reduction.default:
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A1]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..6
|
|
; CHECK1-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: [[A1:%.*]] = alloca i32, align 4
|
|
; CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
|
|
; CHECK1-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 [[A1]]) #[[ATTR0]]
|
|
; CHECK1-NEXT: store i32 1, ptr [[A1]], align 4
|
|
; CHECK1-NEXT: store ptr [[A1]], ptr [[DOTOMP_REDUCTION_RED_LIST]], align 8
|
|
; CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK1-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(ptr noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, ptr noundef nonnull align 8 [[DOTOMP_REDUCTION_RED_LIST]], ptr noundef nonnull @.omp.reduction.reduction_func, ptr noundef nonnull @.gomp_critical_user_.reduction.var)
|
|
; CHECK1-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
|
|
; CHECK1-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
|
|
; CHECK1-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
|
|
; CHECK1-NEXT: ]
|
|
; CHECK1: .omp.reduction.case1:
|
|
; CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[A1]], align 4
|
|
; CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
|
|
; CHECK1-NEXT: store i32 [[ADD]], ptr [[A]], align 4
|
|
; CHECK1-NEXT: call void @__kmpc_end_reduce_nowait(ptr noundef nonnull @[[GLOB2]], i32 [[TMP2]], ptr noundef nonnull @.gomp_critical_user_.reduction.var)
|
|
; CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
|
|
; CHECK1: .omp.reduction.case2:
|
|
; CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[A1]], align 4
|
|
; CHECK1-NEXT: [[TMP8:%.*]] = atomicrmw add ptr [[A]], i32 [[TMP7]] monotonic, align 4
|
|
; CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
|
|
; CHECK1: .omp.reduction.default:
|
|
; CHECK1-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A1]])
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..6
|
|
; CHECK2-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[A1:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
|
|
; CHECK2-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 [[A1]]) #[[ATTR0]]
|
|
; CHECK2-NEXT: store i32 1, ptr [[A1]], align 4
|
|
; CHECK2-NEXT: store ptr [[A1]], ptr [[DOTOMP_REDUCTION_RED_LIST]], align 8
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK2-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(ptr noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, ptr noundef nonnull align 8 [[DOTOMP_REDUCTION_RED_LIST]], ptr noundef nonnull @.omp.reduction.reduction_func, ptr noundef nonnull @.gomp_critical_user_.reduction.var)
|
|
; CHECK2-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
|
|
; CHECK2-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
|
|
; CHECK2-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
|
|
; CHECK2-NEXT: ]
|
|
; CHECK2: .omp.reduction.case1:
|
|
; CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[A1]], align 4
|
|
; CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
|
|
; CHECK2-NEXT: store i32 [[ADD]], ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @__kmpc_end_reduce_nowait(ptr noundef nonnull @[[GLOB2]], i32 [[TMP2]], ptr noundef nonnull @.gomp_critical_user_.reduction.var)
|
|
; CHECK2-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
|
|
; CHECK2: .omp.reduction.case2:
|
|
; CHECK2-NEXT: [[TMP7:%.*]] = load i32, ptr [[A1]], align 4
|
|
; CHECK2-NEXT: [[TMP8:%.*]] = atomicrmw add ptr [[A]], i32 [[TMP7]] monotonic, align 4
|
|
; CHECK2-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
|
|
; CHECK2: .omp.reduction.default:
|
|
; CHECK2-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A1]])
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
%a1 = alloca i32, align 4
|
|
%.omp.reduction.red_list = alloca [1 x ptr], align 8
|
|
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %a1)
|
|
store i32 1, ptr %a1, align 4
|
|
store ptr %a1, ptr %.omp.reduction.red_list, align 8
|
|
%tmp2 = load i32, ptr %.global_tid., align 4
|
|
%tmp4 = call i32 @__kmpc_reduce_nowait(ptr nonnull @2, i32 %tmp2, i32 1, i64 8, ptr nonnull %.omp.reduction.red_list, ptr nonnull @.omp.reduction.reduction_func, ptr nonnull @.gomp_critical_user_.reduction.var)
|
|
switch i32 %tmp4, label %.omp.reduction.default [
|
|
i32 1, label %.omp.reduction.case1
|
|
i32 2, label %.omp.reduction.case2
|
|
]
|
|
|
|
.omp.reduction.case1: ; preds = %entry
|
|
%tmp5 = load i32, ptr %a, align 4
|
|
%tmp6 = load i32, ptr %a1, align 4
|
|
%add = add nsw i32 %tmp5, %tmp6
|
|
store i32 %add, ptr %a, align 4
|
|
call void @__kmpc_end_reduce_nowait(ptr nonnull @2, i32 %tmp2, ptr nonnull @.gomp_critical_user_.reduction.var)
|
|
br label %.omp.reduction.default
|
|
|
|
.omp.reduction.case2: ; preds = %entry
|
|
%tmp7 = load i32, ptr %a1, align 4
|
|
%tmp8 = atomicrmw add ptr %a, i32 %tmp7 monotonic
|
|
br label %.omp.reduction.default
|
|
|
|
.omp.reduction.default: ; preds = %.omp.reduction.case2, %.omp.reduction.case1, %entry
|
|
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %a1)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp.reduction.reduction_func(ptr %arg, ptr %arg1) {
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
|
|
; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARG1]], align 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARG]], align 8
|
|
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP2]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[TMP4]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
; CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
|
|
; CHECK1-SAME: (ptr nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], ptr nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] {
|
|
; CHECK1-NEXT: entry:
|
|
; CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARG1]], align 8
|
|
; CHECK1-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARG]], align 8
|
|
; CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
|
|
; CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP2]], align 4
|
|
; CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
|
|
; CHECK1-NEXT: store i32 [[ADD]], ptr [[TMP4]], align 4
|
|
; CHECK1-NEXT: ret void
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
|
|
; CHECK2-SAME: (ptr nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], ptr nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARG1]], align 8
|
|
; CHECK2-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARG]], align 8
|
|
; CHECK2-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
|
|
; CHECK2-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP2]], align 4
|
|
; CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
|
|
; CHECK2-NEXT: store i32 [[ADD]], ptr [[TMP4]], align 4
|
|
; CHECK2-NEXT: ret void
|
|
entry:
|
|
%tmp2 = load ptr, ptr %arg1, align 8
|
|
%tmp4 = load ptr, ptr %arg, align 8
|
|
%tmp5 = load i32, ptr %tmp4, align 4
|
|
%tmp6 = load i32, ptr %tmp2, align 4
|
|
%add = add nsw i32 %tmp5, %tmp6
|
|
store i32 %add, ptr %tmp4, align 4
|
|
ret void
|
|
}
|
|
|
|
declare i32 @__kmpc_single(ptr, i32)
|
|
|
|
declare void @__kmpc_end_single(ptr, i32)
|
|
|
|
declare void @__kmpc_barrier(ptr, i32)
|
|
|
|
declare i32 @__kmpc_global_thread_num(ptr) nofree nosync nounwind readonly
|
|
|
|
declare i32 @__kmpc_reduce_nowait(ptr, i32, i32, i64, ptr, ptr, ptr)
|
|
|
|
declare void @__kmpc_end_reduce_nowait(ptr, i32, ptr)
|
|
|
|
declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
|
|
|
|
declare !callback !2 void @__kmpc_fork_call(ptr, i32, ptr, ...)
|
|
|
|
declare void @unknown()
|
|
|
|
declare void @readonly() readonly
|
|
|
|
declare void @readnone() readnone
|
|
|
|
!llvm.module.flags = !{!8}
|
|
|
|
!0 = !{i32 1, !"wchar_size", i32 4}
|
|
!1 = !{!"clang"}
|
|
!2 = !{!3}
|
|
!3 = !{i64 2, i64 -1, i64 -1, i1 true}
|
|
!4 = !{!5, !5, i64 0}
|
|
!5 = !{!"int", !6, i64 0}
|
|
!6 = !{!"omnipotent char", !7, i64 0}
|
|
!7 = !{!"Simple C/C++ TBAA"}
|
|
!8 = !{i32 7, !"openmp", i32 50}
|