1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 2 // 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 3 // %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 4 // %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 5 6 // expected-no-diagnostics 7 8 // TODO: Teach the update script to check new functions too. 9 10 #ifndef HEADER 11 #define HEADER 12 13 // ALL-LABEL: @_Z17nested_parallel_0v( 14 // ALL-NEXT: entry: 15 // ALL-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1:[0-9]+]]) 16 // ALL-NEXT: br label [[OMP_PARALLEL:%.*]] 17 // ALL: omp_parallel: 18 // ALL-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @_Z17nested_parallel_0v..omp_par.1 to void (i32*, i32*, ...)*)) 19 // ALL-NEXT: br label [[OMP_PAR_OUTLINED_EXIT12:%.*]] 20 // ALL: omp.par.outlined.exit12: 21 // ALL-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]] 22 // ALL: omp.par.exit.split: 23 // ALL-NEXT: ret void 24 // 25 void nested_parallel_0(void) { 26 #pragma omp parallel 27 { 28 #pragma omp parallel 29 { 30 } 31 } 32 } 33 34 // ALL-LABEL: @_Z17nested_parallel_1Pfid( 35 // ALL-NEXT: entry: 36 // ALL-NEXT: [[R_ADDR:%.*]] = alloca float*, align 8 37 // ALL-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 38 // ALL-NEXT: [[B_ADDR:%.*]] = alloca double, align 8 39 // ALL-NEXT: store float* [[R:%.*]], float** [[R_ADDR]], align 8 40 // ALL-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4 41 // ALL-NEXT: store double [[B:%.*]], double* [[B_ADDR]], align 8 42 // ALL-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) 43 // ALL-NEXT: br label [[OMP_PARALLEL:%.*]] 44 // ALL: omp_parallel: 45 // ALL-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], 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]]) 46 // ALL-NEXT: br label [[OMP_PAR_OUTLINED_EXIT13:%.*]] 47 // ALL: omp.par.outlined.exit13: 48 // ALL-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]] 49 // ALL: omp.par.exit.split: 50 // ALL-NEXT: ret void 51 // 52 void nested_parallel_1(float *r, int a, double b) { 53 #pragma omp parallel 54 { 55 #pragma omp parallel 56 { 57 *r = a + b; 58 } 59 } 60 } 61 62 // ALL-LABEL: @_Z17nested_parallel_2Pfid( 63 // ALL-NEXT: entry: 64 // ALL-NEXT: [[R_ADDR:%.*]] = alloca float*, align 8 65 // ALL-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 66 // ALL-NEXT: [[B_ADDR:%.*]] = alloca double, align 8 67 // ALL-NEXT: store float* [[R:%.*]], float** [[R_ADDR]], align 8 68 // ALL-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4 69 // ALL-NEXT: store double [[B:%.*]], double* [[B_ADDR]], align 8 70 // ALL-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) 71 // ALL-NEXT: br label [[OMP_PARALLEL:%.*]] 72 // ALL: omp_parallel: 73 // ALL-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], 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]]) 74 // ALL-NEXT: br label [[OMP_PAR_OUTLINED_EXIT55:%.*]] 75 // ALL: omp.par.outlined.exit55: 76 // ALL-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]] 77 // ALL: omp.par.exit.split: 78 // ALL-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4 79 // ALL-NEXT: [[CONV56:%.*]] = sitofp i32 [[TMP0]] to double 80 // ALL-NEXT: [[TMP1:%.*]] = load double, double* [[B_ADDR]], align 8 81 // ALL-NEXT: [[ADD57:%.*]] = fadd double [[CONV56]], [[TMP1]] 82 // ALL-NEXT: [[CONV58:%.*]] = fptrunc double [[ADD57]] to float 83 // ALL-NEXT: [[TMP2:%.*]] = load float*, float** [[R_ADDR]], align 8 84 // ALL-NEXT: store float [[CONV58]], float* [[TMP2]], align 4 85 // ALL-NEXT: ret void 86 // 87 void nested_parallel_2(float *r, int a, double b) { 88 #pragma omp parallel 89 { 90 *r = a + b; 91 #pragma omp parallel 92 { 93 *r = a + b; 94 #pragma omp parallel 95 { 96 *r = a + b; 97 } 98 *r = a + b; 99 #pragma omp parallel 100 { 101 *r = a + b; 102 } 103 *r = a + b; 104 } 105 *r = a + b; 106 } 107 *r = a + b; 108 } 109 110 #endif 111