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