During code generation we might change/add basic blocks so keeping a list of them is fairly easy to break. Nested parallel regions were enough. The new scheme does recompute the list of blocks to be outlined once it is needed. Reviewed By: anchu-rajendran Differential Revision: https://reviews.llvm.org/D82722
111 lines
4.7 KiB
C
111 lines
4.7 KiB
C
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
|
|
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-enable-irbuilder -x c++ -emit-llvm %s -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=ALL,IRBUILDER
|
|
// %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o /tmp/t1 %s
|
|
// %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch /tmp/t1 -verify %s -emit-llvm -o - | FileCheck --check-prefixes=ALL-DEBUG,IRBUILDER-DEBUG %s
|
|
|
|
// expected-no-diagnostics
|
|
|
|
// TODO: Teach the update script to check new functions too.
|
|
|
|
#ifndef HEADER
|
|
#define HEADER
|
|
|
|
// ALL-LABEL: @_Z17nested_parallel_0v(
|
|
// ALL-NEXT: entry:
|
|
// ALL-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @1)
|
|
// ALL-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
// ALL: omp_parallel:
|
|
// ALL-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @1, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @_Z17nested_parallel_0v..omp_par.1 to void (i32*, i32*, ...)*))
|
|
// ALL-NEXT: br label [[OMP_PAR_OUTLINED_EXIT12:%.*]]
|
|
// ALL: omp.par.outlined.exit12:
|
|
// ALL-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
// ALL: omp.par.exit.split:
|
|
// ALL-NEXT: ret void
|
|
//
|
|
void nested_parallel_0(void) {
|
|
#pragma omp parallel
|
|
{
|
|
#pragma omp parallel
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
// ALL-LABEL: @_Z17nested_parallel_1Pfid(
|
|
// ALL-NEXT: entry:
|
|
// ALL-NEXT: [[R_ADDR:%.*]] = alloca float*, align 8
|
|
// ALL-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
// ALL-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
|
|
// ALL-NEXT: store float* [[R:%.*]], float** [[R_ADDR]], align 8
|
|
// ALL-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
|
|
// ALL-NEXT: store double [[B:%.*]], double* [[B_ADDR]], align 8
|
|
// ALL-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @1)
|
|
// ALL-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
// ALL: omp_parallel:
|
|
// ALL-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @1, i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, double*, float**)* @_Z17nested_parallel_1Pfid..omp_par.2 to void (i32*, i32*, ...)*), i32* [[A_ADDR]], double* [[B_ADDR]], float** [[R_ADDR]])
|
|
// ALL-NEXT: br label [[OMP_PAR_OUTLINED_EXIT13:%.*]]
|
|
// ALL: omp.par.outlined.exit13:
|
|
// ALL-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
// ALL: omp.par.exit.split:
|
|
// ALL-NEXT: ret void
|
|
//
|
|
void nested_parallel_1(float *r, int a, double b) {
|
|
#pragma omp parallel
|
|
{
|
|
#pragma omp parallel
|
|
{
|
|
*r = a + b;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ALL-LABEL: @_Z17nested_parallel_2Pfid(
|
|
// ALL-NEXT: entry:
|
|
// ALL-NEXT: [[R_ADDR:%.*]] = alloca float*, align 8
|
|
// ALL-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
|
|
// ALL-NEXT: [[B_ADDR:%.*]] = alloca double, align 8
|
|
// ALL-NEXT: store float* [[R:%.*]], float** [[R_ADDR]], align 8
|
|
// ALL-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
|
|
// ALL-NEXT: store double [[B:%.*]], double* [[B_ADDR]], align 8
|
|
// ALL-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @1)
|
|
// ALL-NEXT: br label [[OMP_PARALLEL:%.*]]
|
|
// ALL: omp_parallel:
|
|
// ALL-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @1, i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, double*, float**)* @_Z17nested_parallel_2Pfid..omp_par.5 to void (i32*, i32*, ...)*), i32* [[A_ADDR]], double* [[B_ADDR]], float** [[R_ADDR]])
|
|
// ALL-NEXT: br label [[OMP_PAR_OUTLINED_EXIT55:%.*]]
|
|
// ALL: omp.par.outlined.exit55:
|
|
// ALL-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]]
|
|
// ALL: omp.par.exit.split:
|
|
// ALL-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
|
|
// ALL-NEXT: [[CONV56:%.*]] = sitofp i32 [[TMP0]] to double
|
|
// ALL-NEXT: [[TMP1:%.*]] = load double, double* [[B_ADDR]], align 8
|
|
// ALL-NEXT: [[ADD57:%.*]] = fadd double [[CONV56]], [[TMP1]]
|
|
// ALL-NEXT: [[CONV58:%.*]] = fptrunc double [[ADD57]] to float
|
|
// ALL-NEXT: [[TMP2:%.*]] = load float*, float** [[R_ADDR]], align 8
|
|
// ALL-NEXT: store float [[CONV58]], float* [[TMP2]], align 4
|
|
// ALL-NEXT: ret void
|
|
//
|
|
void nested_parallel_2(float *r, int a, double b) {
|
|
#pragma omp parallel
|
|
{
|
|
*r = a + b;
|
|
#pragma omp parallel
|
|
{
|
|
*r = a + b;
|
|
#pragma omp parallel
|
|
{
|
|
*r = a + b;
|
|
}
|
|
*r = a + b;
|
|
#pragma omp parallel
|
|
{
|
|
*r = a + b;
|
|
}
|
|
*r = a + b;
|
|
}
|
|
*r = a + b;
|
|
}
|
|
*r = a + b;
|
|
}
|
|
|
|
#endif
|