1 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -x c++ -emit-llvm %s -o - | FileCheck %s 2 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -x c++ -emit-llvm -std=c++98 %s -o - | FileCheck %s 3 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -x c++ -emit-llvm -std=c++11 %s -o - | FileCheck %s 4 // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG 5 // expected-no-diagnostics 6 7 int a; 8 int b; 9 10 struct St { 11 unsigned long field; 12 St() {} 13 ~St() {} 14 int &get() { return a; } 15 }; 16 17 // CHECK-LABEL: parallel_atomic_ewc 18 void parallel_atomic_ewc() { 19 St s; 20 #pragma omp parallel 21 { 22 // CHECK: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]]) 23 // CHECK: [[SCALAR_ADDR:%.+]] = invoke dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* [[TEMP_ST_ADDR]]) 24 // CHECK: [[SCALAR_VAL:%.+]] = load atomic i32, i32* [[SCALAR_ADDR]] monotonic 25 // CHECK: store i32 [[SCALAR_VAL]], i32* @b 26 // CHECK98: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]]) 27 // CHECK11: call void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]]) 28 #pragma omp atomic read 29 b = St().get(); 30 // CHECK-DAG: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]]) 31 // CHECK-DAG: [[SCALAR_ADDR:%.+]] = invoke dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* [[TEMP_ST_ADDR]]) 32 // CHECK-DAG: [[B_VAL:%.+]] = load i32, i32* @b 33 // CHECK: store atomic i32 [[B_VAL]], i32* [[SCALAR_ADDR]] monotonic 34 // CHECK: {{invoke|call}} void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]]) 35 #pragma omp atomic write 36 St().get() = b; 37 // CHECK: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]]) 38 // CHECK: [[SCALAR_ADDR:%.+]] = invoke dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* [[TEMP_ST_ADDR]]) 39 // CHECK: [[B_VAL:%.+]] = load i32, i32* @b 40 // CHECK: [[OLD_VAL:%.+]] = load atomic i32, i32* [[SCALAR_ADDR]] monotonic, 41 // CHECK: br label %[[OMP_UPDATE:.+]] 42 // CHECK: [[OMP_UPDATE]] 43 // CHECK: [[OLD_PHI_VAL:%.+]] = phi i32 [ [[OLD_VAL]], %{{.+}} ], [ [[NEW_OLD_VAL:%.+]], %[[OMP_UPDATE]] ] 44 // CHECK: [[NEW_VAL:%.+]] = srem i32 [[OLD_PHI_VAL]], [[B_VAL]] 45 // CHECK: store i32 [[NEW_VAL]], i32* [[TEMP:%.+]], 46 // CHECK: [[NEW_VAL:%.+]] = load i32, i32* [[TEMP]], 47 // CHECK: [[RES:%.+]] = cmpxchg i32* [[SCALAR_ADDR]], i32 [[OLD_PHI_VAL]], i32 [[NEW_VAL]] monotonic monotonic 48 // CHECK: [[NEW_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0 49 // CHECK: [[COND:%.+]] = extractvalue { i32, i1 } [[RES]], 1 50 // CHECK: br i1 [[COND]], label %[[OMP_DONE:.+]], label %[[OMP_UPDATE]] 51 // CHECK: [[OMP_DONE]] 52 // CHECK: {{invoke|call}} void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]]) 53 #pragma omp atomic 54 St().get() %= b; 55 #pragma omp atomic 56 s.field++; 57 // CHECK: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]]) 58 // CHECK: [[SCALAR_ADDR:%.+]] = invoke dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* [[TEMP_ST_ADDR]]) 59 // CHECK: [[B_VAL:%.+]] = load i32, i32* @b 60 // CHECK: [[OLD_VAL:%.+]] = load atomic i32, i32* [[SCALAR_ADDR]] monotonic, 61 // CHECK: br label %[[OMP_UPDATE:.+]] 62 // CHECK: [[OMP_UPDATE]] 63 // CHECK: [[OLD_PHI_VAL:%.+]] = phi i32 [ [[OLD_VAL]], %{{.+}} ], [ [[NEW_OLD_VAL:%.+]], %[[OMP_UPDATE]] ] 64 // CHECK: [[NEW_CALC_VAL:%.+]] = srem i32 [[OLD_PHI_VAL]], [[B_VAL]] 65 // CHECK: store i32 [[NEW_CALC_VAL]], i32* [[TEMP:%.+]], 66 // CHECK: [[NEW_VAL:%.+]] = load i32, i32* [[TEMP]], 67 // CHECK: [[RES:%.+]] = cmpxchg i32* [[SCALAR_ADDR]], i32 [[OLD_PHI_VAL]], i32 [[NEW_VAL]] monotonic monotonic 68 // CHECK: [[NEW_OLD_VAL]] = extractvalue { i32, i1 } [[RES]], 0 69 // CHECK: [[COND:%.+]] = extractvalue { i32, i1 } [[RES]], 1 70 // CHECK: br i1 [[COND]], label %[[OMP_DONE:.+]], label %[[OMP_UPDATE]] 71 // CHECK: [[OMP_DONE]] 72 // CHECK: store i32 [[NEW_CALC_VAL]], i32* @a, 73 // CHECK: {{invoke|call}} void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]]) 74 #pragma omp atomic capture 75 a = St().get() %= b; 76 } 77 } 78 79 int &foo() { return a; } 80 81 // TERM_DEBUG-LABEL: parallel_atomic 82 void parallel_atomic() { 83 #pragma omp parallel 84 { 85 #pragma omp atomic read 86 // TERM_DEBUG-NOT: __kmpc_global_thread_num 87 // TERM_DEBUG: invoke {{.*}}foo{{.*}}() 88 // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], 89 // TERM_DEBUG: load atomic i32, i32* @{{.+}} monotonic, {{.*}}!dbg [[READ_LOC:![0-9]+]] 90 foo() = a; 91 #pragma omp atomic write 92 // TERM_DEBUG-NOT: __kmpc_global_thread_num 93 // TERM_DEBUG: invoke {{.*}}foo{{.*}}() 94 // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], 95 // TERM_DEBUG-NOT: __kmpc_global_thread_num 96 // TERM_DEBUG: store atomic i32 {{%.+}}, i32* @{{.+}} monotonic, {{.*}}!dbg [[WRITE_LOC:![0-9]+]] 97 a = foo(); 98 #pragma omp atomic update 99 // TERM_DEBUG-NOT: __kmpc_global_thread_num 100 // TERM_DEBUG: invoke {{.*}}foo{{.*}}() 101 // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], 102 // TERM_DEBUG-NOT: __kmpc_global_thread_num 103 // TERM_DEBUG: atomicrmw add i32* @{{.+}}, i32 %{{.+}} monotonic, {{.*}}!dbg [[UPDATE_LOC:![0-9]+]] 104 a += foo(); 105 #pragma omp atomic capture 106 // TERM_DEBUG-NOT: __kmpc_global_thread_num 107 // TERM_DEBUG: invoke {{.*}}foo{{.*}}() 108 // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], 109 // TERM_DEBUG-NOT: __kmpc_global_thread_num 110 // TERM_DEBUG: [[OLD_VAL:%.+]] = atomicrmw add i32* @{{.+}}, i32 %{{.+}} monotonic, {{.*}}!dbg [[CAPTURE_LOC:![0-9]+]] 111 // TERM_DEBUG: store i32 [[OLD_VAL]], i32* @b, 112 {b = a; a += foo(); } 113 } 114 // TERM_DEBUG: [[TERM_LPAD]] 115 // TERM_DEBUG: call void @__clang_call_terminate 116 // TERM_DEBUG: unreachable 117 } 118 // TERM_DEBUG-DAG: [[READ_LOC]] = !DILocation(line: [[@LINE-28]], 119 // TERM_DEBUG-DAG: [[WRITE_LOC]] = !DILocation(line: [[@LINE-22]], 120 // TERM_DEBUG-DAG: [[UPDATE_LOC]] = !DILocation(line: [[@LINE-16]], 121 // TERM_DEBUG-DAG: [[CAPTURE_LOC]] = !DILocation(line: [[@LINE-9]], 122