Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / OpenMP / reduction_compound_op.cpp
blob1cb9292a8e5ae4f456c23e07c4b5bd2f2ddcac39
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
2 // RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp -DNORM \
3 //RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix NORM
5 //RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp -DCOMP \
6 //RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix COMP
8 // Prefer compound operators since that is what the spec seems to say.
9 // RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp -DNORM -DCOMP \
10 //RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix COMP
12 //RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp-simd -DNORM \
13 //RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix SIMD-ONLY
15 //RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp-simd -DCOMP \
16 //RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix SIMD-ONLY
18 //RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-unknown-linux-gnu -fopenmp-simd -DNORM -DCOMP \
19 //RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix SIMD-ONLY
22 struct Point {
23 int x = 0;
24 int y = 0;
25 #if NORM
26 Point operator+(Point const &other) const;
27 Point operator-(Point const &other) const;
28 Point operator*(Point const &other) const;
29 Point operator&(Point const &other) const;
30 Point operator|(Point const &other) const;
31 Point operator^(Point const &other) const;
32 #endif
33 Point operator&&(Point const &other) const;
34 Point operator||(Point const &other) const;
35 Point &operator=(Point const &other);
36 #if COMP
37 Point &operator+=(Point const &other);
38 Point &operator*=(Point const &other);
39 Point &operator&=(Point const &other);
40 Point &operator|=(Point const &other);
41 Point &operator^=(Point const &other);
42 #endif
45 void work(Point &P, int N, Point const *Points);
47 void foo(int N, Point const *Points) {
48 Point Red;
49 #pragma omp parallel for reduction(+: Red)
50 for (unsigned I = 0; I < N; ++I)
51 work(Red, I, Points);
53 #pragma omp parallel for reduction(-: Red)
54 for (unsigned I = 0; I < N; ++I)
55 work(Red, I, Points);
57 #pragma omp parallel for reduction(*: Red)
58 for (unsigned I = 0; I < N; ++I)
59 work(Red, I, Points);
61 #pragma omp parallel for reduction(&: Red)
62 for (unsigned I = 0; I < N; ++I)
63 work(Red, I, Points);
65 #pragma omp parallel for reduction(|: Red)
66 for (unsigned I = 0; I < N; ++I)
67 work(Red, I, Points);
69 #pragma omp parallel for reduction(^: Red)
70 for (unsigned I = 0; I < N; ++I)
71 work(Red, I, Points);
73 #pragma omp parallel for reduction(&&: Red)
74 for (unsigned I = 0; I < N; ++I)
75 work(Red, I, Points);
77 #pragma omp parallel for reduction(||: Red)
78 for (unsigned I = 0; I < N; ++I)
79 work(Red, I, Points);
81 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point
82 // NORM-SAME: (i32 [[N:%.*]], ptr [[POINTS:%.*]]) #[[ATTR0:[0-9]+]] {
83 // NORM-NEXT: entry:
84 // NORM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4
85 // NORM-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
86 // NORM-NEXT: [[RED:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
87 // NORM-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4
88 // NORM-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
89 // NORM-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED]]) #[[ATTR3:[0-9]+]]
90 // NORM-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
91 // NORM-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.1, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
92 // NORM-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.2, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
93 // NORM-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.3, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
94 // NORM-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.4, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
95 // NORM-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.5, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
96 // NORM-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.6, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
97 // NORM-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.7, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
98 // NORM-NEXT: ret void
101 // NORM-LABEL: define {{[^@]+}}@_ZN5PointC1Ev
102 // NORM-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 {
103 // NORM-NEXT: entry:
104 // NORM-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8
105 // NORM-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
106 // NORM-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
107 // NORM-NEXT: call void @_ZN5PointC2Ev(ptr nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR3]]
108 // NORM-NEXT: ret void
111 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined
112 // NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2:[0-9]+]] {
113 // NORM-NEXT: entry:
114 // NORM-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
115 // NORM-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
116 // NORM-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
117 // NORM-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
118 // NORM-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
119 // NORM-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
120 // NORM-NEXT: [[TMP:%.*]] = alloca i32, align 4
121 // NORM-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
122 // NORM-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
123 // NORM-NEXT: [[I:%.*]] = alloca i32, align 4
124 // NORM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
125 // NORM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
126 // NORM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
127 // NORM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
128 // NORM-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
129 // NORM-NEXT: [[I4:%.*]] = alloca i32, align 4
130 // NORM-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
131 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
132 // NORM-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
133 // NORM-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
134 // NORM-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
135 // NORM-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
136 // NORM-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
137 // NORM-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
138 // NORM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
139 // NORM-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
140 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
141 // NORM-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
142 // NORM-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
143 // NORM-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
144 // NORM-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
145 // NORM-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
146 // NORM-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
147 // NORM-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
148 // NORM-NEXT: store i32 0, ptr [[I]], align 4
149 // NORM-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
150 // NORM-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
151 // NORM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
152 // NORM: omp.precond.then:
153 // NORM-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
154 // NORM-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
155 // NORM-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
156 // NORM-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
157 // NORM-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
158 // NORM-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
159 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
160 // NORM-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
161 // NORM-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1:[0-9]+]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
162 // NORM-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
163 // NORM-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
164 // NORM-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
165 // NORM-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
166 // NORM: cond.true:
167 // NORM-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
168 // NORM-NEXT: br label [[COND_END:%.*]]
169 // NORM: cond.false:
170 // NORM-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
171 // NORM-NEXT: br label [[COND_END]]
172 // NORM: cond.end:
173 // NORM-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
174 // NORM-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
175 // NORM-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
176 // NORM-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
177 // NORM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
178 // NORM: omp.inner.for.cond:
179 // NORM-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
180 // NORM-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
181 // NORM-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
182 // NORM-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
183 // NORM-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
184 // NORM: omp.inner.for.body:
185 // NORM-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
186 // NORM-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
187 // NORM-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
188 // NORM-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
189 // NORM-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
190 // NORM-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
191 // NORM-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
192 // NORM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
193 // NORM: omp.body.continue:
194 // NORM-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
195 // NORM: omp.inner.for.inc:
196 // NORM-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
197 // NORM-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
198 // NORM-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
199 // NORM-NEXT: br label [[OMP_INNER_FOR_COND]]
200 // NORM: omp.inner.for.end:
201 // NORM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
202 // NORM: omp.loop.exit:
203 // NORM-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
204 // NORM-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
205 // NORM-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
206 // NORM-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
207 // NORM-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
208 // NORM-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
209 // NORM-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
210 // NORM-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2:[0-9]+]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
211 // NORM-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
212 // NORM-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
213 // NORM-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
214 // NORM-NEXT: ]
215 // NORM: .omp.reduction.case1:
216 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
217 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
218 // NORM-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
219 // NORM-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
220 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
221 // NORM: .omp.reduction.case2:
222 // NORM-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
223 // NORM-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
224 // NORM-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
225 // NORM-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
226 // NORM-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
227 // NORM-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
228 // NORM-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
229 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
230 // NORM: .omp.reduction.default:
231 // NORM-NEXT: br label [[OMP_PRECOND_END]]
232 // NORM: omp.precond.end:
233 // NORM-NEXT: ret void
236 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.omp.reduction.reduction_func
237 // NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5:[0-9]+]] {
238 // NORM-NEXT: entry:
239 // NORM-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
240 // NORM-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
241 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
242 // NORM-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
243 // NORM-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
244 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
245 // NORM-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
246 // NORM-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
247 // NORM-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
248 // NORM-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
249 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
250 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
251 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
252 // NORM-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
253 // NORM-NEXT: ret void
256 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.1
257 // NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
258 // NORM-NEXT: entry:
259 // NORM-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
260 // NORM-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
261 // NORM-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
262 // NORM-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
263 // NORM-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
264 // NORM-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
265 // NORM-NEXT: [[TMP:%.*]] = alloca i32, align 4
266 // NORM-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
267 // NORM-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
268 // NORM-NEXT: [[I:%.*]] = alloca i32, align 4
269 // NORM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
270 // NORM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
271 // NORM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
272 // NORM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
273 // NORM-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
274 // NORM-NEXT: [[I4:%.*]] = alloca i32, align 4
275 // NORM-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
276 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
277 // NORM-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
278 // NORM-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
279 // NORM-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
280 // NORM-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
281 // NORM-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
282 // NORM-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
283 // NORM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
284 // NORM-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
285 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
286 // NORM-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
287 // NORM-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
288 // NORM-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
289 // NORM-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
290 // NORM-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
291 // NORM-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
292 // NORM-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
293 // NORM-NEXT: store i32 0, ptr [[I]], align 4
294 // NORM-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
295 // NORM-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
296 // NORM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
297 // NORM: omp.precond.then:
298 // NORM-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
299 // NORM-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
300 // NORM-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
301 // NORM-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
302 // NORM-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
303 // NORM-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
304 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
305 // NORM-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
306 // NORM-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
307 // NORM-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
308 // NORM-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
309 // NORM-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
310 // NORM-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
311 // NORM: cond.true:
312 // NORM-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
313 // NORM-NEXT: br label [[COND_END:%.*]]
314 // NORM: cond.false:
315 // NORM-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
316 // NORM-NEXT: br label [[COND_END]]
317 // NORM: cond.end:
318 // NORM-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
319 // NORM-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
320 // NORM-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
321 // NORM-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
322 // NORM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
323 // NORM: omp.inner.for.cond:
324 // NORM-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
325 // NORM-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
326 // NORM-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
327 // NORM-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
328 // NORM-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
329 // NORM: omp.inner.for.body:
330 // NORM-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
331 // NORM-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
332 // NORM-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
333 // NORM-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
334 // NORM-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
335 // NORM-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
336 // NORM-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
337 // NORM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
338 // NORM: omp.body.continue:
339 // NORM-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
340 // NORM: omp.inner.for.inc:
341 // NORM-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
342 // NORM-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
343 // NORM-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
344 // NORM-NEXT: br label [[OMP_INNER_FOR_COND]]
345 // NORM: omp.inner.for.end:
346 // NORM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
347 // NORM: omp.loop.exit:
348 // NORM-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
349 // NORM-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
350 // NORM-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
351 // NORM-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
352 // NORM-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
353 // NORM-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
354 // NORM-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
355 // NORM-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.1.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
356 // NORM-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
357 // NORM-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
358 // NORM-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
359 // NORM-NEXT: ]
360 // NORM: .omp.reduction.case1:
361 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
362 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
363 // NORM-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
364 // NORM-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
365 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
366 // NORM: .omp.reduction.case2:
367 // NORM-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
368 // NORM-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
369 // NORM-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
370 // NORM-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
371 // NORM-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
372 // NORM-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
373 // NORM-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
374 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
375 // NORM: .omp.reduction.default:
376 // NORM-NEXT: br label [[OMP_PRECOND_END]]
377 // NORM: omp.precond.end:
378 // NORM-NEXT: ret void
381 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.1.omp.reduction.reduction_func
382 // NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
383 // NORM-NEXT: entry:
384 // NORM-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
385 // NORM-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
386 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
387 // NORM-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
388 // NORM-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
389 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
390 // NORM-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
391 // NORM-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
392 // NORM-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
393 // NORM-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
394 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
395 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointplERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
396 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
397 // NORM-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
398 // NORM-NEXT: ret void
401 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.2
402 // NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
403 // NORM-NEXT: entry:
404 // NORM-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
405 // NORM-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
406 // NORM-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
407 // NORM-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
408 // NORM-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
409 // NORM-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
410 // NORM-NEXT: [[TMP:%.*]] = alloca i32, align 4
411 // NORM-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
412 // NORM-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
413 // NORM-NEXT: [[I:%.*]] = alloca i32, align 4
414 // NORM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
415 // NORM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
416 // NORM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
417 // NORM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
418 // NORM-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
419 // NORM-NEXT: [[I4:%.*]] = alloca i32, align 4
420 // NORM-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
421 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
422 // NORM-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
423 // NORM-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
424 // NORM-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
425 // NORM-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
426 // NORM-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
427 // NORM-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
428 // NORM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
429 // NORM-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
430 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
431 // NORM-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
432 // NORM-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
433 // NORM-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
434 // NORM-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
435 // NORM-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
436 // NORM-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
437 // NORM-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
438 // NORM-NEXT: store i32 0, ptr [[I]], align 4
439 // NORM-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
440 // NORM-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
441 // NORM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
442 // NORM: omp.precond.then:
443 // NORM-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
444 // NORM-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
445 // NORM-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
446 // NORM-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
447 // NORM-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
448 // NORM-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
449 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
450 // NORM-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
451 // NORM-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
452 // NORM-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
453 // NORM-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
454 // NORM-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
455 // NORM-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
456 // NORM: cond.true:
457 // NORM-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
458 // NORM-NEXT: br label [[COND_END:%.*]]
459 // NORM: cond.false:
460 // NORM-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
461 // NORM-NEXT: br label [[COND_END]]
462 // NORM: cond.end:
463 // NORM-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
464 // NORM-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
465 // NORM-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
466 // NORM-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
467 // NORM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
468 // NORM: omp.inner.for.cond:
469 // NORM-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
470 // NORM-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
471 // NORM-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
472 // NORM-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
473 // NORM-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
474 // NORM: omp.inner.for.body:
475 // NORM-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
476 // NORM-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
477 // NORM-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
478 // NORM-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
479 // NORM-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
480 // NORM-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
481 // NORM-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
482 // NORM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
483 // NORM: omp.body.continue:
484 // NORM-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
485 // NORM: omp.inner.for.inc:
486 // NORM-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
487 // NORM-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
488 // NORM-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
489 // NORM-NEXT: br label [[OMP_INNER_FOR_COND]]
490 // NORM: omp.inner.for.end:
491 // NORM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
492 // NORM: omp.loop.exit:
493 // NORM-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
494 // NORM-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
495 // NORM-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
496 // NORM-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
497 // NORM-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
498 // NORM-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
499 // NORM-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
500 // NORM-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.2.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
501 // NORM-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
502 // NORM-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
503 // NORM-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
504 // NORM-NEXT: ]
505 // NORM: .omp.reduction.case1:
506 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointmlERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
507 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
508 // NORM-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
509 // NORM-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
510 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
511 // NORM: .omp.reduction.case2:
512 // NORM-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
513 // NORM-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
514 // NORM-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
515 // NORM-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointmlERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
516 // NORM-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
517 // NORM-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
518 // NORM-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
519 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
520 // NORM: .omp.reduction.default:
521 // NORM-NEXT: br label [[OMP_PRECOND_END]]
522 // NORM: omp.precond.end:
523 // NORM-NEXT: ret void
526 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.2.omp.reduction.reduction_func
527 // NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
528 // NORM-NEXT: entry:
529 // NORM-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
530 // NORM-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
531 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
532 // NORM-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
533 // NORM-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
534 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
535 // NORM-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
536 // NORM-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
537 // NORM-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
538 // NORM-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
539 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
540 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointmlERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
541 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
542 // NORM-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
543 // NORM-NEXT: ret void
546 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.3
547 // NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
548 // NORM-NEXT: entry:
549 // NORM-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
550 // NORM-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
551 // NORM-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
552 // NORM-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
553 // NORM-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
554 // NORM-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
555 // NORM-NEXT: [[TMP:%.*]] = alloca i32, align 4
556 // NORM-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
557 // NORM-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
558 // NORM-NEXT: [[I:%.*]] = alloca i32, align 4
559 // NORM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
560 // NORM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
561 // NORM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
562 // NORM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
563 // NORM-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
564 // NORM-NEXT: [[I4:%.*]] = alloca i32, align 4
565 // NORM-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
566 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
567 // NORM-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
568 // NORM-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
569 // NORM-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
570 // NORM-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
571 // NORM-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
572 // NORM-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
573 // NORM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
574 // NORM-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
575 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
576 // NORM-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
577 // NORM-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
578 // NORM-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
579 // NORM-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
580 // NORM-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
581 // NORM-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
582 // NORM-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
583 // NORM-NEXT: store i32 0, ptr [[I]], align 4
584 // NORM-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
585 // NORM-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
586 // NORM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
587 // NORM: omp.precond.then:
588 // NORM-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
589 // NORM-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
590 // NORM-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
591 // NORM-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
592 // NORM-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
593 // NORM-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
594 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
595 // NORM-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
596 // NORM-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
597 // NORM-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
598 // NORM-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
599 // NORM-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
600 // NORM-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
601 // NORM: cond.true:
602 // NORM-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
603 // NORM-NEXT: br label [[COND_END:%.*]]
604 // NORM: cond.false:
605 // NORM-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
606 // NORM-NEXT: br label [[COND_END]]
607 // NORM: cond.end:
608 // NORM-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
609 // NORM-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
610 // NORM-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
611 // NORM-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
612 // NORM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
613 // NORM: omp.inner.for.cond:
614 // NORM-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
615 // NORM-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
616 // NORM-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
617 // NORM-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
618 // NORM-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
619 // NORM: omp.inner.for.body:
620 // NORM-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
621 // NORM-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
622 // NORM-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
623 // NORM-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
624 // NORM-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
625 // NORM-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
626 // NORM-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
627 // NORM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
628 // NORM: omp.body.continue:
629 // NORM-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
630 // NORM: omp.inner.for.inc:
631 // NORM-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
632 // NORM-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
633 // NORM-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
634 // NORM-NEXT: br label [[OMP_INNER_FOR_COND]]
635 // NORM: omp.inner.for.end:
636 // NORM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
637 // NORM: omp.loop.exit:
638 // NORM-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
639 // NORM-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
640 // NORM-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
641 // NORM-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
642 // NORM-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
643 // NORM-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
644 // NORM-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
645 // NORM-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.3.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
646 // NORM-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
647 // NORM-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
648 // NORM-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
649 // NORM-NEXT: ]
650 // NORM: .omp.reduction.case1:
651 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointanERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
652 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
653 // NORM-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
654 // NORM-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
655 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
656 // NORM: .omp.reduction.case2:
657 // NORM-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
658 // NORM-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
659 // NORM-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
660 // NORM-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointanERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
661 // NORM-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
662 // NORM-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
663 // NORM-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
664 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
665 // NORM: .omp.reduction.default:
666 // NORM-NEXT: br label [[OMP_PRECOND_END]]
667 // NORM: omp.precond.end:
668 // NORM-NEXT: ret void
671 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.3.omp.reduction.reduction_func
672 // NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
673 // NORM-NEXT: entry:
674 // NORM-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
675 // NORM-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
676 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
677 // NORM-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
678 // NORM-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
679 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
680 // NORM-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
681 // NORM-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
682 // NORM-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
683 // NORM-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
684 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
685 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointanERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
686 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
687 // NORM-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
688 // NORM-NEXT: ret void
691 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.4
692 // NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
693 // NORM-NEXT: entry:
694 // NORM-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
695 // NORM-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
696 // NORM-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
697 // NORM-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
698 // NORM-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
699 // NORM-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
700 // NORM-NEXT: [[TMP:%.*]] = alloca i32, align 4
701 // NORM-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
702 // NORM-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
703 // NORM-NEXT: [[I:%.*]] = alloca i32, align 4
704 // NORM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
705 // NORM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
706 // NORM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
707 // NORM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
708 // NORM-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
709 // NORM-NEXT: [[I4:%.*]] = alloca i32, align 4
710 // NORM-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
711 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
712 // NORM-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
713 // NORM-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
714 // NORM-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
715 // NORM-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
716 // NORM-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
717 // NORM-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
718 // NORM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
719 // NORM-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
720 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
721 // NORM-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
722 // NORM-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
723 // NORM-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
724 // NORM-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
725 // NORM-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
726 // NORM-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
727 // NORM-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
728 // NORM-NEXT: store i32 0, ptr [[I]], align 4
729 // NORM-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
730 // NORM-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
731 // NORM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
732 // NORM: omp.precond.then:
733 // NORM-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
734 // NORM-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
735 // NORM-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
736 // NORM-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
737 // NORM-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
738 // NORM-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
739 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
740 // NORM-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
741 // NORM-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
742 // NORM-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
743 // NORM-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
744 // NORM-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
745 // NORM-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
746 // NORM: cond.true:
747 // NORM-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
748 // NORM-NEXT: br label [[COND_END:%.*]]
749 // NORM: cond.false:
750 // NORM-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
751 // NORM-NEXT: br label [[COND_END]]
752 // NORM: cond.end:
753 // NORM-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
754 // NORM-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
755 // NORM-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
756 // NORM-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
757 // NORM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
758 // NORM: omp.inner.for.cond:
759 // NORM-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
760 // NORM-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
761 // NORM-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
762 // NORM-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
763 // NORM-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
764 // NORM: omp.inner.for.body:
765 // NORM-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
766 // NORM-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
767 // NORM-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
768 // NORM-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
769 // NORM-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
770 // NORM-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
771 // NORM-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
772 // NORM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
773 // NORM: omp.body.continue:
774 // NORM-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
775 // NORM: omp.inner.for.inc:
776 // NORM-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
777 // NORM-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
778 // NORM-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
779 // NORM-NEXT: br label [[OMP_INNER_FOR_COND]]
780 // NORM: omp.inner.for.end:
781 // NORM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
782 // NORM: omp.loop.exit:
783 // NORM-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
784 // NORM-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
785 // NORM-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
786 // NORM-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
787 // NORM-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
788 // NORM-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
789 // NORM-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
790 // NORM-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.4.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
791 // NORM-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
792 // NORM-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
793 // NORM-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
794 // NORM-NEXT: ]
795 // NORM: .omp.reduction.case1:
796 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointorERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
797 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
798 // NORM-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
799 // NORM-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
800 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
801 // NORM: .omp.reduction.case2:
802 // NORM-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
803 // NORM-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
804 // NORM-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
805 // NORM-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointorERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
806 // NORM-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
807 // NORM-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
808 // NORM-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
809 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
810 // NORM: .omp.reduction.default:
811 // NORM-NEXT: br label [[OMP_PRECOND_END]]
812 // NORM: omp.precond.end:
813 // NORM-NEXT: ret void
816 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.4.omp.reduction.reduction_func
817 // NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
818 // NORM-NEXT: entry:
819 // NORM-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
820 // NORM-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
821 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
822 // NORM-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
823 // NORM-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
824 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
825 // NORM-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
826 // NORM-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
827 // NORM-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
828 // NORM-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
829 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
830 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointorERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
831 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
832 // NORM-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
833 // NORM-NEXT: ret void
836 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.5
837 // NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
838 // NORM-NEXT: entry:
839 // NORM-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
840 // NORM-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
841 // NORM-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
842 // NORM-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
843 // NORM-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
844 // NORM-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
845 // NORM-NEXT: [[TMP:%.*]] = alloca i32, align 4
846 // NORM-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
847 // NORM-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
848 // NORM-NEXT: [[I:%.*]] = alloca i32, align 4
849 // NORM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
850 // NORM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
851 // NORM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
852 // NORM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
853 // NORM-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
854 // NORM-NEXT: [[I4:%.*]] = alloca i32, align 4
855 // NORM-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
856 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
857 // NORM-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
858 // NORM-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
859 // NORM-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
860 // NORM-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
861 // NORM-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
862 // NORM-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
863 // NORM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
864 // NORM-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
865 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
866 // NORM-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
867 // NORM-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
868 // NORM-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
869 // NORM-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
870 // NORM-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
871 // NORM-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
872 // NORM-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
873 // NORM-NEXT: store i32 0, ptr [[I]], align 4
874 // NORM-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
875 // NORM-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
876 // NORM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
877 // NORM: omp.precond.then:
878 // NORM-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
879 // NORM-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
880 // NORM-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
881 // NORM-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
882 // NORM-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
883 // NORM-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
884 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
885 // NORM-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
886 // NORM-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
887 // NORM-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
888 // NORM-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
889 // NORM-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
890 // NORM-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
891 // NORM: cond.true:
892 // NORM-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
893 // NORM-NEXT: br label [[COND_END:%.*]]
894 // NORM: cond.false:
895 // NORM-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
896 // NORM-NEXT: br label [[COND_END]]
897 // NORM: cond.end:
898 // NORM-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
899 // NORM-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
900 // NORM-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
901 // NORM-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
902 // NORM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
903 // NORM: omp.inner.for.cond:
904 // NORM-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
905 // NORM-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
906 // NORM-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
907 // NORM-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
908 // NORM-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
909 // NORM: omp.inner.for.body:
910 // NORM-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
911 // NORM-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
912 // NORM-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
913 // NORM-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
914 // NORM-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
915 // NORM-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
916 // NORM-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
917 // NORM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
918 // NORM: omp.body.continue:
919 // NORM-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
920 // NORM: omp.inner.for.inc:
921 // NORM-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
922 // NORM-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
923 // NORM-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
924 // NORM-NEXT: br label [[OMP_INNER_FOR_COND]]
925 // NORM: omp.inner.for.end:
926 // NORM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
927 // NORM: omp.loop.exit:
928 // NORM-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
929 // NORM-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
930 // NORM-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
931 // NORM-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
932 // NORM-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
933 // NORM-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
934 // NORM-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
935 // NORM-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.5.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
936 // NORM-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
937 // NORM-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
938 // NORM-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
939 // NORM-NEXT: ]
940 // NORM: .omp.reduction.case1:
941 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointeoERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
942 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
943 // NORM-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
944 // NORM-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
945 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
946 // NORM: .omp.reduction.case2:
947 // NORM-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
948 // NORM-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
949 // NORM-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
950 // NORM-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointeoERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
951 // NORM-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
952 // NORM-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
953 // NORM-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
954 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
955 // NORM: .omp.reduction.default:
956 // NORM-NEXT: br label [[OMP_PRECOND_END]]
957 // NORM: omp.precond.end:
958 // NORM-NEXT: ret void
961 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.5.omp.reduction.reduction_func
962 // NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
963 // NORM-NEXT: entry:
964 // NORM-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
965 // NORM-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
966 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
967 // NORM-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
968 // NORM-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
969 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
970 // NORM-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
971 // NORM-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
972 // NORM-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
973 // NORM-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
974 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
975 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointeoERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
976 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
977 // NORM-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
978 // NORM-NEXT: ret void
981 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.6
982 // NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
983 // NORM-NEXT: entry:
984 // NORM-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
985 // NORM-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
986 // NORM-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
987 // NORM-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
988 // NORM-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
989 // NORM-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
990 // NORM-NEXT: [[TMP:%.*]] = alloca i32, align 4
991 // NORM-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
992 // NORM-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
993 // NORM-NEXT: [[I:%.*]] = alloca i32, align 4
994 // NORM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
995 // NORM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
996 // NORM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
997 // NORM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
998 // NORM-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
999 // NORM-NEXT: [[I4:%.*]] = alloca i32, align 4
1000 // NORM-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
1001 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
1002 // NORM-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
1003 // NORM-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
1004 // NORM-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
1005 // NORM-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
1006 // NORM-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
1007 // NORM-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
1008 // NORM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
1009 // NORM-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
1010 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
1011 // NORM-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
1012 // NORM-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
1013 // NORM-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1014 // NORM-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
1015 // NORM-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
1016 // NORM-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
1017 // NORM-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
1018 // NORM-NEXT: store i32 0, ptr [[I]], align 4
1019 // NORM-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1020 // NORM-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
1021 // NORM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
1022 // NORM: omp.precond.then:
1023 // NORM-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
1024 // NORM-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1025 // NORM-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
1026 // NORM-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
1027 // NORM-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
1028 // NORM-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
1029 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1030 // NORM-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
1031 // NORM-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
1032 // NORM-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1033 // NORM-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1034 // NORM-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
1035 // NORM-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
1036 // NORM: cond.true:
1037 // NORM-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1038 // NORM-NEXT: br label [[COND_END:%.*]]
1039 // NORM: cond.false:
1040 // NORM-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1041 // NORM-NEXT: br label [[COND_END]]
1042 // NORM: cond.end:
1043 // NORM-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
1044 // NORM-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
1045 // NORM-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
1046 // NORM-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
1047 // NORM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
1048 // NORM: omp.inner.for.cond:
1049 // NORM-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1050 // NORM-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1051 // NORM-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
1052 // NORM-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
1053 // NORM-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
1054 // NORM: omp.inner.for.body:
1055 // NORM-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1056 // NORM-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
1057 // NORM-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
1058 // NORM-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
1059 // NORM-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
1060 // NORM-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
1061 // NORM-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
1062 // NORM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
1063 // NORM: omp.body.continue:
1064 // NORM-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
1065 // NORM: omp.inner.for.inc:
1066 // NORM-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1067 // NORM-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
1068 // NORM-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
1069 // NORM-NEXT: br label [[OMP_INNER_FOR_COND]]
1070 // NORM: omp.inner.for.end:
1071 // NORM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
1072 // NORM: omp.loop.exit:
1073 // NORM-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1074 // NORM-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
1075 // NORM-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
1076 // NORM-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
1077 // NORM-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
1078 // NORM-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1079 // NORM-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
1080 // NORM-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.6.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
1081 // NORM-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
1082 // NORM-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
1083 // NORM-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
1084 // NORM-NEXT: ]
1085 // NORM: .omp.reduction.case1:
1086 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1087 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
1088 // NORM-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
1089 // NORM-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
1090 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1091 // NORM: .omp.reduction.case2:
1092 // NORM-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1093 // NORM-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
1094 // NORM-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1095 // NORM-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1096 // NORM-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
1097 // NORM-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
1098 // NORM-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1099 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1100 // NORM: .omp.reduction.default:
1101 // NORM-NEXT: br label [[OMP_PRECOND_END]]
1102 // NORM: omp.precond.end:
1103 // NORM-NEXT: ret void
1106 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.6.omp.reduction.reduction_func
1107 // NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
1108 // NORM-NEXT: entry:
1109 // NORM-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
1110 // NORM-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
1111 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
1112 // NORM-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
1113 // NORM-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
1114 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
1115 // NORM-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
1116 // NORM-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
1117 // NORM-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
1118 // NORM-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
1119 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
1120 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
1121 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
1122 // NORM-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
1123 // NORM-NEXT: ret void
1126 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.7
1127 // NORM-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
1128 // NORM-NEXT: entry:
1129 // NORM-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
1130 // NORM-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
1131 // NORM-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
1132 // NORM-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
1133 // NORM-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
1134 // NORM-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
1135 // NORM-NEXT: [[TMP:%.*]] = alloca i32, align 4
1136 // NORM-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
1137 // NORM-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
1138 // NORM-NEXT: [[I:%.*]] = alloca i32, align 4
1139 // NORM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
1140 // NORM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
1141 // NORM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
1142 // NORM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
1143 // NORM-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
1144 // NORM-NEXT: [[I4:%.*]] = alloca i32, align 4
1145 // NORM-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
1146 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
1147 // NORM-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
1148 // NORM-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
1149 // NORM-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
1150 // NORM-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
1151 // NORM-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
1152 // NORM-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
1153 // NORM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
1154 // NORM-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
1155 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
1156 // NORM-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
1157 // NORM-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
1158 // NORM-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1159 // NORM-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
1160 // NORM-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
1161 // NORM-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
1162 // NORM-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
1163 // NORM-NEXT: store i32 0, ptr [[I]], align 4
1164 // NORM-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1165 // NORM-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
1166 // NORM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
1167 // NORM: omp.precond.then:
1168 // NORM-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
1169 // NORM-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1170 // NORM-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
1171 // NORM-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
1172 // NORM-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
1173 // NORM-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
1174 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1175 // NORM-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
1176 // NORM-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
1177 // NORM-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1178 // NORM-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1179 // NORM-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
1180 // NORM-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
1181 // NORM: cond.true:
1182 // NORM-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1183 // NORM-NEXT: br label [[COND_END:%.*]]
1184 // NORM: cond.false:
1185 // NORM-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1186 // NORM-NEXT: br label [[COND_END]]
1187 // NORM: cond.end:
1188 // NORM-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
1189 // NORM-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
1190 // NORM-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
1191 // NORM-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
1192 // NORM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
1193 // NORM: omp.inner.for.cond:
1194 // NORM-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1195 // NORM-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1196 // NORM-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
1197 // NORM-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
1198 // NORM-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
1199 // NORM: omp.inner.for.body:
1200 // NORM-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1201 // NORM-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
1202 // NORM-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
1203 // NORM-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
1204 // NORM-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
1205 // NORM-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
1206 // NORM-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
1207 // NORM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
1208 // NORM: omp.body.continue:
1209 // NORM-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
1210 // NORM: omp.inner.for.inc:
1211 // NORM-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1212 // NORM-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
1213 // NORM-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
1214 // NORM-NEXT: br label [[OMP_INNER_FOR_COND]]
1215 // NORM: omp.inner.for.end:
1216 // NORM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
1217 // NORM: omp.loop.exit:
1218 // NORM-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1219 // NORM-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
1220 // NORM-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
1221 // NORM-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
1222 // NORM-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
1223 // NORM-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1224 // NORM-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
1225 // NORM-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.7.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
1226 // NORM-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
1227 // NORM-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
1228 // NORM-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
1229 // NORM-NEXT: ]
1230 // NORM: .omp.reduction.case1:
1231 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1232 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
1233 // NORM-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
1234 // NORM-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
1235 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1236 // NORM: .omp.reduction.case2:
1237 // NORM-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1238 // NORM-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
1239 // NORM-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1240 // NORM-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1241 // NORM-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
1242 // NORM-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
1243 // NORM-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1244 // NORM-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1245 // NORM: .omp.reduction.default:
1246 // NORM-NEXT: br label [[OMP_PRECOND_END]]
1247 // NORM: omp.precond.end:
1248 // NORM-NEXT: ret void
1251 // NORM-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.7.omp.reduction.reduction_func
1252 // NORM-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
1253 // NORM-NEXT: entry:
1254 // NORM-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
1255 // NORM-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
1256 // NORM-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
1257 // NORM-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
1258 // NORM-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
1259 // NORM-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
1260 // NORM-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
1261 // NORM-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
1262 // NORM-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
1263 // NORM-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
1264 // NORM-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
1265 // NORM-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
1266 // NORM-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
1267 // NORM-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
1268 // NORM-NEXT: ret void
1271 // NORM-LABEL: define {{[^@]+}}@_ZN5PointC2Ev
1272 // NORM-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 {
1273 // NORM-NEXT: entry:
1274 // NORM-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8
1275 // NORM-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1276 // NORM-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1277 // NORM-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_POINT:%.*]], ptr [[THIS1]], i32 0, i32 0
1278 // NORM-NEXT: store i32 0, ptr [[X]], align 4
1279 // NORM-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_POINT]], ptr [[THIS1]], i32 0, i32 1
1280 // NORM-NEXT: store i32 0, ptr [[Y]], align 4
1281 // NORM-NEXT: ret void
1284 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point
1285 // COMP-SAME: (i32 [[N:%.*]], ptr [[POINTS:%.*]]) #[[ATTR0:[0-9]+]] {
1286 // COMP-NEXT: entry:
1287 // COMP-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4
1288 // COMP-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
1289 // COMP-NEXT: [[RED:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
1290 // COMP-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4
1291 // COMP-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
1292 // COMP-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED]]) #[[ATTR3:[0-9]+]]
1293 // COMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3:[0-9]+]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
1294 // COMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.1, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
1295 // COMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.2, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
1296 // COMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.3, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
1297 // COMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.4, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
1298 // COMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.5, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
1299 // COMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.6, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
1300 // COMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @_Z3fooiPK5Point.omp_outlined.7, ptr [[N_ADDR]], ptr [[RED]], ptr [[POINTS_ADDR]])
1301 // COMP-NEXT: ret void
1304 // COMP-LABEL: define {{[^@]+}}@_ZN5PointC1Ev
1305 // COMP-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 {
1306 // COMP-NEXT: entry:
1307 // COMP-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8
1308 // COMP-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
1309 // COMP-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
1310 // COMP-NEXT: call void @_ZN5PointC2Ev(ptr nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR3]]
1311 // COMP-NEXT: ret void
1314 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined
1315 // COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2:[0-9]+]] {
1316 // COMP-NEXT: entry:
1317 // COMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
1318 // COMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
1319 // COMP-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
1320 // COMP-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
1321 // COMP-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
1322 // COMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
1323 // COMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
1324 // COMP-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
1325 // COMP-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
1326 // COMP-NEXT: [[I:%.*]] = alloca i32, align 4
1327 // COMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
1328 // COMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
1329 // COMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
1330 // COMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
1331 // COMP-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
1332 // COMP-NEXT: [[I4:%.*]] = alloca i32, align 4
1333 // COMP-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
1334 // COMP-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
1335 // COMP-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
1336 // COMP-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
1337 // COMP-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
1338 // COMP-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
1339 // COMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
1340 // COMP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
1341 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
1342 // COMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
1343 // COMP-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
1344 // COMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1345 // COMP-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
1346 // COMP-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
1347 // COMP-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
1348 // COMP-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
1349 // COMP-NEXT: store i32 0, ptr [[I]], align 4
1350 // COMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1351 // COMP-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
1352 // COMP-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
1353 // COMP: omp.precond.then:
1354 // COMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
1355 // COMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1356 // COMP-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
1357 // COMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
1358 // COMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
1359 // COMP-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
1360 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1361 // COMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
1362 // COMP-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1:[0-9]+]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
1363 // COMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1364 // COMP-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1365 // COMP-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
1366 // COMP-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
1367 // COMP: cond.true:
1368 // COMP-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1369 // COMP-NEXT: br label [[COND_END:%.*]]
1370 // COMP: cond.false:
1371 // COMP-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1372 // COMP-NEXT: br label [[COND_END]]
1373 // COMP: cond.end:
1374 // COMP-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
1375 // COMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
1376 // COMP-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
1377 // COMP-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
1378 // COMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
1379 // COMP: omp.inner.for.cond:
1380 // COMP-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1381 // COMP-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1382 // COMP-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
1383 // COMP-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
1384 // COMP-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
1385 // COMP: omp.inner.for.body:
1386 // COMP-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1387 // COMP-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
1388 // COMP-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
1389 // COMP-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
1390 // COMP-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
1391 // COMP-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
1392 // COMP-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
1393 // COMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
1394 // COMP: omp.body.continue:
1395 // COMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
1396 // COMP: omp.inner.for.inc:
1397 // COMP-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1398 // COMP-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
1399 // COMP-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
1400 // COMP-NEXT: br label [[OMP_INNER_FOR_COND]]
1401 // COMP: omp.inner.for.end:
1402 // COMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
1403 // COMP: omp.loop.exit:
1404 // COMP-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1405 // COMP-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
1406 // COMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
1407 // COMP-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
1408 // COMP-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
1409 // COMP-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1410 // COMP-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
1411 // COMP-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2:[0-9]+]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
1412 // COMP-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
1413 // COMP-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
1414 // COMP-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
1415 // COMP-NEXT: ]
1416 // COMP: .omp.reduction.case1:
1417 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1418 // COMP-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
1419 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1420 // COMP: .omp.reduction.case2:
1421 // COMP-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1422 // COMP-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
1423 // COMP-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1424 // COMP-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1425 // COMP-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1426 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1427 // COMP: .omp.reduction.default:
1428 // COMP-NEXT: br label [[OMP_PRECOND_END]]
1429 // COMP: omp.precond.end:
1430 // COMP-NEXT: ret void
1433 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.omp.reduction.reduction_func
1434 // COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5:[0-9]+]] {
1435 // COMP-NEXT: entry:
1436 // COMP-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
1437 // COMP-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
1438 // COMP-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
1439 // COMP-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
1440 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
1441 // COMP-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
1442 // COMP-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
1443 // COMP-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
1444 // COMP-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
1445 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
1446 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
1447 // COMP-NEXT: ret void
1450 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.1
1451 // COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
1452 // COMP-NEXT: entry:
1453 // COMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
1454 // COMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
1455 // COMP-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
1456 // COMP-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
1457 // COMP-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
1458 // COMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
1459 // COMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
1460 // COMP-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
1461 // COMP-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
1462 // COMP-NEXT: [[I:%.*]] = alloca i32, align 4
1463 // COMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
1464 // COMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
1465 // COMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
1466 // COMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
1467 // COMP-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
1468 // COMP-NEXT: [[I4:%.*]] = alloca i32, align 4
1469 // COMP-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
1470 // COMP-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
1471 // COMP-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
1472 // COMP-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
1473 // COMP-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
1474 // COMP-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
1475 // COMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
1476 // COMP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
1477 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
1478 // COMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
1479 // COMP-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
1480 // COMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1481 // COMP-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
1482 // COMP-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
1483 // COMP-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
1484 // COMP-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
1485 // COMP-NEXT: store i32 0, ptr [[I]], align 4
1486 // COMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1487 // COMP-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
1488 // COMP-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
1489 // COMP: omp.precond.then:
1490 // COMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
1491 // COMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1492 // COMP-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
1493 // COMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
1494 // COMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
1495 // COMP-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
1496 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1497 // COMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
1498 // COMP-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
1499 // COMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1500 // COMP-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1501 // COMP-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
1502 // COMP-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
1503 // COMP: cond.true:
1504 // COMP-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1505 // COMP-NEXT: br label [[COND_END:%.*]]
1506 // COMP: cond.false:
1507 // COMP-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1508 // COMP-NEXT: br label [[COND_END]]
1509 // COMP: cond.end:
1510 // COMP-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
1511 // COMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
1512 // COMP-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
1513 // COMP-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
1514 // COMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
1515 // COMP: omp.inner.for.cond:
1516 // COMP-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1517 // COMP-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1518 // COMP-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
1519 // COMP-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
1520 // COMP-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
1521 // COMP: omp.inner.for.body:
1522 // COMP-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1523 // COMP-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
1524 // COMP-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
1525 // COMP-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
1526 // COMP-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
1527 // COMP-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
1528 // COMP-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
1529 // COMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
1530 // COMP: omp.body.continue:
1531 // COMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
1532 // COMP: omp.inner.for.inc:
1533 // COMP-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1534 // COMP-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
1535 // COMP-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
1536 // COMP-NEXT: br label [[OMP_INNER_FOR_COND]]
1537 // COMP: omp.inner.for.end:
1538 // COMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
1539 // COMP: omp.loop.exit:
1540 // COMP-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1541 // COMP-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
1542 // COMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
1543 // COMP-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
1544 // COMP-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
1545 // COMP-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1546 // COMP-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
1547 // COMP-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.1.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
1548 // COMP-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
1549 // COMP-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
1550 // COMP-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
1551 // COMP-NEXT: ]
1552 // COMP: .omp.reduction.case1:
1553 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1554 // COMP-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
1555 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1556 // COMP: .omp.reduction.case2:
1557 // COMP-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1558 // COMP-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
1559 // COMP-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1560 // COMP-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1561 // COMP-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1562 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1563 // COMP: .omp.reduction.default:
1564 // COMP-NEXT: br label [[OMP_PRECOND_END]]
1565 // COMP: omp.precond.end:
1566 // COMP-NEXT: ret void
1569 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.1.omp.reduction.reduction_func
1570 // COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
1571 // COMP-NEXT: entry:
1572 // COMP-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
1573 // COMP-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
1574 // COMP-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
1575 // COMP-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
1576 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
1577 // COMP-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
1578 // COMP-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
1579 // COMP-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
1580 // COMP-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
1581 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
1582 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointpLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
1583 // COMP-NEXT: ret void
1586 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.2
1587 // COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
1588 // COMP-NEXT: entry:
1589 // COMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
1590 // COMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
1591 // COMP-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
1592 // COMP-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
1593 // COMP-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
1594 // COMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
1595 // COMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
1596 // COMP-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
1597 // COMP-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
1598 // COMP-NEXT: [[I:%.*]] = alloca i32, align 4
1599 // COMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
1600 // COMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
1601 // COMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
1602 // COMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
1603 // COMP-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
1604 // COMP-NEXT: [[I4:%.*]] = alloca i32, align 4
1605 // COMP-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
1606 // COMP-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
1607 // COMP-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
1608 // COMP-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
1609 // COMP-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
1610 // COMP-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
1611 // COMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
1612 // COMP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
1613 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
1614 // COMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
1615 // COMP-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
1616 // COMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1617 // COMP-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
1618 // COMP-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
1619 // COMP-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
1620 // COMP-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
1621 // COMP-NEXT: store i32 0, ptr [[I]], align 4
1622 // COMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1623 // COMP-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
1624 // COMP-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
1625 // COMP: omp.precond.then:
1626 // COMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
1627 // COMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1628 // COMP-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
1629 // COMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
1630 // COMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
1631 // COMP-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
1632 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1633 // COMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
1634 // COMP-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
1635 // COMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1636 // COMP-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1637 // COMP-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
1638 // COMP-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
1639 // COMP: cond.true:
1640 // COMP-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1641 // COMP-NEXT: br label [[COND_END:%.*]]
1642 // COMP: cond.false:
1643 // COMP-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1644 // COMP-NEXT: br label [[COND_END]]
1645 // COMP: cond.end:
1646 // COMP-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
1647 // COMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
1648 // COMP-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
1649 // COMP-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
1650 // COMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
1651 // COMP: omp.inner.for.cond:
1652 // COMP-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1653 // COMP-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1654 // COMP-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
1655 // COMP-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
1656 // COMP-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
1657 // COMP: omp.inner.for.body:
1658 // COMP-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1659 // COMP-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
1660 // COMP-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
1661 // COMP-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
1662 // COMP-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
1663 // COMP-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
1664 // COMP-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
1665 // COMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
1666 // COMP: omp.body.continue:
1667 // COMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
1668 // COMP: omp.inner.for.inc:
1669 // COMP-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1670 // COMP-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
1671 // COMP-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
1672 // COMP-NEXT: br label [[OMP_INNER_FOR_COND]]
1673 // COMP: omp.inner.for.end:
1674 // COMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
1675 // COMP: omp.loop.exit:
1676 // COMP-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1677 // COMP-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
1678 // COMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
1679 // COMP-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
1680 // COMP-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
1681 // COMP-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1682 // COMP-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
1683 // COMP-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.2.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
1684 // COMP-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
1685 // COMP-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
1686 // COMP-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
1687 // COMP-NEXT: ]
1688 // COMP: .omp.reduction.case1:
1689 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointmLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1690 // COMP-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
1691 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1692 // COMP: .omp.reduction.case2:
1693 // COMP-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1694 // COMP-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
1695 // COMP-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1696 // COMP-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointmLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1697 // COMP-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1698 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1699 // COMP: .omp.reduction.default:
1700 // COMP-NEXT: br label [[OMP_PRECOND_END]]
1701 // COMP: omp.precond.end:
1702 // COMP-NEXT: ret void
1705 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.2.omp.reduction.reduction_func
1706 // COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
1707 // COMP-NEXT: entry:
1708 // COMP-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
1709 // COMP-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
1710 // COMP-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
1711 // COMP-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
1712 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
1713 // COMP-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
1714 // COMP-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
1715 // COMP-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
1716 // COMP-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
1717 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
1718 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointmLERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
1719 // COMP-NEXT: ret void
1722 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.3
1723 // COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
1724 // COMP-NEXT: entry:
1725 // COMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
1726 // COMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
1727 // COMP-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
1728 // COMP-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
1729 // COMP-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
1730 // COMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
1731 // COMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
1732 // COMP-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
1733 // COMP-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
1734 // COMP-NEXT: [[I:%.*]] = alloca i32, align 4
1735 // COMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
1736 // COMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
1737 // COMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
1738 // COMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
1739 // COMP-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
1740 // COMP-NEXT: [[I4:%.*]] = alloca i32, align 4
1741 // COMP-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
1742 // COMP-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
1743 // COMP-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
1744 // COMP-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
1745 // COMP-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
1746 // COMP-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
1747 // COMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
1748 // COMP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
1749 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
1750 // COMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
1751 // COMP-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
1752 // COMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1753 // COMP-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
1754 // COMP-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
1755 // COMP-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
1756 // COMP-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
1757 // COMP-NEXT: store i32 0, ptr [[I]], align 4
1758 // COMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1759 // COMP-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
1760 // COMP-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
1761 // COMP: omp.precond.then:
1762 // COMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
1763 // COMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1764 // COMP-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
1765 // COMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
1766 // COMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
1767 // COMP-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
1768 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1769 // COMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
1770 // COMP-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
1771 // COMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1772 // COMP-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1773 // COMP-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
1774 // COMP-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
1775 // COMP: cond.true:
1776 // COMP-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1777 // COMP-NEXT: br label [[COND_END:%.*]]
1778 // COMP: cond.false:
1779 // COMP-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1780 // COMP-NEXT: br label [[COND_END]]
1781 // COMP: cond.end:
1782 // COMP-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
1783 // COMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
1784 // COMP-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
1785 // COMP-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
1786 // COMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
1787 // COMP: omp.inner.for.cond:
1788 // COMP-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1789 // COMP-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1790 // COMP-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
1791 // COMP-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
1792 // COMP-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
1793 // COMP: omp.inner.for.body:
1794 // COMP-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1795 // COMP-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
1796 // COMP-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
1797 // COMP-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
1798 // COMP-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
1799 // COMP-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
1800 // COMP-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
1801 // COMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
1802 // COMP: omp.body.continue:
1803 // COMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
1804 // COMP: omp.inner.for.inc:
1805 // COMP-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1806 // COMP-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
1807 // COMP-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
1808 // COMP-NEXT: br label [[OMP_INNER_FOR_COND]]
1809 // COMP: omp.inner.for.end:
1810 // COMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
1811 // COMP: omp.loop.exit:
1812 // COMP-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1813 // COMP-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
1814 // COMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
1815 // COMP-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
1816 // COMP-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
1817 // COMP-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1818 // COMP-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
1819 // COMP-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.3.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
1820 // COMP-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
1821 // COMP-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
1822 // COMP-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
1823 // COMP-NEXT: ]
1824 // COMP: .omp.reduction.case1:
1825 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaNERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1826 // COMP-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
1827 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1828 // COMP: .omp.reduction.case2:
1829 // COMP-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1830 // COMP-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
1831 // COMP-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1832 // COMP-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaNERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1833 // COMP-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1834 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1835 // COMP: .omp.reduction.default:
1836 // COMP-NEXT: br label [[OMP_PRECOND_END]]
1837 // COMP: omp.precond.end:
1838 // COMP-NEXT: ret void
1841 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.3.omp.reduction.reduction_func
1842 // COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
1843 // COMP-NEXT: entry:
1844 // COMP-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
1845 // COMP-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
1846 // COMP-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
1847 // COMP-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
1848 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
1849 // COMP-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
1850 // COMP-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
1851 // COMP-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
1852 // COMP-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
1853 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
1854 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaNERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
1855 // COMP-NEXT: ret void
1858 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.4
1859 // COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
1860 // COMP-NEXT: entry:
1861 // COMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
1862 // COMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
1863 // COMP-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
1864 // COMP-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
1865 // COMP-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
1866 // COMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
1867 // COMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
1868 // COMP-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
1869 // COMP-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
1870 // COMP-NEXT: [[I:%.*]] = alloca i32, align 4
1871 // COMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
1872 // COMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
1873 // COMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
1874 // COMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
1875 // COMP-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
1876 // COMP-NEXT: [[I4:%.*]] = alloca i32, align 4
1877 // COMP-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
1878 // COMP-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
1879 // COMP-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
1880 // COMP-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
1881 // COMP-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
1882 // COMP-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
1883 // COMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
1884 // COMP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
1885 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
1886 // COMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
1887 // COMP-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
1888 // COMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1889 // COMP-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
1890 // COMP-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
1891 // COMP-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
1892 // COMP-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
1893 // COMP-NEXT: store i32 0, ptr [[I]], align 4
1894 // COMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
1895 // COMP-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
1896 // COMP-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
1897 // COMP: omp.precond.then:
1898 // COMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
1899 // COMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1900 // COMP-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
1901 // COMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
1902 // COMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
1903 // COMP-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
1904 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1905 // COMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
1906 // COMP-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
1907 // COMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1908 // COMP-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1909 // COMP-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
1910 // COMP-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
1911 // COMP: cond.true:
1912 // COMP-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
1913 // COMP-NEXT: br label [[COND_END:%.*]]
1914 // COMP: cond.false:
1915 // COMP-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1916 // COMP-NEXT: br label [[COND_END]]
1917 // COMP: cond.end:
1918 // COMP-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
1919 // COMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
1920 // COMP-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
1921 // COMP-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
1922 // COMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
1923 // COMP: omp.inner.for.cond:
1924 // COMP-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1925 // COMP-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
1926 // COMP-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
1927 // COMP-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
1928 // COMP-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
1929 // COMP: omp.inner.for.body:
1930 // COMP-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1931 // COMP-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
1932 // COMP-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
1933 // COMP-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
1934 // COMP-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
1935 // COMP-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
1936 // COMP-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
1937 // COMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
1938 // COMP: omp.body.continue:
1939 // COMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
1940 // COMP: omp.inner.for.inc:
1941 // COMP-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
1942 // COMP-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
1943 // COMP-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
1944 // COMP-NEXT: br label [[OMP_INNER_FOR_COND]]
1945 // COMP: omp.inner.for.end:
1946 // COMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
1947 // COMP: omp.loop.exit:
1948 // COMP-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1949 // COMP-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
1950 // COMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
1951 // COMP-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
1952 // COMP-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
1953 // COMP-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1954 // COMP-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
1955 // COMP-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.4.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
1956 // COMP-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
1957 // COMP-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
1958 // COMP-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
1959 // COMP-NEXT: ]
1960 // COMP: .omp.reduction.case1:
1961 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointoRERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1962 // COMP-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
1963 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1964 // COMP: .omp.reduction.case2:
1965 // COMP-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
1966 // COMP-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
1967 // COMP-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1968 // COMP-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointoRERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
1969 // COMP-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
1970 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
1971 // COMP: .omp.reduction.default:
1972 // COMP-NEXT: br label [[OMP_PRECOND_END]]
1973 // COMP: omp.precond.end:
1974 // COMP-NEXT: ret void
1977 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.4.omp.reduction.reduction_func
1978 // COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
1979 // COMP-NEXT: entry:
1980 // COMP-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
1981 // COMP-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
1982 // COMP-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
1983 // COMP-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
1984 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
1985 // COMP-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
1986 // COMP-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
1987 // COMP-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
1988 // COMP-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
1989 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
1990 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointoRERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
1991 // COMP-NEXT: ret void
1994 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.5
1995 // COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
1996 // COMP-NEXT: entry:
1997 // COMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
1998 // COMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
1999 // COMP-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
2000 // COMP-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
2001 // COMP-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
2002 // COMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
2003 // COMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
2004 // COMP-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
2005 // COMP-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
2006 // COMP-NEXT: [[I:%.*]] = alloca i32, align 4
2007 // COMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
2008 // COMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
2009 // COMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
2010 // COMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
2011 // COMP-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
2012 // COMP-NEXT: [[I4:%.*]] = alloca i32, align 4
2013 // COMP-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
2014 // COMP-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
2015 // COMP-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
2016 // COMP-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
2017 // COMP-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
2018 // COMP-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
2019 // COMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
2020 // COMP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
2021 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2022 // COMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
2023 // COMP-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
2024 // COMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
2025 // COMP-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
2026 // COMP-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
2027 // COMP-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
2028 // COMP-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
2029 // COMP-NEXT: store i32 0, ptr [[I]], align 4
2030 // COMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
2031 // COMP-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
2032 // COMP-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
2033 // COMP: omp.precond.then:
2034 // COMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
2035 // COMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
2036 // COMP-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
2037 // COMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
2038 // COMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
2039 // COMP-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
2040 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2041 // COMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
2042 // COMP-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
2043 // COMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
2044 // COMP-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
2045 // COMP-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
2046 // COMP-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
2047 // COMP: cond.true:
2048 // COMP-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
2049 // COMP-NEXT: br label [[COND_END:%.*]]
2050 // COMP: cond.false:
2051 // COMP-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
2052 // COMP-NEXT: br label [[COND_END]]
2053 // COMP: cond.end:
2054 // COMP-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
2055 // COMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
2056 // COMP-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
2057 // COMP-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
2058 // COMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
2059 // COMP: omp.inner.for.cond:
2060 // COMP-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
2061 // COMP-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
2062 // COMP-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
2063 // COMP-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
2064 // COMP-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
2065 // COMP: omp.inner.for.body:
2066 // COMP-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
2067 // COMP-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
2068 // COMP-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
2069 // COMP-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
2070 // COMP-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
2071 // COMP-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
2072 // COMP-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
2073 // COMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
2074 // COMP: omp.body.continue:
2075 // COMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
2076 // COMP: omp.inner.for.inc:
2077 // COMP-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
2078 // COMP-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
2079 // COMP-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
2080 // COMP-NEXT: br label [[OMP_INNER_FOR_COND]]
2081 // COMP: omp.inner.for.end:
2082 // COMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
2083 // COMP: omp.loop.exit:
2084 // COMP-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2085 // COMP-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
2086 // COMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
2087 // COMP-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
2088 // COMP-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
2089 // COMP-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2090 // COMP-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
2091 // COMP-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.5.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
2092 // COMP-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
2093 // COMP-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
2094 // COMP-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
2095 // COMP-NEXT: ]
2096 // COMP: .omp.reduction.case1:
2097 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointeOERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
2098 // COMP-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
2099 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
2100 // COMP: .omp.reduction.case2:
2101 // COMP-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2102 // COMP-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
2103 // COMP-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
2104 // COMP-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointeOERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
2105 // COMP-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
2106 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
2107 // COMP: .omp.reduction.default:
2108 // COMP-NEXT: br label [[OMP_PRECOND_END]]
2109 // COMP: omp.precond.end:
2110 // COMP-NEXT: ret void
2113 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.5.omp.reduction.reduction_func
2114 // COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
2115 // COMP-NEXT: entry:
2116 // COMP-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
2117 // COMP-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
2118 // COMP-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
2119 // COMP-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
2120 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
2121 // COMP-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
2122 // COMP-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
2123 // COMP-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
2124 // COMP-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
2125 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
2126 // COMP-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointeOERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
2127 // COMP-NEXT: ret void
2130 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.6
2131 // COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
2132 // COMP-NEXT: entry:
2133 // COMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
2134 // COMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
2135 // COMP-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
2136 // COMP-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
2137 // COMP-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
2138 // COMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
2139 // COMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
2140 // COMP-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
2141 // COMP-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
2142 // COMP-NEXT: [[I:%.*]] = alloca i32, align 4
2143 // COMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
2144 // COMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
2145 // COMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
2146 // COMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
2147 // COMP-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
2148 // COMP-NEXT: [[I4:%.*]] = alloca i32, align 4
2149 // COMP-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
2150 // COMP-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
2151 // COMP-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
2152 // COMP-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
2153 // COMP-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
2154 // COMP-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
2155 // COMP-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
2156 // COMP-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
2157 // COMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
2158 // COMP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
2159 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2160 // COMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
2161 // COMP-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
2162 // COMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
2163 // COMP-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
2164 // COMP-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
2165 // COMP-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
2166 // COMP-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
2167 // COMP-NEXT: store i32 0, ptr [[I]], align 4
2168 // COMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
2169 // COMP-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
2170 // COMP-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
2171 // COMP: omp.precond.then:
2172 // COMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
2173 // COMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
2174 // COMP-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
2175 // COMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
2176 // COMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
2177 // COMP-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
2178 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2179 // COMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
2180 // COMP-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
2181 // COMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
2182 // COMP-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
2183 // COMP-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
2184 // COMP-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
2185 // COMP: cond.true:
2186 // COMP-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
2187 // COMP-NEXT: br label [[COND_END:%.*]]
2188 // COMP: cond.false:
2189 // COMP-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
2190 // COMP-NEXT: br label [[COND_END]]
2191 // COMP: cond.end:
2192 // COMP-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
2193 // COMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
2194 // COMP-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
2195 // COMP-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
2196 // COMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
2197 // COMP: omp.inner.for.cond:
2198 // COMP-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
2199 // COMP-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
2200 // COMP-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
2201 // COMP-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
2202 // COMP-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
2203 // COMP: omp.inner.for.body:
2204 // COMP-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
2205 // COMP-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
2206 // COMP-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
2207 // COMP-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
2208 // COMP-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
2209 // COMP-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
2210 // COMP-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
2211 // COMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
2212 // COMP: omp.body.continue:
2213 // COMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
2214 // COMP: omp.inner.for.inc:
2215 // COMP-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
2216 // COMP-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
2217 // COMP-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
2218 // COMP-NEXT: br label [[OMP_INNER_FOR_COND]]
2219 // COMP: omp.inner.for.end:
2220 // COMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
2221 // COMP: omp.loop.exit:
2222 // COMP-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2223 // COMP-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
2224 // COMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
2225 // COMP-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
2226 // COMP-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
2227 // COMP-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2228 // COMP-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
2229 // COMP-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.6.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
2230 // COMP-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
2231 // COMP-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
2232 // COMP-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
2233 // COMP-NEXT: ]
2234 // COMP: .omp.reduction.case1:
2235 // COMP-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
2236 // COMP-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
2237 // COMP-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
2238 // COMP-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
2239 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
2240 // COMP: .omp.reduction.case2:
2241 // COMP-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2242 // COMP-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
2243 // COMP-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
2244 // COMP-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
2245 // COMP-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
2246 // COMP-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
2247 // COMP-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
2248 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
2249 // COMP: .omp.reduction.default:
2250 // COMP-NEXT: br label [[OMP_PRECOND_END]]
2251 // COMP: omp.precond.end:
2252 // COMP-NEXT: ret void
2255 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.6.omp.reduction.reduction_func
2256 // COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
2257 // COMP-NEXT: entry:
2258 // COMP-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
2259 // COMP-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
2260 // COMP-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
2261 // COMP-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
2262 // COMP-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
2263 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
2264 // COMP-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
2265 // COMP-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
2266 // COMP-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
2267 // COMP-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
2268 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
2269 // COMP-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointaaERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
2270 // COMP-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
2271 // COMP-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
2272 // COMP-NEXT: ret void
2275 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.7
2276 // COMP-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]], ptr nonnull align 4 dereferenceable(4) [[N:%.*]], ptr nonnull align 4 dereferenceable(8) [[RED:%.*]], ptr nonnull align 8 dereferenceable(8) [[POINTS:%.*]]) #[[ATTR2]] {
2277 // COMP-NEXT: entry:
2278 // COMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
2279 // COMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
2280 // COMP-NEXT: [[N_ADDR:%.*]] = alloca ptr, align 8
2281 // COMP-NEXT: [[RED_ADDR:%.*]] = alloca ptr, align 8
2282 // COMP-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
2283 // COMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
2284 // COMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
2285 // COMP-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32, align 4
2286 // COMP-NEXT: [[DOTCAPTURE_EXPR_1:%.*]] = alloca i32, align 4
2287 // COMP-NEXT: [[I:%.*]] = alloca i32, align 4
2288 // COMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
2289 // COMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
2290 // COMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
2291 // COMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
2292 // COMP-NEXT: [[RED3:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
2293 // COMP-NEXT: [[I4:%.*]] = alloca i32, align 4
2294 // COMP-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
2295 // COMP-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT]], align 4
2296 // COMP-NEXT: [[REF_TMP10:%.*]] = alloca [[STRUCT_POINT]], align 4
2297 // COMP-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
2298 // COMP-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8
2299 // COMP-NEXT: store ptr [[N]], ptr [[N_ADDR]], align 8
2300 // COMP-NEXT: store ptr [[RED]], ptr [[RED_ADDR]], align 8
2301 // COMP-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
2302 // COMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[N_ADDR]], align 8
2303 // COMP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[RED_ADDR]], align 8
2304 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2305 // COMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP0]], align 4
2306 // COMP-NEXT: store i32 [[TMP3]], ptr [[DOTCAPTURE_EXPR_]], align 4
2307 // COMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
2308 // COMP-NEXT: [[SUB:%.*]] = sub i32 [[TMP4]], 0
2309 // COMP-NEXT: [[DIV:%.*]] = udiv i32 [[SUB]], 1
2310 // COMP-NEXT: [[SUB2:%.*]] = sub i32 [[DIV]], 1
2311 // COMP-NEXT: store i32 [[SUB2]], ptr [[DOTCAPTURE_EXPR_1]], align 4
2312 // COMP-NEXT: store i32 0, ptr [[I]], align 4
2313 // COMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_]], align 4
2314 // COMP-NEXT: [[CMP:%.*]] = icmp ult i32 0, [[TMP5]]
2315 // COMP-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
2316 // COMP: omp.precond.then:
2317 // COMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
2318 // COMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
2319 // COMP-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_UB]], align 4
2320 // COMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
2321 // COMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
2322 // COMP-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED3]]) #[[ATTR3]]
2323 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2324 // COMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
2325 // COMP-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[TMP8]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
2326 // COMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
2327 // COMP-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
2328 // COMP-NEXT: [[CMP5:%.*]] = icmp ugt i32 [[TMP9]], [[TMP10]]
2329 // COMP-NEXT: br i1 [[CMP5]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
2330 // COMP: cond.true:
2331 // COMP-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTCAPTURE_EXPR_1]], align 4
2332 // COMP-NEXT: br label [[COND_END:%.*]]
2333 // COMP: cond.false:
2334 // COMP-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
2335 // COMP-NEXT: br label [[COND_END]]
2336 // COMP: cond.end:
2337 // COMP-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ]
2338 // COMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
2339 // COMP-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
2340 // COMP-NEXT: store i32 [[TMP13]], ptr [[DOTOMP_IV]], align 4
2341 // COMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
2342 // COMP: omp.inner.for.cond:
2343 // COMP-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
2344 // COMP-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
2345 // COMP-NEXT: [[ADD:%.*]] = add i32 [[TMP15]], 1
2346 // COMP-NEXT: [[CMP6:%.*]] = icmp ult i32 [[TMP14]], [[ADD]]
2347 // COMP-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
2348 // COMP: omp.inner.for.body:
2349 // COMP-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
2350 // COMP-NEXT: [[MUL:%.*]] = mul i32 [[TMP16]], 1
2351 // COMP-NEXT: [[ADD7:%.*]] = add i32 0, [[MUL]]
2352 // COMP-NEXT: store i32 [[ADD7]], ptr [[I4]], align 4
2353 // COMP-NEXT: [[TMP17:%.*]] = load i32, ptr [[I4]], align 4
2354 // COMP-NEXT: [[TMP18:%.*]] = load ptr, ptr [[TMP2]], align 8
2355 // COMP-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED3]], i32 [[TMP17]], ptr [[TMP18]])
2356 // COMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
2357 // COMP: omp.body.continue:
2358 // COMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
2359 // COMP: omp.inner.for.inc:
2360 // COMP-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
2361 // COMP-NEXT: [[ADD8:%.*]] = add i32 [[TMP19]], 1
2362 // COMP-NEXT: store i32 [[ADD8]], ptr [[DOTOMP_IV]], align 4
2363 // COMP-NEXT: br label [[OMP_INNER_FOR_COND]]
2364 // COMP: omp.inner.for.end:
2365 // COMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
2366 // COMP: omp.loop.exit:
2367 // COMP-NEXT: [[TMP20:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2368 // COMP-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 4
2369 // COMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP21]])
2370 // COMP-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0
2371 // COMP-NEXT: store ptr [[RED3]], ptr [[TMP22]], align 8
2372 // COMP-NEXT: [[TMP23:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2373 // COMP-NEXT: [[TMP24:%.*]] = load i32, ptr [[TMP23]], align 4
2374 // COMP-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], i32 1, i64 8, ptr [[DOTOMP_REDUCTION_RED_LIST]], ptr @_Z3fooiPK5Point.omp_outlined.7.omp.reduction.reduction_func, ptr @.gomp_critical_user_.reduction.var)
2375 // COMP-NEXT: switch i32 [[TMP25]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
2376 // COMP-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
2377 // COMP-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
2378 // COMP-NEXT: ]
2379 // COMP: .omp.reduction.case1:
2380 // COMP-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
2381 // COMP-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
2382 // COMP-NEXT: [[CALL9:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
2383 // COMP-NEXT: call void @__kmpc_end_reduce_nowait(ptr @[[GLOB2]], i32 [[TMP24]], ptr @.gomp_critical_user_.reduction.var)
2384 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
2385 // COMP: .omp.reduction.case2:
2386 // COMP-NEXT: [[TMP26:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
2387 // COMP-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
2388 // COMP-NEXT: call void @__kmpc_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
2389 // COMP-NEXT: [[CALL11:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[RED3]])
2390 // COMP-NEXT: store i64 [[CALL11]], ptr [[REF_TMP10]], align 4
2391 // COMP-NEXT: [[CALL12:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP1]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP10]])
2392 // COMP-NEXT: call void @__kmpc_end_critical(ptr @[[GLOB3]], i32 [[TMP27]], ptr @.gomp_critical_user_.atomic_reduction.var)
2393 // COMP-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
2394 // COMP: .omp.reduction.default:
2395 // COMP-NEXT: br label [[OMP_PRECOND_END]]
2396 // COMP: omp.precond.end:
2397 // COMP-NEXT: ret void
2400 // COMP-LABEL: define {{[^@]+}}@_Z3fooiPK5Point.omp_outlined.7.omp.reduction.reduction_func
2401 // COMP-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]]) #[[ATTR5]] {
2402 // COMP-NEXT: entry:
2403 // COMP-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8
2404 // COMP-NEXT: [[DOTADDR1:%.*]] = alloca ptr, align 8
2405 // COMP-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
2406 // COMP-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8
2407 // COMP-NEXT: store ptr [[TMP1]], ptr [[DOTADDR1]], align 8
2408 // COMP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTADDR]], align 8
2409 // COMP-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTADDR1]], align 8
2410 // COMP-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP3]], i64 0, i64 0
2411 // COMP-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8
2412 // COMP-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x ptr], ptr [[TMP2]], i64 0, i64 0
2413 // COMP-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP6]], align 8
2414 // COMP-NEXT: [[CALL:%.*]] = call i64 @_ZNK5PointooERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[TMP5]])
2415 // COMP-NEXT: store i64 [[CALL]], ptr [[REF_TMP]], align 4
2416 // COMP-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(8) ptr @_ZN5PointaSERKS_(ptr nonnull align 4 dereferenceable(8) [[TMP7]], ptr nonnull align 4 dereferenceable(8) [[REF_TMP]])
2417 // COMP-NEXT: ret void
2420 // COMP-LABEL: define {{[^@]+}}@_ZN5PointC2Ev
2421 // COMP-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 {
2422 // COMP-NEXT: entry:
2423 // COMP-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8
2424 // COMP-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
2425 // COMP-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
2426 // COMP-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_POINT:%.*]], ptr [[THIS1]], i32 0, i32 0
2427 // COMP-NEXT: store i32 0, ptr [[X]], align 4
2428 // COMP-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_POINT]], ptr [[THIS1]], i32 0, i32 1
2429 // COMP-NEXT: store i32 0, ptr [[Y]], align 4
2430 // COMP-NEXT: ret void
2433 // SIMD-ONLY-LABEL: define {{[^@]+}}@_Z3fooiPK5Point
2434 // SIMD-ONLY-SAME: (i32 [[N:%.*]], ptr [[POINTS:%.*]]) #[[ATTR0:[0-9]+]] {
2435 // SIMD-ONLY-NEXT: entry:
2436 // SIMD-ONLY-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4
2437 // SIMD-ONLY-NEXT: [[POINTS_ADDR:%.*]] = alloca ptr, align 8
2438 // SIMD-ONLY-NEXT: [[RED:%.*]] = alloca [[STRUCT_POINT:%.*]], align 4
2439 // SIMD-ONLY-NEXT: [[I:%.*]] = alloca i32, align 4
2440 // SIMD-ONLY-NEXT: [[I1:%.*]] = alloca i32, align 4
2441 // SIMD-ONLY-NEXT: [[I8:%.*]] = alloca i32, align 4
2442 // SIMD-ONLY-NEXT: [[I15:%.*]] = alloca i32, align 4
2443 // SIMD-ONLY-NEXT: [[I22:%.*]] = alloca i32, align 4
2444 // SIMD-ONLY-NEXT: [[I29:%.*]] = alloca i32, align 4
2445 // SIMD-ONLY-NEXT: [[I36:%.*]] = alloca i32, align 4
2446 // SIMD-ONLY-NEXT: [[I43:%.*]] = alloca i32, align 4
2447 // SIMD-ONLY-NEXT: store i32 [[N]], ptr [[N_ADDR]], align 4
2448 // SIMD-ONLY-NEXT: store ptr [[POINTS]], ptr [[POINTS_ADDR]], align 8
2449 // SIMD-ONLY-NEXT: call void @_ZN5PointC1Ev(ptr nonnull align 4 dereferenceable(8) [[RED]]) #[[ATTR3:[0-9]+]]
2450 // SIMD-ONLY-NEXT: store i32 0, ptr [[I]], align 4
2451 // SIMD-ONLY-NEXT: br label [[FOR_COND:%.*]]
2452 // SIMD-ONLY: for.cond:
2453 // SIMD-ONLY-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4
2454 // SIMD-ONLY-NEXT: [[TMP1:%.*]] = load i32, ptr [[N_ADDR]], align 4
2455 // SIMD-ONLY-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP0]], [[TMP1]]
2456 // SIMD-ONLY-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
2457 // SIMD-ONLY: for.body:
2458 // SIMD-ONLY-NEXT: [[TMP2:%.*]] = load i32, ptr [[I]], align 4
2459 // SIMD-ONLY-NEXT: [[TMP3:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2460 // SIMD-ONLY-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP2]], ptr [[TMP3]])
2461 // SIMD-ONLY-NEXT: br label [[FOR_INC:%.*]]
2462 // SIMD-ONLY: for.inc:
2463 // SIMD-ONLY-NEXT: [[TMP4:%.*]] = load i32, ptr [[I]], align 4
2464 // SIMD-ONLY-NEXT: [[INC:%.*]] = add i32 [[TMP4]], 1
2465 // SIMD-ONLY-NEXT: store i32 [[INC]], ptr [[I]], align 4
2466 // SIMD-ONLY-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
2467 // SIMD-ONLY: for.end:
2468 // SIMD-ONLY-NEXT: store i32 0, ptr [[I1]], align 4
2469 // SIMD-ONLY-NEXT: br label [[FOR_COND2:%.*]]
2470 // SIMD-ONLY: for.cond2:
2471 // SIMD-ONLY-NEXT: [[TMP5:%.*]] = load i32, ptr [[I1]], align 4
2472 // SIMD-ONLY-NEXT: [[TMP6:%.*]] = load i32, ptr [[N_ADDR]], align 4
2473 // SIMD-ONLY-NEXT: [[CMP3:%.*]] = icmp ult i32 [[TMP5]], [[TMP6]]
2474 // SIMD-ONLY-NEXT: br i1 [[CMP3]], label [[FOR_BODY4:%.*]], label [[FOR_END7:%.*]]
2475 // SIMD-ONLY: for.body4:
2476 // SIMD-ONLY-NEXT: [[TMP7:%.*]] = load i32, ptr [[I1]], align 4
2477 // SIMD-ONLY-NEXT: [[TMP8:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2478 // SIMD-ONLY-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP7]], ptr [[TMP8]])
2479 // SIMD-ONLY-NEXT: br label [[FOR_INC5:%.*]]
2480 // SIMD-ONLY: for.inc5:
2481 // SIMD-ONLY-NEXT: [[TMP9:%.*]] = load i32, ptr [[I1]], align 4
2482 // SIMD-ONLY-NEXT: [[INC6:%.*]] = add i32 [[TMP9]], 1
2483 // SIMD-ONLY-NEXT: store i32 [[INC6]], ptr [[I1]], align 4
2484 // SIMD-ONLY-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP4:![0-9]+]]
2485 // SIMD-ONLY: for.end7:
2486 // SIMD-ONLY-NEXT: store i32 0, ptr [[I8]], align 4
2487 // SIMD-ONLY-NEXT: br label [[FOR_COND9:%.*]]
2488 // SIMD-ONLY: for.cond9:
2489 // SIMD-ONLY-NEXT: [[TMP10:%.*]] = load i32, ptr [[I8]], align 4
2490 // SIMD-ONLY-NEXT: [[TMP11:%.*]] = load i32, ptr [[N_ADDR]], align 4
2491 // SIMD-ONLY-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP10]], [[TMP11]]
2492 // SIMD-ONLY-NEXT: br i1 [[CMP10]], label [[FOR_BODY11:%.*]], label [[FOR_END14:%.*]]
2493 // SIMD-ONLY: for.body11:
2494 // SIMD-ONLY-NEXT: [[TMP12:%.*]] = load i32, ptr [[I8]], align 4
2495 // SIMD-ONLY-NEXT: [[TMP13:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2496 // SIMD-ONLY-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP12]], ptr [[TMP13]])
2497 // SIMD-ONLY-NEXT: br label [[FOR_INC12:%.*]]
2498 // SIMD-ONLY: for.inc12:
2499 // SIMD-ONLY-NEXT: [[TMP14:%.*]] = load i32, ptr [[I8]], align 4
2500 // SIMD-ONLY-NEXT: [[INC13:%.*]] = add i32 [[TMP14]], 1
2501 // SIMD-ONLY-NEXT: store i32 [[INC13]], ptr [[I8]], align 4
2502 // SIMD-ONLY-NEXT: br label [[FOR_COND9]], !llvm.loop [[LOOP5:![0-9]+]]
2503 // SIMD-ONLY: for.end14:
2504 // SIMD-ONLY-NEXT: store i32 0, ptr [[I15]], align 4
2505 // SIMD-ONLY-NEXT: br label [[FOR_COND16:%.*]]
2506 // SIMD-ONLY: for.cond16:
2507 // SIMD-ONLY-NEXT: [[TMP15:%.*]] = load i32, ptr [[I15]], align 4
2508 // SIMD-ONLY-NEXT: [[TMP16:%.*]] = load i32, ptr [[N_ADDR]], align 4
2509 // SIMD-ONLY-NEXT: [[CMP17:%.*]] = icmp ult i32 [[TMP15]], [[TMP16]]
2510 // SIMD-ONLY-NEXT: br i1 [[CMP17]], label [[FOR_BODY18:%.*]], label [[FOR_END21:%.*]]
2511 // SIMD-ONLY: for.body18:
2512 // SIMD-ONLY-NEXT: [[TMP17:%.*]] = load i32, ptr [[I15]], align 4
2513 // SIMD-ONLY-NEXT: [[TMP18:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2514 // SIMD-ONLY-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP17]], ptr [[TMP18]])
2515 // SIMD-ONLY-NEXT: br label [[FOR_INC19:%.*]]
2516 // SIMD-ONLY: for.inc19:
2517 // SIMD-ONLY-NEXT: [[TMP19:%.*]] = load i32, ptr [[I15]], align 4
2518 // SIMD-ONLY-NEXT: [[INC20:%.*]] = add i32 [[TMP19]], 1
2519 // SIMD-ONLY-NEXT: store i32 [[INC20]], ptr [[I15]], align 4
2520 // SIMD-ONLY-NEXT: br label [[FOR_COND16]], !llvm.loop [[LOOP6:![0-9]+]]
2521 // SIMD-ONLY: for.end21:
2522 // SIMD-ONLY-NEXT: store i32 0, ptr [[I22]], align 4
2523 // SIMD-ONLY-NEXT: br label [[FOR_COND23:%.*]]
2524 // SIMD-ONLY: for.cond23:
2525 // SIMD-ONLY-NEXT: [[TMP20:%.*]] = load i32, ptr [[I22]], align 4
2526 // SIMD-ONLY-NEXT: [[TMP21:%.*]] = load i32, ptr [[N_ADDR]], align 4
2527 // SIMD-ONLY-NEXT: [[CMP24:%.*]] = icmp ult i32 [[TMP20]], [[TMP21]]
2528 // SIMD-ONLY-NEXT: br i1 [[CMP24]], label [[FOR_BODY25:%.*]], label [[FOR_END28:%.*]]
2529 // SIMD-ONLY: for.body25:
2530 // SIMD-ONLY-NEXT: [[TMP22:%.*]] = load i32, ptr [[I22]], align 4
2531 // SIMD-ONLY-NEXT: [[TMP23:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2532 // SIMD-ONLY-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP22]], ptr [[TMP23]])
2533 // SIMD-ONLY-NEXT: br label [[FOR_INC26:%.*]]
2534 // SIMD-ONLY: for.inc26:
2535 // SIMD-ONLY-NEXT: [[TMP24:%.*]] = load i32, ptr [[I22]], align 4
2536 // SIMD-ONLY-NEXT: [[INC27:%.*]] = add i32 [[TMP24]], 1
2537 // SIMD-ONLY-NEXT: store i32 [[INC27]], ptr [[I22]], align 4
2538 // SIMD-ONLY-NEXT: br label [[FOR_COND23]], !llvm.loop [[LOOP7:![0-9]+]]
2539 // SIMD-ONLY: for.end28:
2540 // SIMD-ONLY-NEXT: store i32 0, ptr [[I29]], align 4
2541 // SIMD-ONLY-NEXT: br label [[FOR_COND30:%.*]]
2542 // SIMD-ONLY: for.cond30:
2543 // SIMD-ONLY-NEXT: [[TMP25:%.*]] = load i32, ptr [[I29]], align 4
2544 // SIMD-ONLY-NEXT: [[TMP26:%.*]] = load i32, ptr [[N_ADDR]], align 4
2545 // SIMD-ONLY-NEXT: [[CMP31:%.*]] = icmp ult i32 [[TMP25]], [[TMP26]]
2546 // SIMD-ONLY-NEXT: br i1 [[CMP31]], label [[FOR_BODY32:%.*]], label [[FOR_END35:%.*]]
2547 // SIMD-ONLY: for.body32:
2548 // SIMD-ONLY-NEXT: [[TMP27:%.*]] = load i32, ptr [[I29]], align 4
2549 // SIMD-ONLY-NEXT: [[TMP28:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2550 // SIMD-ONLY-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP27]], ptr [[TMP28]])
2551 // SIMD-ONLY-NEXT: br label [[FOR_INC33:%.*]]
2552 // SIMD-ONLY: for.inc33:
2553 // SIMD-ONLY-NEXT: [[TMP29:%.*]] = load i32, ptr [[I29]], align 4
2554 // SIMD-ONLY-NEXT: [[INC34:%.*]] = add i32 [[TMP29]], 1
2555 // SIMD-ONLY-NEXT: store i32 [[INC34]], ptr [[I29]], align 4
2556 // SIMD-ONLY-NEXT: br label [[FOR_COND30]], !llvm.loop [[LOOP8:![0-9]+]]
2557 // SIMD-ONLY: for.end35:
2558 // SIMD-ONLY-NEXT: store i32 0, ptr [[I36]], align 4
2559 // SIMD-ONLY-NEXT: br label [[FOR_COND37:%.*]]
2560 // SIMD-ONLY: for.cond37:
2561 // SIMD-ONLY-NEXT: [[TMP30:%.*]] = load i32, ptr [[I36]], align 4
2562 // SIMD-ONLY-NEXT: [[TMP31:%.*]] = load i32, ptr [[N_ADDR]], align 4
2563 // SIMD-ONLY-NEXT: [[CMP38:%.*]] = icmp ult i32 [[TMP30]], [[TMP31]]
2564 // SIMD-ONLY-NEXT: br i1 [[CMP38]], label [[FOR_BODY39:%.*]], label [[FOR_END42:%.*]]
2565 // SIMD-ONLY: for.body39:
2566 // SIMD-ONLY-NEXT: [[TMP32:%.*]] = load i32, ptr [[I36]], align 4
2567 // SIMD-ONLY-NEXT: [[TMP33:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2568 // SIMD-ONLY-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP32]], ptr [[TMP33]])
2569 // SIMD-ONLY-NEXT: br label [[FOR_INC40:%.*]]
2570 // SIMD-ONLY: for.inc40:
2571 // SIMD-ONLY-NEXT: [[TMP34:%.*]] = load i32, ptr [[I36]], align 4
2572 // SIMD-ONLY-NEXT: [[INC41:%.*]] = add i32 [[TMP34]], 1
2573 // SIMD-ONLY-NEXT: store i32 [[INC41]], ptr [[I36]], align 4
2574 // SIMD-ONLY-NEXT: br label [[FOR_COND37]], !llvm.loop [[LOOP9:![0-9]+]]
2575 // SIMD-ONLY: for.end42:
2576 // SIMD-ONLY-NEXT: store i32 0, ptr [[I43]], align 4
2577 // SIMD-ONLY-NEXT: br label [[FOR_COND44:%.*]]
2578 // SIMD-ONLY: for.cond44:
2579 // SIMD-ONLY-NEXT: [[TMP35:%.*]] = load i32, ptr [[I43]], align 4
2580 // SIMD-ONLY-NEXT: [[TMP36:%.*]] = load i32, ptr [[N_ADDR]], align 4
2581 // SIMD-ONLY-NEXT: [[CMP45:%.*]] = icmp ult i32 [[TMP35]], [[TMP36]]
2582 // SIMD-ONLY-NEXT: br i1 [[CMP45]], label [[FOR_BODY46:%.*]], label [[FOR_END49:%.*]]
2583 // SIMD-ONLY: for.body46:
2584 // SIMD-ONLY-NEXT: [[TMP37:%.*]] = load i32, ptr [[I43]], align 4
2585 // SIMD-ONLY-NEXT: [[TMP38:%.*]] = load ptr, ptr [[POINTS_ADDR]], align 8
2586 // SIMD-ONLY-NEXT: call void @_Z4workR5PointiPKS_(ptr nonnull align 4 dereferenceable(8) [[RED]], i32 [[TMP37]], ptr [[TMP38]])
2587 // SIMD-ONLY-NEXT: br label [[FOR_INC47:%.*]]
2588 // SIMD-ONLY: for.inc47:
2589 // SIMD-ONLY-NEXT: [[TMP39:%.*]] = load i32, ptr [[I43]], align 4
2590 // SIMD-ONLY-NEXT: [[INC48:%.*]] = add i32 [[TMP39]], 1
2591 // SIMD-ONLY-NEXT: store i32 [[INC48]], ptr [[I43]], align 4
2592 // SIMD-ONLY-NEXT: br label [[FOR_COND44]], !llvm.loop [[LOOP10:![0-9]+]]
2593 // SIMD-ONLY: for.end49:
2594 // SIMD-ONLY-NEXT: ret void
2597 // SIMD-ONLY-LABEL: define {{[^@]+}}@_ZN5PointC1Ev
2598 // SIMD-ONLY-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 {
2599 // SIMD-ONLY-NEXT: entry:
2600 // SIMD-ONLY-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8
2601 // SIMD-ONLY-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
2602 // SIMD-ONLY-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
2603 // SIMD-ONLY-NEXT: call void @_ZN5PointC2Ev(ptr nonnull align 4 dereferenceable(8) [[THIS1]]) #[[ATTR3]]
2604 // SIMD-ONLY-NEXT: ret void
2607 // SIMD-ONLY-LABEL: define {{[^@]+}}@_ZN5PointC2Ev
2608 // SIMD-ONLY-SAME: (ptr nonnull align 4 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] comdat align 2 {
2609 // SIMD-ONLY-NEXT: entry:
2610 // SIMD-ONLY-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8
2611 // SIMD-ONLY-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8
2612 // SIMD-ONLY-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8
2613 // SIMD-ONLY-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_POINT:%.*]], ptr [[THIS1]], i32 0, i32 0
2614 // SIMD-ONLY-NEXT: store i32 0, ptr [[X]], align 4
2615 // SIMD-ONLY-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_POINT]], ptr [[THIS1]], i32 0, i32 1
2616 // SIMD-ONLY-NEXT: store i32 0, ptr [[Y]], align 4
2617 // SIMD-ONLY-NEXT: ret void