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