A barrier will pause execution until all threads reach it. If some go to a different barrier then we deadlock. This manifests in that the finalization callback must only be run once. Fix by ensuring we always go through the same finalization block whether the thread in cancelled or not and no matter which cancellation point causes the cancellation. The old callback only affected PARALLEL, so it has been moved into the code generating PARALLEL. For this reason, we don't need similar changes for other cancellable constructs. We need to create the barrier on the shared exit from the outlined function instead of only on the cancelled branch to make sure that threads exiting normally (without cancellation) meet the same barriers as those which were cancelled. For example, previously we might have generated code like ``` ... %ret = call i32 @__kmpc_cancel(...) %cond = icmp eq i32 %ret, 0 br i1 %cond, label %continue, label %cancel continue: // do the rest of the callback, eventually branching to %fini br label %fini cancel: // Populated by the callback: // unsafe: if any thread makes it to the end without being cancelled // it won't reach this barrier and then the program will deadlock %unused = call i32 @__kmpc_cancel_barrier(...) br label %fini fini: // run destructors etc ret ``` In the new version the barrier is moved into fini. I generate it *after* the destructors because the standard describes the barrier as occurring after the end of the parallel region. ``` ... %ret = call i32 @__kmpc_cancel(...) %cond = icmp eq i32 %ret, 0 br i1 %cond, label %continue, label %cancel continue: // do the rest of the callback, eventually branching to %fini br label %fini cancel: br label %fini fini: // run destructors etc // safe so long as every exit from the function happens via this block: %unused = call i32 @__kmpc_cancel_barrier(...) ret ``` To achieve this, the barrier is now generated alongside the finalization code instead of in the callback. This is the reason for the changes to the unit test. I'm unsure if I should keep the incorrect barrier generation callback only on the cancellation branch in clang with the OMPIRBuilder backend because that would match clang's ordinary codegen. Right now I have opted to remove it entirely because it is a deadlock waiting to happen. --- This re-lands #164586 with a small fix for a failing buildbot running address sanitizer on clang lit tests. In the previous version of the patch I added an insertion point guard "just to be safe" and never removed it. There isn't insertion point guarding on the other route out of this function and we do not preserve the insertion point around getFiniBB either so it is not needed here. The problem flagged by the sanitizers was because the saved insertion point pointed to an instruction which was then removed inside the FiniCB for some clang codegen functions. The instruction was freed when it was removed. Then accessing it to restore the insertion point was a use after free bug.
5880 lines
360 KiB
LLVM
5880 lines
360 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
|
|
; RUN: opt -S -aa-pipeline= -passes='attributor,cgscc(openmp-opt-cgscc)' -openmp-opt-enable-merging < %s | FileCheck %s --check-prefix=CHECK2
|
|
; #include <omp.h>
|
|
; void foo();
|
|
; void use(int);
|
|
; void usef(float);
|
|
; void merge(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
; void unmergable_proc_bind(int a) {
|
|
; #pragma omp parallel proc_bind(close)
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
; void unmergable_num_threads(int a) {
|
|
; #pragma omp parallel num_threads(a)
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
; void unmergable_seq_call(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; foo();
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
; void merge_seq(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; a = a + 1;
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; use(a);
|
|
; }
|
|
; void merge_seq_float(float f, ptr p) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(f);
|
|
; }
|
|
; *p = f + 3.14f;
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(f);
|
|
; }
|
|
; }
|
|
; void merge_seq_firstprivate(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; a = a + 1;
|
|
; #pragma omp parallel firstprivate(a)
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; use(a);
|
|
; }
|
|
; void merge_seq_sink_lt(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; {
|
|
; int b = (int)&b;
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
; void merge_seq_par_use(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; int b = a + 1;
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; use(b);
|
|
; }
|
|
; }
|
|
; void merge_cancellable_regions(int cancel1, int cancel2)
|
|
; {
|
|
; #pragma omp parallel
|
|
; {
|
|
; if(cancel1) {
|
|
; #pragma omp cancel parallel
|
|
; }
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; if (cancel2) {
|
|
; #pragma omp cancel parallel
|
|
; }
|
|
; }
|
|
; }
|
|
; void merge_cancellable_regions_seq(int cancel1, int cancel2)
|
|
; {
|
|
; #pragma omp parallel
|
|
; {
|
|
; if(cancel1) {
|
|
; #pragma omp cancel parallel
|
|
; }
|
|
; }
|
|
; cancel2 = !cancel1;
|
|
; #pragma omp parallel
|
|
; {
|
|
; if (cancel2) {
|
|
; #pragma omp cancel parallel
|
|
; }
|
|
; }
|
|
; }
|
|
; void merge_3(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
; void merge_3_seq(int a, int b) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; b = a + 1;
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; b = b + a;
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; use(b);
|
|
; }
|
|
; void unmergable_3_seq_call(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; foo();
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; foo();
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
; void unmergable_3_proc_bind(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel proc_bind(close)
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
; void unmergable_3_num_threads(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel num_threads(a)
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
; void merge_2_unmergable_1(int a) {
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; foo();
|
|
; #pragma omp parallel
|
|
; {
|
|
; use(a);
|
|
; }
|
|
; }
|
|
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 }
|
|
|
|
@0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
|
|
@1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, ptr @0 }, align 8
|
|
|
|
define dso_local void @merge(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined., ptr nonnull %a.addr)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..1, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined.(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
declare dso_local void @use(i32) local_unnamed_addr
|
|
|
|
declare !callback !1 void @__kmpc_fork_call(ptr, i32, ptr, ...) local_unnamed_addr
|
|
|
|
define internal void @.omp_outlined..1(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @unmergable_proc_bind(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
%0 = call i32 @__kmpc_global_thread_num(ptr nonnull @1)
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void @__kmpc_push_proc_bind(ptr nonnull @1, i32 %0, i32 3)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..2, ptr nonnull %a.addr)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..3, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..2(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
declare i32 @__kmpc_global_thread_num(ptr) local_unnamed_addr
|
|
|
|
declare void @__kmpc_push_proc_bind(ptr, i32, i32) local_unnamed_addr
|
|
|
|
define internal void @.omp_outlined..3(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @unmergable_num_threads(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
%0 = call i32 @__kmpc_global_thread_num(ptr nonnull @1)
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void @__kmpc_push_num_threads(ptr nonnull @1, i32 %0, i32 %a)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..4, ptr nonnull %a.addr)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..5, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..4(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
declare void @__kmpc_push_num_threads(ptr, i32, i32) local_unnamed_addr
|
|
|
|
define internal void @.omp_outlined..5(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @unmergable_seq_call(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..6, ptr nonnull %a.addr)
|
|
call void (...) @foo()
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..7, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..6(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
declare dso_local void @foo(...) local_unnamed_addr
|
|
|
|
define internal void @.omp_outlined..7(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_seq(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..8, ptr nonnull %a.addr)
|
|
%0 = load i32, ptr %a.addr, align 4
|
|
%add = add nsw i32 %0, 1
|
|
store i32 %add, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..9, ptr nonnull %a.addr)
|
|
%1 = load i32, ptr %a.addr, align 4
|
|
call void @use(i32 %1)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..8(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..9(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_seq_float(float %f, ptr nocapture %p) local_unnamed_addr {
|
|
entry:
|
|
%f.addr = alloca float, align 4
|
|
store float %f, ptr %f.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..10, ptr nonnull %f.addr)
|
|
%0 = load float, ptr %f.addr, align 4
|
|
%add = fadd float %0, 0x40091EB860000000
|
|
store float %add, ptr %p, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..11, ptr nonnull %f.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..10(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %f) {
|
|
entry:
|
|
%0 = load float, ptr %f, align 4
|
|
%conv = fptosi float %0 to i32
|
|
call void @use(i32 %conv)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..11(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %f) {
|
|
entry:
|
|
%0 = load float, ptr %f, align 4
|
|
%conv = fptosi float %0 to i32
|
|
call void @use(i32 %conv)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_seq_firstprivate(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..12, ptr nonnull %a.addr)
|
|
%0 = load i32, ptr %a.addr, align 4
|
|
%add = add nsw i32 %0, 1
|
|
store i32 %add, ptr %a.addr, align 4
|
|
%a.casted.sroa.0.0.insert.ext = zext i32 %add to i64
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..13, i64 %a.casted.sroa.0.0.insert.ext)
|
|
%1 = load i32, ptr %a.addr, align 4
|
|
call void @use(i32 %1)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..12(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..13(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., i64 %a) {
|
|
entry:
|
|
%a.addr.sroa.0.0.extract.trunc = trunc i64 %a to i32
|
|
call void @use(i32 %a.addr.sroa.0.0.extract.trunc)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_seq_sink_lt(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
%b = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..14, ptr nonnull %a.addr)
|
|
call void @llvm.lifetime.start.p0(ptr nonnull %b)
|
|
%0 = ptrtoint ptr %b to i64
|
|
%1 = trunc i64 %0 to i32
|
|
store i32 %1, ptr %b, align 4
|
|
call void @llvm.lifetime.end.p0(ptr nonnull %b)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..15, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..14(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
declare void @llvm.lifetime.start.p0(ptr nocapture)
|
|
|
|
declare void @llvm.lifetime.end.p0(ptr nocapture)
|
|
|
|
define internal void @.omp_outlined..15(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_seq_par_use(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
%b = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..16, ptr nonnull %a.addr)
|
|
call void @llvm.lifetime.start.p0(ptr nonnull %b)
|
|
%0 = load i32, ptr %a.addr, align 4
|
|
%add = add nsw i32 %0, 1
|
|
store i32 %add, ptr %b, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 2, ptr @.omp_outlined..17, ptr nonnull %a.addr, ptr nonnull %b)
|
|
call void @llvm.lifetime.end.p0(ptr nonnull %b)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..16(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..17(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a, ptr nocapture nonnull readonly align 4 dereferenceable(4) %b) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
%1 = load i32, ptr %b, align 4
|
|
call void @use(i32 %1)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_cancellable_regions(i32 %cancel1, i32 %cancel2) local_unnamed_addr {
|
|
entry:
|
|
%cancel1.addr = alloca i32, align 4
|
|
%cancel2.addr = alloca i32, align 4
|
|
store i32 %cancel1, ptr %cancel1.addr, align 4
|
|
store i32 %cancel2, ptr %cancel2.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..18, ptr nonnull %cancel1.addr)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..19, ptr nonnull %cancel2.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..18(ptr noalias nocapture readonly %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %cancel1) {
|
|
entry:
|
|
%0 = load i32, ptr %cancel1, align 4
|
|
%tobool.not = icmp eq i32 %0, 0
|
|
br i1 %tobool.not, label %if.end, label %if.then
|
|
|
|
if.then: ; preds = %entry
|
|
%1 = load i32, ptr %.global_tid., align 4
|
|
%2 = call i32 @__kmpc_cancel(ptr nonnull @1, i32 %1, i32 1)
|
|
ret void
|
|
|
|
if.end: ; preds = %entry
|
|
ret void
|
|
}
|
|
|
|
declare i32 @__kmpc_cancel(ptr, i32, i32) local_unnamed_addr
|
|
|
|
define internal void @.omp_outlined..19(ptr noalias nocapture readonly %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %cancel2) {
|
|
entry:
|
|
%0 = load i32, ptr %cancel2, align 4
|
|
%tobool.not = icmp eq i32 %0, 0
|
|
br i1 %tobool.not, label %if.end, label %if.then
|
|
|
|
if.then: ; preds = %entry
|
|
%1 = load i32, ptr %.global_tid., align 4
|
|
%2 = call i32 @__kmpc_cancel(ptr nonnull @1, i32 %1, i32 1)
|
|
ret void
|
|
|
|
if.end: ; preds = %entry
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_cancellable_regions_seq(i32 %cancel1, i32 %cancel2) local_unnamed_addr {
|
|
entry:
|
|
%cancel1.addr = alloca i32, align 4
|
|
%cancel2.addr = alloca i32, align 4
|
|
store i32 %cancel1, ptr %cancel1.addr, align 4
|
|
store i32 %cancel2, ptr %cancel2.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..20, ptr nonnull %cancel1.addr)
|
|
%0 = load i32, ptr %cancel1.addr, align 4
|
|
%tobool.not = icmp eq i32 %0, 0
|
|
%lnot.ext = zext i1 %tobool.not to i32
|
|
store i32 %lnot.ext, ptr %cancel2.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..21, ptr nonnull %cancel2.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..20(ptr noalias nocapture readonly %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %cancel1) {
|
|
entry:
|
|
%0 = load i32, ptr %cancel1, align 4
|
|
%tobool.not = icmp eq i32 %0, 0
|
|
br i1 %tobool.not, label %if.end, label %if.then
|
|
|
|
if.then: ; preds = %entry
|
|
%1 = load i32, ptr %.global_tid., align 4
|
|
%2 = call i32 @__kmpc_cancel(ptr nonnull @1, i32 %1, i32 1)
|
|
ret void
|
|
|
|
if.end: ; preds = %entry
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..21(ptr noalias nocapture readonly %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %cancel2) {
|
|
entry:
|
|
%0 = load i32, ptr %cancel2, align 4
|
|
%tobool.not = icmp eq i32 %0, 0
|
|
br i1 %tobool.not, label %if.end, label %if.then
|
|
|
|
if.then: ; preds = %entry
|
|
%1 = load i32, ptr %.global_tid., align 4
|
|
%2 = call i32 @__kmpc_cancel(ptr nonnull @1, i32 %1, i32 1)
|
|
ret void
|
|
|
|
if.end: ; preds = %entry
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_3(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..22, ptr nonnull %a.addr)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..23, ptr nonnull %a.addr)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..24, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..22(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..23(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..24(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_3_seq(i32 %a, i32 %b) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..25, ptr nonnull %a.addr)
|
|
%0 = load i32, ptr %a.addr, align 4
|
|
%add = add nsw i32 %0, 1
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..26, ptr nonnull %a.addr)
|
|
%1 = load i32, ptr %a.addr, align 4
|
|
%add1 = add nsw i32 %add, %1
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..27, ptr nonnull %a.addr)
|
|
call void @use(i32 %add1)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..25(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..26(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..27(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @unmergable_3_seq_call(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..28, ptr nonnull %a.addr)
|
|
call void (...) @foo()
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..29, ptr nonnull %a.addr)
|
|
call void (...) @foo()
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..30, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..28(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..29(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..30(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @unmergable_3_proc_bind(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
%0 = call i32 @__kmpc_global_thread_num(ptr nonnull @1)
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..31, ptr nonnull %a.addr)
|
|
call void @__kmpc_push_proc_bind(ptr nonnull @1, i32 %0, i32 3)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..32, ptr nonnull %a.addr)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..33, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..31(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..32(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..33(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @unmergable_3_num_threads(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
%0 = call i32 @__kmpc_global_thread_num(ptr nonnull @1)
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..34, ptr nonnull %a.addr)
|
|
%1 = load i32, ptr %a.addr, align 4
|
|
call void @__kmpc_push_num_threads(ptr nonnull @1, i32 %0, i32 %1)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..35, ptr nonnull %a.addr)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..36, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..34(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..35(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..36(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @merge_2_unmergable_1(i32 %a) local_unnamed_addr {
|
|
entry:
|
|
%a.addr = alloca i32, align 4
|
|
store i32 %a, ptr %a.addr, align 4
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..37, ptr nonnull %a.addr)
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..38, ptr nonnull %a.addr)
|
|
call void (...) @foo()
|
|
call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @1, i32 1, ptr @.omp_outlined..39, ptr nonnull %a.addr)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..37(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..38(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
define internal void @.omp_outlined..39(ptr noalias nocapture readnone %.global_tid., ptr noalias nocapture readnone %.bound_tid., ptr nocapture nonnull readonly align 4 dereferenceable(4) %a) {
|
|
entry:
|
|
%0 = load i32, ptr %a, align 4
|
|
call void @use(i32 %0)
|
|
ret void
|
|
}
|
|
|
|
|
|
!llvm.module.flags = !{!0, !3}
|
|
|
|
!0 = !{i32 1, !"wchar_size", i32 4}
|
|
!1 = !{!2}
|
|
!2 = !{i64 2, i64 -1, i64 -1, i1 true}
|
|
!3 = !{i32 7, !"openmp", i32 50}
|
|
; CHECK-LABEL: define {{[^@]+}}@merge
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined.(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..1(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_proc_bind
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..2, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..3, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; 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 readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_num_threads
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[A]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..4, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..5, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_seq_call
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..6, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..7, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..7
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_seq..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..8(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..9(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..8
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..9
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_float
|
|
; CHECK-SAME: (float [[F:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4
|
|
; CHECK-NEXT: store float [[F]], ptr [[F_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_float..omp_par, ptr [[F_ADDR]], ptr [[P]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_float..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[F_ADDR:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..10(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..11(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[F_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP3]], 0x40091EB860000000
|
|
; CHECK-NEXT: store float [[ADD]], ptr [[P]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..10
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..11
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_firstprivate
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]] = alloca i64, align 8
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_firstprivate..omp_par, ptr [[A_ADDR]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_firstprivate..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..12(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD:%.*]] = load i64, ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK-NEXT: call void @.omp_outlined..13(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], i64 [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT:%.*]] = zext i32 [[ADD]] to i64
|
|
; CHECK-NEXT: store i64 [[A_CASTED_SROA_0_0_INSERT_EXT]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..12
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..13
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i64 [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[A_ADDR_SROA_0_0_EXTRACT_TRUNC]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_sink_lt
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_seq_sink_lt..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_sink_lt..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..14(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..15(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[B]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
|
|
; CHECK-NEXT: store i32 [[TMP5]], ptr [[B]], align 4
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..14
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..15
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_par_use
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[B]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_par_use..omp_par, ptr [[A_ADDR]], ptr [[B]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_par_use..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[B:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..16(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..17(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[B]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..16
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..17
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP1]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions
|
|
; CHECK-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_cancellable_regions..omp_par, ptr [[CANCEL1_ADDR]], ptr [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[CANCEL1_ADDR:%.*]], ptr [[CANCEL2_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..18(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..19(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..18
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..19
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq
|
|
; CHECK-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_cancellable_regions_seq..omp_par, ptr [[CANCEL1_ADDR]], ptr [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[CANCEL1_ADDR:%.*]], ptr [[CANCEL2_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..20(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..21(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: [[LNOT_EXT:%.*]] = zext i1 [[TOBOOL_NOT]] to i32
|
|
; CHECK-NEXT: store i32 [[LNOT_EXT]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..20
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..21
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_3..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..22(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..23(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: call void @.omp_outlined..24(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..22
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..23
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..24
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3_seq
|
|
; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD1_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[ADD_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM7:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 3, ptr @merge_3_seq..omp_par, ptr [[A_ADDR]], ptr [[ADD_SEQ_OUTPUT_ALLOC]], ptr [[ADD1_SEQ_OUTPUT_ALLOC]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[ADD1_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[ADD1_SEQ_OUTPUT_LOAD]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[ADD_SEQ_OUTPUT_ALLOC:%.*]], ptr [[ADD1_SEQ_OUTPUT_ALLOC:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..25(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..26(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM4:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM4]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[OMP_REGION_BODY5:%.*]], label [[OMP_REGION_END4:%.*]]
|
|
; CHECK: omp_region.end4:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM6:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM6]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..27(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body5:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED2:%.*]]
|
|
; CHECK: seq.par.merged2:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD_SEQ_OUTPUT_LOAD]], [[TMP5]]
|
|
; CHECK-NEXT: store i32 [[ADD1]], ptr [[ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY5_SPLIT:%.*]]
|
|
; CHECK: omp_region.body5.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END4]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP6]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..25
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..26
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..27
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_seq_call
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..28, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..29, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..30, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..28
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..29
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..30
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_proc_bind
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..31, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..32, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..33, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..31
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..32
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..33
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_num_threads
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..34, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[TMP1]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..35, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..36, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..34
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..35
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..36
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_2_unmergable_1
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_2_unmergable_1..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..39, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_2_unmergable_1..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..37(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..38(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..37
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..38
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..39
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined.(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..1(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_proc_bind
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..2, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..3, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; 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 readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_num_threads
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[A]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..4, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..5, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_seq_call
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..6, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..7, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..7
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_seq..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..8(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..9(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..8
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..9
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_float
|
|
; CHECK-SAME: (float [[F:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4
|
|
; CHECK-NEXT: store float [[F]], ptr [[F_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_float..omp_par, ptr [[F_ADDR]], ptr [[P]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_float..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[F_ADDR:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..10(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..11(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[F_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP3]], 0x40091EB860000000
|
|
; CHECK-NEXT: store float [[ADD]], ptr [[P]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..10
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..11
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_firstprivate
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]] = alloca i64, align 8
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_firstprivate..omp_par, ptr [[A_ADDR]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_firstprivate..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..12(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD:%.*]] = load i64, ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK-NEXT: call void @.omp_outlined..13(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], i64 [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT:%.*]] = zext i32 [[ADD]] to i64
|
|
; CHECK-NEXT: store i64 [[A_CASTED_SROA_0_0_INSERT_EXT]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..12
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..13
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i64 [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[A_ADDR_SROA_0_0_EXTRACT_TRUNC]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_sink_lt
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_seq_sink_lt..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_sink_lt..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..14(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..15(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[B]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
|
|
; CHECK-NEXT: store i32 [[TMP5]], ptr [[B]], align 4
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..14
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..15
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_par_use
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[B]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_par_use..omp_par, ptr [[A_ADDR]], ptr [[B]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_par_use..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[B:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..16(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..17(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[B]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..16
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..17
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP1]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions
|
|
; CHECK-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_cancellable_regions..omp_par, ptr [[CANCEL1_ADDR]], ptr [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[CANCEL1_ADDR:%.*]], ptr [[CANCEL2_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..18(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..19(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..18
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..19
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq
|
|
; CHECK-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_cancellable_regions_seq..omp_par, ptr [[CANCEL1_ADDR]], ptr [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[CANCEL1_ADDR:%.*]], ptr [[CANCEL2_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..20(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..21(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: [[LNOT_EXT:%.*]] = zext i1 [[TOBOOL_NOT]] to i32
|
|
; CHECK-NEXT: store i32 [[LNOT_EXT]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..20
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..21
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_3..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..22(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..23(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: call void @.omp_outlined..24(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..22
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..23
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..24
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3_seq
|
|
; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD1_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[ADD_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM7:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 3, ptr @merge_3_seq..omp_par, ptr [[A_ADDR]], ptr [[ADD_SEQ_OUTPUT_ALLOC]], ptr [[ADD1_SEQ_OUTPUT_ALLOC]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[ADD1_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[ADD1_SEQ_OUTPUT_LOAD]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[ADD_SEQ_OUTPUT_ALLOC:%.*]], ptr [[ADD1_SEQ_OUTPUT_ALLOC:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..25(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..26(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM4:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM4]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[OMP_REGION_BODY5:%.*]], label [[OMP_REGION_END4:%.*]]
|
|
; CHECK: omp_region.end4:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM6:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM6]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..27(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body5:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED2:%.*]]
|
|
; CHECK: seq.par.merged2:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD_SEQ_OUTPUT_LOAD]], [[TMP5]]
|
|
; CHECK-NEXT: store i32 [[ADD1]], ptr [[ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY5_SPLIT:%.*]]
|
|
; CHECK: omp_region.body5.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END4]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP6]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..25
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..26
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..27
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_seq_call
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..28, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..29, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..30, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..28
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..29
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..30
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_proc_bind
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..31, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..32, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..33, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..31
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..32
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..33
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_num_threads
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..34, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[TMP1]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..35, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..36, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..34
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..35
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..36
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_2_unmergable_1
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_2_unmergable_1..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..39, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_2_unmergable_1..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..37(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..38(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..37
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..38
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..39
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined.(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..1(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_proc_bind
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..2, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..3, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; 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 readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_num_threads
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[A]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..4, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..5, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_seq_call
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..6, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..7, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..7
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_seq..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..8(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..9(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..8
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..9
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_float
|
|
; CHECK-SAME: (float [[F:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4
|
|
; CHECK-NEXT: store float [[F]], ptr [[F_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_float..omp_par, ptr [[F_ADDR]], ptr [[P]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_float..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[F_ADDR:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..10(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..11(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[F_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP3]], 0x40091EB860000000
|
|
; CHECK-NEXT: store float [[ADD]], ptr [[P]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..10
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..11
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_firstprivate
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]] = alloca i64, align 8
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_firstprivate..omp_par, ptr [[A_ADDR]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_firstprivate..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..12(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD:%.*]] = load i64, ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK-NEXT: call void @.omp_outlined..13(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], i64 [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT:%.*]] = zext i32 [[ADD]] to i64
|
|
; CHECK-NEXT: store i64 [[A_CASTED_SROA_0_0_INSERT_EXT]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..12
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..13
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i64 [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[A_ADDR_SROA_0_0_EXTRACT_TRUNC]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_sink_lt
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_seq_sink_lt..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_sink_lt..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..14(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..15(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[B]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
|
|
; CHECK-NEXT: store i32 [[TMP5]], ptr [[B]], align 4
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..14
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..15
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_par_use
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[B]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_par_use..omp_par, ptr [[A_ADDR]], ptr [[B]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_par_use..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[B:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..16(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..17(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[B]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..16
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..17
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP1]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions
|
|
; CHECK-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_cancellable_regions..omp_par, ptr [[CANCEL1_ADDR]], ptr [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[CANCEL1_ADDR:%.*]], ptr [[CANCEL2_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..18(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..19(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..18
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..19
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq
|
|
; CHECK-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_cancellable_regions_seq..omp_par, ptr [[CANCEL1_ADDR]], ptr [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[CANCEL1_ADDR:%.*]], ptr [[CANCEL2_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..20(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..21(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: [[LNOT_EXT:%.*]] = zext i1 [[TOBOOL_NOT]] to i32
|
|
; CHECK-NEXT: store i32 [[LNOT_EXT]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..20
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..21
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_3..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..22(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..23(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: call void @.omp_outlined..24(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..22
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..23
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..24
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3_seq
|
|
; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD1_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[ADD_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM7:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 3, ptr @merge_3_seq..omp_par, ptr [[A_ADDR]], ptr [[ADD_SEQ_OUTPUT_ALLOC]], ptr [[ADD1_SEQ_OUTPUT_ALLOC]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[ADD1_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[ADD1_SEQ_OUTPUT_LOAD]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[ADD_SEQ_OUTPUT_ALLOC:%.*]], ptr [[ADD1_SEQ_OUTPUT_ALLOC:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..25(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..26(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM4:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM4]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[OMP_REGION_BODY5:%.*]], label [[OMP_REGION_END4:%.*]]
|
|
; CHECK: omp_region.end4:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM6:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM6]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..27(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body5:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED2:%.*]]
|
|
; CHECK: seq.par.merged2:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD_SEQ_OUTPUT_LOAD]], [[TMP5]]
|
|
; CHECK-NEXT: store i32 [[ADD1]], ptr [[ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY5_SPLIT:%.*]]
|
|
; CHECK: omp_region.body5.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END4]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP6]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..25
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..26
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..27
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_seq_call
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..28, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..29, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..30, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..28
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..29
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..30
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_proc_bind
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..31, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..32, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..33, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..31
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..32
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..33
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_num_threads
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..34, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[TMP1]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..35, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..36, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..34
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..35
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..36
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_2_unmergable_1
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_2_unmergable_1..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..39, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_2_unmergable_1..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..37(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..38(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..37
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..38
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..39
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined.(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..1(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_proc_bind
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..2, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..3, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; 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 readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_num_threads
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[A]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..4, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..5, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_seq_call
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..6, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..7, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..7
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_seq..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..8(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..9(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..8
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..9
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_float
|
|
; CHECK-SAME: (float [[F:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4
|
|
; CHECK-NEXT: store float [[F]], ptr [[F_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_float..omp_par, ptr [[F_ADDR]], ptr [[P]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_float..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[F_ADDR:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..10(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..11(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[F_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP3]], 0x40091EB860000000
|
|
; CHECK-NEXT: store float [[ADD]], ptr [[P]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..10
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..11
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_firstprivate
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]] = alloca i64, align 8
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_firstprivate..omp_par, ptr [[A_ADDR]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_firstprivate..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..12(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD:%.*]] = load i64, ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK-NEXT: call void @.omp_outlined..13(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], i64 [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP3]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT:%.*]] = zext i32 [[ADD]] to i64
|
|
; CHECK-NEXT: store i64 [[A_CASTED_SROA_0_0_INSERT_EXT]], ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..12
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..13
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i64 [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A]] to i32
|
|
; CHECK-NEXT: call void @use(i32 [[A_ADDR_SROA_0_0_EXTRACT_TRUNC]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_sink_lt
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_seq_sink_lt..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_sink_lt..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..14(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..15(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[B]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
|
|
; CHECK-NEXT: store i32 [[TMP5]], ptr [[B]], align 4
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..14
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..15
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_par_use
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[B]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_seq_par_use..omp_par, ptr [[A_ADDR]], ptr [[B]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_seq_par_use..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[B:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..16(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..17(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[B]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..16
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..17
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[B:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP1]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions
|
|
; CHECK-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_cancellable_regions..omp_par, ptr [[CANCEL1_ADDR]], ptr [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[CANCEL1_ADDR:%.*]], ptr [[CANCEL2_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..18(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..19(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..18
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..19
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq
|
|
; CHECK-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 2, ptr @merge_cancellable_regions_seq..omp_par, ptr [[CANCEL1_ADDR]], ptr [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[CANCEL1_ADDR:%.*]], ptr [[CANCEL2_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..20(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..21(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: [[LNOT_EXT:%.*]] = zext i1 [[TOBOOL_NOT]] to i32
|
|
; CHECK-NEXT: store i32 [[LNOT_EXT]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..20
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..21
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_3..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..22(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..23(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: call void @.omp_outlined..24(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..22
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..23
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..24
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3_seq
|
|
; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD1_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[ADD_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM7:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 3, ptr @merge_3_seq..omp_par, ptr [[A_ADDR]], ptr [[ADD_SEQ_OUTPUT_ALLOC]], ptr [[ADD1_SEQ_OUTPUT_ALLOC]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: [[ADD1_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[ADD1_SEQ_OUTPUT_LOAD]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_3_seq..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]], ptr [[ADD_SEQ_OUTPUT_ALLOC:%.*]], ptr [[ADD1_SEQ_OUTPUT_ALLOC:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..25(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK: omp_region.end:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..26(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM4:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM4]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[OMP_REGION_BODY5:%.*]], label [[OMP_REGION_END4:%.*]]
|
|
; CHECK: omp_region.end4:
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM6:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM6]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split.split.split:
|
|
; CHECK-NEXT: call void @.omp_outlined..27(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK: omp_region.body5:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED2:%.*]]
|
|
; CHECK: seq.par.merged2:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD_SEQ_OUTPUT_LOAD]], [[TMP5]]
|
|
; CHECK-NEXT: store i32 [[ADD1]], ptr [[ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split.split.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY5_SPLIT:%.*]]
|
|
; CHECK: omp_region.body5.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END4]]
|
|
; CHECK: omp_region.body:
|
|
; CHECK-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK: seq.par.merged:
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP6]], 1
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK: omp.par.merged.split:
|
|
; CHECK-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK: omp_region.body.split:
|
|
; CHECK-NEXT: call void @__kmpc_end_master(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..25
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..26
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..27
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_seq_call
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..28, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..29, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..30, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..28
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..29
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..30
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_proc_bind
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..31, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..32, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..33, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..31
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..32
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..33
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@unmergable_3_num_threads
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..34, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[TMP1]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..35, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..36, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..34
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..35
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..36
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_2_unmergable_1
|
|
; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK: omp_parallel:
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB1]], i32 1, ptr @merge_2_unmergable_1..omp_par, ptr [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK: omp.par.outlined.exit:
|
|
; CHECK-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
; CHECK: omp.par.exit.split:
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK: entry.split.split:
|
|
; CHECK-NEXT: call void (...) @foo()
|
|
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef @.omp_outlined..39, ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@merge_2_unmergable_1..omp_par
|
|
; CHECK-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[A_ADDR:%.*]]) #[[ATTR0]] {
|
|
; CHECK-NEXT: omp.par.entry:
|
|
; CHECK-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK-NEXT: store i32 [[TMP0]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK: omp.par.outlined.exit.exitStub:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: omp.par.region:
|
|
; CHECK-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK: omp.par.merged:
|
|
; CHECK-NEXT: call void @.omp_outlined..37(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
|
|
; CHECK-NEXT: call void @__kmpc_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK-NEXT: call void @.omp_outlined..38(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_ADDR]])
|
|
; CHECK-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK: entry.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK: omp.par.region.split:
|
|
; CHECK-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK: omp.par.pre_finalize:
|
|
; CHECK-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..37
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..38
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..39
|
|
; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK-NEXT: ret void
|
|
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr }, align 8
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]])
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[A_ADDR]], ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_A_ADDR:%.*]] = load ptr, ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined.(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..1(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..1
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@unmergable_proc_bind
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1:[0-9]+]])
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..2, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..3, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..2
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..3
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@unmergable_num_threads
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[A]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..4, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..5, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..4
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..5
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@unmergable_seq_call
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..6, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: call void (...) @foo()
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..7, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..6
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..7
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr }, align 8
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[A_ADDR]], ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_seq..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_A_ADDR:%.*]] = load ptr, ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..8(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP3]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK2: omp_region.end:
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split.split:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..9(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp_region.body:
|
|
; CHECK2-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK2: seq.par.merged:
|
|
; CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[LOADGEP_A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], 1
|
|
; CHECK2-NEXT: store i32 [[ADD]], ptr [[LOADGEP_A_ADDR]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK2: omp_region.body.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_FINALIZE:%.*]]
|
|
; CHECK2: omp_region.finalize:
|
|
; CHECK2-NEXT: call void @__kmpc_end_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..8
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..9
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_float
|
|
; CHECK2-SAME: (float [[F:%.*]], ptr nofree writeonly captures(none) [[P:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr, ptr, ptr }, align 8
|
|
; CHECK2-NEXT: [[F_RELOADED:%.*]] = alloca float, align 4
|
|
; CHECK2-NEXT: [[F_ADDR:%.*]] = alloca float, align 4
|
|
; CHECK2-NEXT: store float [[F]], ptr [[F_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: store float [[F]], ptr [[F_RELOADED]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_F_RELOADED:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[F_RELOADED]], ptr [[GEP_F_RELOADED]], align 8
|
|
; CHECK2-NEXT: [[GEP_F_ADDR:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 1
|
|
; CHECK2-NEXT: store ptr [[F_ADDR]], ptr [[GEP_F_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_P:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 2
|
|
; CHECK2-NEXT: store ptr [[P]], ptr [[GEP_P]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_seq_float..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_float..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_F_RELOADED:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_F_RELOADED:%.*]] = load ptr, ptr [[GEP_F_RELOADED]], align 8
|
|
; CHECK2-NEXT: [[GEP_F_ADDR:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 1
|
|
; CHECK2-NEXT: [[LOADGEP_F_ADDR:%.*]] = load ptr, ptr [[GEP_F_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_P:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 2
|
|
; CHECK2-NEXT: [[LOADGEP_P:%.*]] = load ptr, ptr [[GEP_P]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = load float, ptr [[LOADGEP_F_RELOADED]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..10(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_F_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP4]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK2: omp_region.end:
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split.split:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..11(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_F_ADDR]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp_region.body:
|
|
; CHECK2-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK2: seq.par.merged:
|
|
; CHECK2-NEXT: [[ADD:%.*]] = fadd float [[TMP2]], 0x40091EB860000000
|
|
; CHECK2-NEXT: store float [[ADD]], ptr [[LOADGEP_P]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK2: omp_region.body.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_FINALIZE:%.*]]
|
|
; CHECK2: omp_region.finalize:
|
|
; CHECK2-NEXT: call void @__kmpc_end_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..10
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK2-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK2-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..11
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[F:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load float, ptr [[F]], align 4
|
|
; CHECK2-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32
|
|
; CHECK2-NEXT: call void @use(i32 [[CONV]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_firstprivate
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr, ptr }, align 8
|
|
; CHECK2-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]] = alloca i64, align 8
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[A_ADDR]], ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]] = getelementptr { ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 1
|
|
; CHECK2-NEXT: store ptr [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], ptr [[GEP_A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_seq_firstprivate..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_firstprivate..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr, ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_A_ADDR:%.*]] = load ptr, ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]] = getelementptr { ptr, ptr }, ptr [[TMP0]], i32 0, i32 1
|
|
; CHECK2-NEXT: [[LOADGEP_A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC:%.*]] = load ptr, ptr [[GEP_A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..12(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP3]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK2: omp_region.end:
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split.split:
|
|
; CHECK2-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD:%.*]] = load i64, ptr [[LOADGEP_A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..13(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], i64 [[A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_LOAD]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp_region.body:
|
|
; CHECK2-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK2: seq.par.merged:
|
|
; CHECK2-NEXT: [[TMP4:%.*]] = load i32, ptr [[LOADGEP_A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP4]], 1
|
|
; CHECK2-NEXT: store i32 [[ADD]], ptr [[LOADGEP_A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[A_CASTED_SROA_0_0_INSERT_EXT:%.*]] = zext i32 [[ADD]] to i64
|
|
; CHECK2-NEXT: store i64 [[A_CASTED_SROA_0_0_INSERT_EXT]], ptr [[LOADGEP_A_CASTED_SROA_0_0_INSERT_EXT_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK2: omp_region.body.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_FINALIZE:%.*]]
|
|
; CHECK2: omp_region.finalize:
|
|
; CHECK2-NEXT: call void @__kmpc_end_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..12
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..13
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], i64 [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[A_ADDR_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A]] to i32
|
|
; CHECK2-NEXT: call void @use(i32 [[A_ADDR_SROA_0_0_EXTRACT_TRUNC]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_sink_lt
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr }, align 8
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[A_ADDR]], ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_seq_sink_lt..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_sink_lt..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_A_ADDR:%.*]] = load ptr, ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..14(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP3]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK2: omp_region.end:
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split.split:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..15(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp_region.body:
|
|
; CHECK2-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK2: seq.par.merged:
|
|
; CHECK2-NEXT: call void @llvm.lifetime.start.p0(ptr noundef nonnull [[B]])
|
|
; CHECK2-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[B]] to i64
|
|
; CHECK2-NEXT: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
|
|
; CHECK2-NEXT: store i32 [[TMP5]], ptr [[B]], align 4
|
|
; CHECK2-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK2: omp_region.body.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_FINALIZE:%.*]]
|
|
; CHECK2: omp_region.finalize:
|
|
; CHECK2-NEXT: call void @__kmpc_end_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..14
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..15
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_par_use
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr, ptr, ptr }, align 8
|
|
; CHECK2-NEXT: [[A_RELOADED:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[B:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_RELOADED]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_A_RELOADED:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[A_RELOADED]], ptr [[GEP_A_RELOADED]], align 8
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 1
|
|
; CHECK2-NEXT: store ptr [[A_ADDR]], ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_B:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 2
|
|
; CHECK2-NEXT: store ptr [[B]], ptr [[GEP_B]], align 8
|
|
; CHECK2-NEXT: call void @llvm.lifetime.start.p0(ptr [[B]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_seq_par_use..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[B]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_seq_par_use..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_A_RELOADED:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_A_RELOADED:%.*]] = load ptr, ptr [[GEP_A_RELOADED]], align 8
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 1
|
|
; CHECK2-NEXT: [[LOADGEP_A_ADDR:%.*]] = load ptr, ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_B:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 2
|
|
; CHECK2-NEXT: [[LOADGEP_B:%.*]] = load ptr, ptr [[GEP_B]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[LOADGEP_A_RELOADED]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..16(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP4]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK2: omp_region.end:
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split.split:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..17(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_B]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp_region.body:
|
|
; CHECK2-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK2: seq.par.merged:
|
|
; CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], 1
|
|
; CHECK2-NEXT: store i32 [[ADD]], ptr [[LOADGEP_B]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK2: omp_region.body.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_FINALIZE:%.*]]
|
|
; CHECK2: omp_region.finalize:
|
|
; CHECK2-NEXT: call void @__kmpc_end_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..16
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..17
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[B:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP1]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_cancellable_regions
|
|
; CHECK2-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr, ptr }, align 8
|
|
; CHECK2-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_CANCEL1_ADDR:%.*]] = getelementptr { ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[CANCEL1_ADDR]], ptr [[GEP_CANCEL1_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_CANCEL2_ADDR:%.*]] = getelementptr { ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 1
|
|
; CHECK2-NEXT: store ptr [[CANCEL2_ADDR]], ptr [[GEP_CANCEL2_ADDR]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_cancellable_regions..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_cancellable_regions..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_CANCEL1_ADDR:%.*]] = getelementptr { ptr, ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_CANCEL1_ADDR:%.*]] = load ptr, ptr [[GEP_CANCEL1_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_CANCEL2_ADDR:%.*]] = getelementptr { ptr, ptr }, ptr [[TMP0]], i32 0, i32 1
|
|
; CHECK2-NEXT: [[LOADGEP_CANCEL2_ADDR:%.*]] = load ptr, ptr [[GEP_CANCEL2_ADDR]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..18(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_CANCEL1_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..19(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_CANCEL2_ADDR]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..18
|
|
; CHECK2-SAME: (ptr noalias nofree readonly captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK2-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK2-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK2: if.then:
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK2-NEXT: ret void
|
|
; CHECK2: if.end:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..19
|
|
; CHECK2-SAME: (ptr noalias nofree readonly captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK2-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK2-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK2: if.then:
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK2-NEXT: ret void
|
|
; CHECK2: if.end:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq
|
|
; CHECK2-SAME: (i32 [[CANCEL1:%.*]], i32 [[CANCEL2:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr, ptr, ptr }, align 8
|
|
; CHECK2-NEXT: [[CANCEL1_RELOADED:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[CANCEL1_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[CANCEL2_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[CANCEL2]], ptr [[CANCEL2_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: store i32 [[CANCEL1]], ptr [[CANCEL1_RELOADED]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_CANCEL1_RELOADED:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[CANCEL1_RELOADED]], ptr [[GEP_CANCEL1_RELOADED]], align 8
|
|
; CHECK2-NEXT: [[GEP_CANCEL1_ADDR:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 1
|
|
; CHECK2-NEXT: store ptr [[CANCEL1_ADDR]], ptr [[GEP_CANCEL1_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_CANCEL2_ADDR:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 2
|
|
; CHECK2-NEXT: store ptr [[CANCEL2_ADDR]], ptr [[GEP_CANCEL2_ADDR]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_cancellable_regions_seq..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_cancellable_regions_seq..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_CANCEL1_RELOADED:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_CANCEL1_RELOADED:%.*]] = load ptr, ptr [[GEP_CANCEL1_RELOADED]], align 8
|
|
; CHECK2-NEXT: [[GEP_CANCEL1_ADDR:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 1
|
|
; CHECK2-NEXT: [[LOADGEP_CANCEL1_ADDR:%.*]] = load ptr, ptr [[GEP_CANCEL1_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_CANCEL2_ADDR:%.*]] = getelementptr { ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 2
|
|
; CHECK2-NEXT: [[LOADGEP_CANCEL2_ADDR:%.*]] = load ptr, ptr [[GEP_CANCEL2_ADDR]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[LOADGEP_CANCEL1_RELOADED]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..20(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_CANCEL1_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP4]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK2: omp_region.end:
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split.split:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..21(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_CANCEL2_ADDR]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp_region.body:
|
|
; CHECK2-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK2: seq.par.merged:
|
|
; CHECK2-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP2]], 0
|
|
; CHECK2-NEXT: [[LNOT_EXT:%.*]] = zext i1 [[TOBOOL_NOT]] to i32
|
|
; CHECK2-NEXT: store i32 [[LNOT_EXT]], ptr [[LOADGEP_CANCEL2_ADDR]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK2: omp_region.body.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_FINALIZE:%.*]]
|
|
; CHECK2: omp_region.finalize:
|
|
; CHECK2-NEXT: call void @__kmpc_end_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..20
|
|
; CHECK2-SAME: (ptr noalias nofree readonly captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[CANCEL1:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL1]], align 4
|
|
; CHECK2-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK2-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK2: if.then:
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK2-NEXT: ret void
|
|
; CHECK2: if.end:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..21
|
|
; CHECK2-SAME: (ptr noalias nofree readonly captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[CANCEL2:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[CANCEL2]], align 4
|
|
; CHECK2-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
|
|
; CHECK2-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK2: if.then:
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_cancel(ptr noundef nonnull @[[GLOB1]], i32 [[TMP1]], i32 noundef 1)
|
|
; CHECK2-NEXT: ret void
|
|
; CHECK2: if.end:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_3
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr }, align 8
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[A_ADDR]], ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_3..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_3..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_A_ADDR:%.*]] = load ptr, ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..22(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..23(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..24(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..22
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..23
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..24
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_3_seq
|
|
; CHECK2-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr, ptr, ptr, ptr }, align 8
|
|
; CHECK2-NEXT: [[A_RELOADED:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[ADD1_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[ADD_SEQ_OUTPUT_ALLOC:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM7:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_RELOADED]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_A_RELOADED:%.*]] = getelementptr { ptr, ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[A_RELOADED]], ptr [[GEP_A_RELOADED]], align 8
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr, ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 1
|
|
; CHECK2-NEXT: store ptr [[A_ADDR]], ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_ADD_SEQ_OUTPUT_ALLOC:%.*]] = getelementptr { ptr, ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 2
|
|
; CHECK2-NEXT: store ptr [[ADD_SEQ_OUTPUT_ALLOC]], ptr [[GEP_ADD_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK2-NEXT: [[GEP_ADD1_SEQ_OUTPUT_ALLOC:%.*]] = getelementptr { ptr, ptr, ptr, ptr }, ptr [[STRUCTARG]], i32 0, i32 3
|
|
; CHECK2-NEXT: store ptr [[ADD1_SEQ_OUTPUT_ALLOC]], ptr [[GEP_ADD1_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_3_seq..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: [[ADD1_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[ADD1_SEQ_OUTPUT_LOAD]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_3_seq..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_A_RELOADED:%.*]] = getelementptr { ptr, ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_A_RELOADED:%.*]] = load ptr, ptr [[GEP_A_RELOADED]], align 8
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr, ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 1
|
|
; CHECK2-NEXT: [[LOADGEP_A_ADDR:%.*]] = load ptr, ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[GEP_ADD_SEQ_OUTPUT_ALLOC:%.*]] = getelementptr { ptr, ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 2
|
|
; CHECK2-NEXT: [[LOADGEP_ADD_SEQ_OUTPUT_ALLOC:%.*]] = load ptr, ptr [[GEP_ADD_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK2-NEXT: [[GEP_ADD1_SEQ_OUTPUT_ALLOC:%.*]] = getelementptr { ptr, ptr, ptr, ptr }, ptr [[TMP0]], i32 0, i32 3
|
|
; CHECK2-NEXT: [[LOADGEP_ADD1_SEQ_OUTPUT_ALLOC:%.*]] = load ptr, ptr [[GEP_ADD1_SEQ_OUTPUT_ALLOC]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TMP2:%.*]] = load i32, ptr [[LOADGEP_A_RELOADED]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..25(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP4]], label [[OMP_REGION_BODY:%.*]], label [[OMP_REGION_END:%.*]]
|
|
; CHECK2: omp_region.end:
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM1]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split.split:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..26(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM4:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM4]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK2-NEXT: [[TMP6:%.*]] = icmp ne i32 [[TMP5]], 0
|
|
; CHECK2-NEXT: br i1 [[TMP6]], label [[OMP_REGION_BODY5:%.*]], label [[OMP_REGION_END4:%.*]]
|
|
; CHECK2: omp_region.end4:
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM6:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM6]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split.split.split.split:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..27(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[FINI:%.*]]
|
|
; CHECK2: .fini:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_EXIT_EXITSTUB:.*]]
|
|
; CHECK2: omp_region.body6:
|
|
; CHECK2-NEXT: br label [[SEQ_PAR_MERGED2:%.*]]
|
|
; CHECK2: seq.par.merged2:
|
|
; CHECK2-NEXT: [[ADD_SEQ_OUTPUT_LOAD:%.*]] = load i32, ptr [[LOADGEP_ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK2-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD_SEQ_OUTPUT_LOAD]], [[TMP2]]
|
|
; CHECK2-NEXT: store i32 [[ADD1]], ptr [[LOADGEP_ADD1_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split.split.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_BODY5_SPLIT:%.*]]
|
|
; CHECK2: omp_region.body6.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_FINALIZE5:%.*]]
|
|
; CHECK2: omp_region.finalize{{.*}}:
|
|
; CHECK2-NEXT: call void @__kmpc_end_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
|
|
; CHECK2-NEXT: br label [[OMP_REGION_END4]]
|
|
; CHECK2: omp_region.body:
|
|
; CHECK2-NEXT: br label [[SEQ_PAR_MERGED:%.*]]
|
|
; CHECK2: seq.par.merged:
|
|
; CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], 1
|
|
; CHECK2-NEXT: store i32 [[ADD]], ptr [[LOADGEP_ADD_SEQ_OUTPUT_ALLOC]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED_SPLIT:%.*]]
|
|
; CHECK2: omp.par.merged.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_BODY_SPLIT:%.*]]
|
|
; CHECK2: omp_region.body.split:
|
|
; CHECK2-NEXT: br label [[OMP_REGION_FINALIZE:%.*]]
|
|
; CHECK2: omp_region.finalize:
|
|
; CHECK2-NEXT: call void @__kmpc_end_master(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: br label [[OMP_REGION_END]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..25
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..26
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..27
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@unmergable_3_seq_call
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..28, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: call void (...) @foo()
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..29, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: call void (...) @foo()
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..30, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..28
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..29
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..30
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@unmergable_3_proc_bind
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..31, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: call void @__kmpc_push_proc_bind(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 noundef 3)
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..32, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..33, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..31
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..32
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..33
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@unmergable_3_num_threads
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]])
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..34, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: call void @__kmpc_push_num_threads(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 [[TMP0]], i32 [[A]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..35, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..36, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..34
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..35
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..36
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_2_unmergable_1
|
|
; CHECK2-SAME: (i32 [[A:%.*]]) local_unnamed_addr {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[STRUCTARG:%.*]] = alloca { ptr }, align 8
|
|
; CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
; CHECK2: omp_parallel:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[STRUCTARG]], i32 0, i32 0
|
|
; CHECK2-NEXT: store ptr [[A_ADDR]], ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 1, ptr @merge_2_unmergable_1..omp_par, ptr [[STRUCTARG]])
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]]
|
|
; CHECK2: omp.par.exit:
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT_SPLIT:%.*]]
|
|
; CHECK2: entry.split.split:
|
|
; CHECK2-NEXT: call void (...) @foo()
|
|
; CHECK2-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..39, ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A_ADDR]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@merge_2_unmergable_1..omp_par
|
|
; CHECK2-SAME: (ptr noalias [[TID_ADDR:%.*]], ptr noalias [[ZERO_ADDR:%.*]], ptr [[TMP0:%.*]]) #[[ATTR0]] {
|
|
; CHECK2-NEXT: omp.par.entry:
|
|
; CHECK2-NEXT: [[GEP_A_ADDR:%.*]] = getelementptr { ptr }, ptr [[TMP0]], i32 0, i32 0
|
|
; CHECK2-NEXT: [[LOADGEP_A_ADDR:%.*]] = load ptr, ptr [[GEP_A_ADDR]], align 8
|
|
; CHECK2-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4
|
|
; CHECK2-NEXT: [[TMP1:%.*]] = load i32, ptr [[TID_ADDR]], align 4
|
|
; CHECK2-NEXT: store i32 [[TMP1]], ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: [[TID:%.*]] = load i32, ptr [[TID_ADDR_LOCAL]], align 4
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION:%.*]]
|
|
; CHECK2: omp.par.region:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_MERGED:%.*]]
|
|
; CHECK2: omp.par.merged:
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..37(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2]])
|
|
; CHECK2-NEXT: call void @__kmpc_barrier(ptr @[[GLOB3]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
|
; CHECK2-NEXT: call void (ptr, ptr, ...) @.omp_outlined..38(ptr [[TID_ADDR]], ptr [[ZERO_ADDR]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOADGEP_A_ADDR]])
|
|
; CHECK2-NEXT: br label [[ENTRY_SPLIT:%.*]]
|
|
; CHECK2: entry.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_REGION_SPLIT:%.*]]
|
|
; CHECK2: omp.par.region.split:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
|
|
; CHECK2: omp.par.pre_finalize:
|
|
; CHECK2-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
|
|
; CHECK2: omp.par.exit.exitStub:
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..37
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..38
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|
|
;
|
|
; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..39
|
|
; CHECK2-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
|
|
; CHECK2-NEXT: entry:
|
|
; CHECK2-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
|
|
; CHECK2-NEXT: call void @use(i32 [[TMP0]])
|
|
; CHECK2-NEXT: ret void
|
|
;
|