teak-llvm/clang/test/OpenMP/parallel_sections_codegen.cpp
Alexey Bataev aee18557f7 [OPRNMP] Fix for PR33445: ICE: OpenMP target containing ordered for.
If exceptions are enabled, there may be a problem with the codegen of
the finalization functions from OpenMP runtime. It happens because of
the problem with the getting of thread identifier value. Patch tries to
fix it by using the result of the call of function
__kmpc_global_thread_num() rather than loading of value of outlined
function parameter.

llvm-svn: 311007
2017-08-16 14:01:00 +00:00

88 lines
3.5 KiB
C++

// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -o - %s | FileCheck %s
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -include-pch %t -fsyntax-only -verify %s -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-llvm -o - | FileCheck %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
// CHECK-LABEL: foo
void foo() {};
// CHECK-LABEL: bar
void bar() {};
template <class T>
T tmain() {
#pragma omp parallel sections
{
foo();
}
return T();
}
// CHECK-LABEL: @main
int main() {
// CHECK: call void (%{{.+}}*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_PARALLEL_FUNC:@.+]] to void (i32*, i32*, ...)*))
// CHECK-LABEL: }
// CHECK: define internal void [[OMP_PARALLEL_FUNC]](i32* noalias [[GTID_PARAM_ADDR:%.+]], i32* noalias %{{.+}})
// CHECK: store i32* [[GTID_PARAM_ADDR]], i32** [[GTID_REF_ADDR:%.+]],
#pragma omp parallel sections
{
// CHECK: store i32 0, i32* [[LB_PTR:%.+]],
// CHECK: store i32 1, i32* [[UB_PTR:%.+]],
// CHECK: call void @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST_PTR:%.+]], i32* [[LB_PTR]], i32* [[UB_PTR]], i32* [[STRIDE_PTR:%.+]], i32 1, i32 1)
// <<UB = min(UB, GlobalUB);>>
// CHECK: [[UB:%.+]] = load i32, i32* [[UB_PTR]]
// CHECK: [[CMP:%.+]] = icmp slt i32 [[UB]], 1
// CHECK: [[MIN_UB_GLOBALUB:%.+]] = select i1 [[CMP]], i32 [[UB]], i32 1
// CHECK: store i32 [[MIN_UB_GLOBALUB]], i32* [[UB_PTR]]
// <<IV = LB;>>
// CHECK: [[LB:%.+]] = load i32, i32* [[LB_PTR]]
// CHECK: store i32 [[LB]], i32* [[IV_PTR:%.+]]
// CHECK: br label %[[INNER_FOR_COND:.+]]
// CHECK: [[INNER_FOR_COND]]
// <<IV <= UB?>>
// CHECK: [[IV:%.+]] = load i32, i32* [[IV_PTR]]
// CHECK: [[UB:%.+]] = load i32, i32* [[UB_PTR]]
// CHECK: [[CMP:%.+]] = icmp sle i32 [[IV]], [[UB]]
// CHECK: br i1 [[CMP]], label %[[INNER_LOOP_BODY:.+]], label %[[INNER_LOOP_END:.+]]
// CHECK: [[INNER_LOOP_BODY]]
// <<TRUE>> - > <BODY>
// CHECK: [[IV:%.+]] = load i32, i32* [[IV_PTR]]
// CHECK: switch i32 [[IV]], label %[[SECTIONS_EXIT:.+]] [
// CHECK-NEXT: i32 0, label %[[SECTIONS_CASE0:.+]]
// CHECK-NEXT: i32 1, label %[[SECTIONS_CASE1:.+]]
#pragma omp section
// CHECK: [[SECTIONS_CASE0]]
// CHECK-NEXT: invoke void @{{.*}}foo{{.*}}()
// CHECK: br label %[[SECTIONS_EXIT]]
foo();
#pragma omp section
// CHECK: [[SECTIONS_CASE1]]
// CHECK-NEXT: invoke void @{{.*}}bar{{.*}}()
// CHECK: br label %[[SECTIONS_EXIT]]
bar();
// CHECK: [[SECTIONS_EXIT]]
// <<++IV;>>
// CHECK: [[IV:%.+]] = load i32, i32* [[IV_PTR]]
// CHECK-NEXT: [[INC:%.+]] = add nsw i32 [[IV]], 1
// CHECK-NEXT: store i32 [[INC]], i32* [[IV_PTR]]
// CHECK-NEXT: br label %[[INNER_FOR_COND]]
// CHECK: [[INNER_LOOP_END]]
}
// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
return tmain<int>();
}
// CHECK-LABEL: tmain
// CHECK: call void {{.*}} @__kmpc_fork_call(
// CHECK: __kmpc_global_thread_num
// CHECK: call void @__kmpc_for_static_init_4(
// CHECK: invoke void @{{.*}}foo{{.*}}()
// CHECK-NEXT: unwind label %[[TERM_LPAD:.+]]
// CHECK: call void @__kmpc_for_static_fini(
// CHECK-NEXT: ret
// CHECK: [[TERM_LPAD]]
// CHECK: call void @__clang_call_terminate(i8*
// CHECK-NEXT: unreachable
#endif