Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / OpenMP / parallel_deletion.ll
blob4619da1206092f0e65d3a18b5e31b0a645f87da7
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2 ; RUN: opt -S -passes='attributor,cgscc(openmp-opt-cgscc)'  < %s | FileCheck %s
4 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
6 %struct.ident_t = type { i32, i32, i32, i32, ptr }
8 @.str = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
9 @0 = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0, i32 0, ptr @.str }, align 8
10 @1 = private unnamed_addr global %struct.ident_t { i32 0, i32 322, i32 0, i32 0, ptr @.str }, align 8
11 @.gomp_critical_user_.reduction.var = common global [8 x i32] zeroinitializer
12 @2 = private unnamed_addr global %struct.ident_t { i32 0, i32 18, i32 0, i32 0, ptr @.str }, align 8
14 ;    void delete_parallel_0(void) {
15 ;    #pragma omp parallel
16 ;      { unknown_willreturn(); }
17 ;    #pragma omp parallel
18 ;      { readonly_willreturn(); }
19 ;    #pragma omp parallel
20 ;      { readnone_willreturn(); }
21 ;    #pragma omp parallel
22 ;      {}
23 ;    }
25 ; We delete all but the first of the parallel regions in this test.
26 define void @delete_parallel_0() {
27 ; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0() {
28 ; CHECK-NEXT:  entry:
29 ; CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, ptr noundef nonnull @.omp_outlined.willreturn)
30 ; CHECK-NEXT:    ret void
32 ; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_0() {
33 ; CHECK1-NEXT:  entry:
34 ; CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, ptr noundef @.omp_outlined.willreturn)
35 ; CHECK1-NEXT:    ret void
36 ; CHECK2-LABEL: define {{[^@]+}}@delete_parallel_0() {
37 ; CHECK2-NEXT:  entry:
38 ; CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0:[0-9]+]], i32 noundef 0, ptr noundef @.omp_outlined.willreturn)
39 ; CHECK2-NEXT:    ret void
40 entry:
41   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.willreturn)
42   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.willreturn.0)
43   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.willreturn.1)
44   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.willreturn.2)
45   ret void
48 define internal void @.omp_outlined.willreturn(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
49 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
50 ; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] {
51 ; CHECK-NEXT:  entry:
52 ; CHECK-NEXT:    call void @unknown() #[[ATTR15:[0-9]+]]
53 ; CHECK-NEXT:    ret void
55 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
56 ; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] {
57 ; CHECK1-NEXT:  entry:
58 ; CHECK1-NEXT:    call void @unknown() #[[ATTR0]]
59 ; CHECK1-NEXT:    ret void
60 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
61 ; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0:[0-9]+]] {
62 ; CHECK2-NEXT:  entry:
63 ; CHECK2-NEXT:    call void @unknown() #[[ATTR0]]
64 ; CHECK2-NEXT:    ret void
65 entry:
66   call void @unknown() willreturn
67   ret void
70 define internal void @.omp_outlined.willreturn.0(ptr noalias %.global_tid., ptr noalias %.bound_tid.) willreturn {
71 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
72 ; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] {
73 ; CHECK-NEXT:  entry:
74 ; CHECK-NEXT:    call void @readonly() #[[ATTR4:[0-9]+]]
75 ; CHECK-NEXT:    ret void
77 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
78 ; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] {
79 ; CHECK1-NEXT:  entry:
80 ; CHECK1-NEXT:    call void @readonly() #[[ATTR4:[0-9]+]]
81 ; CHECK1-NEXT:    ret void
82 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
83 ; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR1:[0-9]+]] {
84 ; CHECK2-NEXT:  entry:
85 ; CHECK2-NEXT:    call void @readonly() #[[ATTR4:[0-9]+]]
86 ; CHECK2-NEXT:    ret void
87 entry:
88   call void @readonly()
89   ret void
92 define internal void @.omp_outlined.willreturn.1(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
93 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
94 ; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] {
95 ; CHECK-NEXT:  entry:
96 ; CHECK-NEXT:    call void @readnone() #[[ATTR16:[0-9]+]]
97 ; CHECK-NEXT:    ret void
99 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
100 ; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] {
101 ; CHECK1-NEXT:  entry:
102 ; CHECK1-NEXT:    call void @readnone() #[[ATTR0]]
103 ; CHECK1-NEXT:    ret void
104 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
105 ; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR2:[0-9]+]] {
106 ; CHECK2-NEXT:  entry:
107 ; CHECK2-NEXT:    call void @readnone() #[[ATTR0]]
108 ; CHECK2-NEXT:    ret void
109 entry:
110   call void @readnone() willreturn
111   ret void
114 define internal void @.omp_outlined.willreturn.2(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
115 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
116 ; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] {
117 ; CHECK-NEXT:  entry:
118 ; CHECK-NEXT:    ret void
120 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
121 ; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] {
122 ; CHECK1-NEXT:  entry:
123 ; CHECK1-NEXT:    ret void
124 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
125 ; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] {
126 ; CHECK2-NEXT:  entry:
127 ; CHECK2-NEXT:    ret void
128 entry:
129   ret void
132 ;    void delete_parallel_1(void) {
133 ;    #pragma omp parallel
134 ;      { unknown(); }
135 ;    #pragma omp parallel
136 ;      { readonly(); }
137 ;    #pragma omp parallel
138 ;      { readnone(); }
139 ;    #pragma omp parallel
140 ;      {}
141 ;    }
143 ; We delete only the last parallel regions in this test because the others might not return.
144 define void @delete_parallel_1() {
145 ; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1() {
146 ; CHECK-NEXT:  entry:
147 ; CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef nonnull @.omp_outlined.)
148 ; CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef nonnull @.omp_outlined..0)
149 ; CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef nonnull @.omp_outlined..1)
150 ; CHECK-NEXT:    ret void
152 ; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_1() {
153 ; CHECK1-NEXT:  entry:
154 ; CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined.)
155 ; CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined..0)
156 ; CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined..1)
157 ; CHECK1-NEXT:    ret void
158 ; CHECK2-LABEL: define {{[^@]+}}@delete_parallel_1() {
159 ; CHECK2-NEXT:  entry:
160 ; CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined.)
161 ; CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined..0)
162 ; CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 0, ptr noundef @.omp_outlined..1)
163 ; CHECK2-NEXT:    ret void
164 entry:
165   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined.)
166   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined..0)
167   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined..1)
168   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 0, ptr @.omp_outlined..2)
169   ret void
172 define internal void @.omp_outlined.(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
173 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
174 ; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) {
175 ; CHECK-NEXT:  entry:
176 ; CHECK-NEXT:    call void @unknown()
177 ; CHECK-NEXT:    ret void
179 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.
180 ; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) {
181 ; CHECK1-NEXT:  entry:
182 ; CHECK1-NEXT:    call void @unknown()
183 ; CHECK1-NEXT:    ret void
184 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.
185 ; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) {
186 ; CHECK2-NEXT:  entry:
187 ; CHECK2-NEXT:    call void @unknown()
188 ; CHECK2-NEXT:    ret void
189 entry:
190   call void @unknown()
191   ret void
194 define internal void @.omp_outlined..0(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
195 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..0
196 ; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] {
197 ; CHECK-NEXT:  entry:
198 ; CHECK-NEXT:    call void @readonly() #[[ATTR4]]
199 ; CHECK-NEXT:    ret void
201 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..0
202 ; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] {
203 ; CHECK1-NEXT:  entry:
204 ; CHECK1-NEXT:    call void @readonly() #[[ATTR4]]
205 ; CHECK1-NEXT:    ret void
206 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..0
207 ; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR4]] {
208 ; CHECK2-NEXT:  entry:
209 ; CHECK2-NEXT:    call void @readonly() #[[ATTR4]]
210 ; CHECK2-NEXT:    ret void
211 entry:
212   call void @readonly()
213   ret void
216 define internal void @.omp_outlined..1(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
217 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
218 ; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] {
219 ; CHECK-NEXT:  entry:
220 ; CHECK-NEXT:    call void @readnone() #[[ATTR17:[0-9]+]]
221 ; CHECK-NEXT:    ret void
223 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..1
224 ; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] {
225 ; CHECK1-NEXT:  entry:
226 ; CHECK1-NEXT:    call void @readnone()
227 ; CHECK1-NEXT:    ret void
228 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..1
229 ; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR5:[0-9]+]] {
230 ; CHECK2-NEXT:  entry:
231 ; CHECK2-NEXT:    call void @readnone()
232 ; CHECK2-NEXT:    ret void
233 entry:
234   call void @readnone()
235   ret void
238 define internal void @.omp_outlined..2(ptr noalias %.global_tid., ptr noalias %.bound_tid.) {
239 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
240 ; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] {
241 ; CHECK-NEXT:  entry:
242 ; CHECK-NEXT:    ret void
244 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..2
245 ; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] {
246 ; CHECK1-NEXT:  entry:
247 ; CHECK1-NEXT:    ret void
248 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..2
249 ; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR3]] {
250 ; CHECK2-NEXT:  entry:
251 ; CHECK2-NEXT:    ret void
252 entry:
253   ret void
256 ;    void delete_parallel_2(void) {
257 ;      int a = 0;
258 ;    #pragma omp parallel
259 ;      {
260 ;        if (omp_get_thread_num() == 0)
261 ;          ++a;
262 ;      }
263 ;    #pragma omp parallel
264 ;      {
265 ;    #pragma omp master
266 ;        ++a;
267 ;      }
268 ;    #pragma omp parallel
269 ;      {
270 ;    #pragma omp single
271 ;        ++a;
272 ;      }
273 ;    #pragma omp parallel reduction(+: a)
274 ;      {
275 ;        ++a;
276 ;      }
277 ;    }
279 ; FIXME: We do not realize that `a` is dead and all accesses to it can be removed
280 ;        making the parallel regions readonly and deletable.
281 define void @delete_parallel_2() {
282 ; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() {
283 ; CHECK-NEXT:  entry:
284 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
285 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR18:[0-9]+]]
286 ; CHECK-NEXT:    store i32 0, ptr [[A]], align 4
287 ; CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..3, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
288 ; CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
289 ; CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..5, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
290 ; CHECK-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..6, ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
291 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A]])
292 ; CHECK-NEXT:    ret void
294 ; CHECK1-LABEL: define {{[^@]+}}@delete_parallel_2() {
295 ; CHECK1-NEXT:  entry:
296 ; CHECK1-NEXT:    [[A:%.*]] = alloca i32, align 4
297 ; CHECK1-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR0]]
298 ; CHECK1-NEXT:    store i32 0, ptr [[A]], align 4
299 ; CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..3, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
300 ; CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
301 ; CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..5, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
302 ; CHECK1-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..6, ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
303 ; CHECK1-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A]])
304 ; CHECK1-NEXT:    ret void
305 ; CHECK2-LABEL: define {{[^@]+}}@delete_parallel_2() {
306 ; CHECK2-NEXT:  entry:
307 ; CHECK2-NEXT:    [[A:%.*]] = alloca i32, align 4
308 ; CHECK2-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR0]]
309 ; CHECK2-NEXT:    store i32 0, ptr [[A]], align 4
310 ; CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..3, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
311 ; CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
312 ; CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..5, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
313 ; CHECK2-NEXT:    call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef @.omp_outlined..6, ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
314 ; CHECK2-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A]])
315 ; CHECK2-NEXT:    ret void
316 entry:
317   %a = alloca i32, align 4
318   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %a)
319   store i32 0, ptr %a, align 4
320   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 1, ptr @.omp_outlined..3, ptr nonnull %a)
321   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 1, ptr @.omp_outlined..4, ptr nonnull %a)
322   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 1, ptr @.omp_outlined..5, ptr nonnull %a)
323   call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr nonnull @0, i32 1, ptr @.omp_outlined..6, ptr nonnull %a)
324   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %a)
325   ret void
328 define internal void @.omp_outlined..3(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
329 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3
330 ; CHECK-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
331 ; CHECK-NEXT:  entry:
332 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR19:[0-9]+]]
333 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
334 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
335 ; CHECK:       if.then:
336 ; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr [[A]], align 4
337 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP]], 1
338 ; CHECK-NEXT:    store i32 [[INC]], ptr [[A]], align 4
339 ; CHECK-NEXT:    br label [[IF_END]]
340 ; CHECK:       if.end:
341 ; CHECK-NEXT:    ret void
343 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..3
344 ; CHECK1-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
345 ; CHECK1-NEXT:  entry:
346 ; CHECK1-NEXT:    [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR14:[0-9]+]]
347 ; CHECK1-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
348 ; CHECK1-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
349 ; CHECK1:       if.then:
350 ; CHECK1-NEXT:    [[TMP:%.*]] = load i32, ptr [[A]], align 4
351 ; CHECK1-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP]], 1
352 ; CHECK1-NEXT:    store i32 [[INC]], ptr [[A]], align 4
353 ; CHECK1-NEXT:    br label [[IF_END]]
354 ; CHECK1:       if.end:
355 ; CHECK1-NEXT:    ret void
356 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..3
357 ; CHECK2-SAME: (ptr noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
358 ; CHECK2-NEXT:  entry:
359 ; CHECK2-NEXT:    [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR14:[0-9]+]]
360 ; CHECK2-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
361 ; CHECK2-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
362 ; CHECK2:       if.then:
363 ; CHECK2-NEXT:    [[TMP:%.*]] = load i32, ptr [[A]], align 4
364 ; CHECK2-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP]], 1
365 ; CHECK2-NEXT:    store i32 [[INC]], ptr [[A]], align 4
366 ; CHECK2-NEXT:    br label [[IF_END]]
367 ; CHECK2:       if.end:
368 ; CHECK2-NEXT:    ret void
369 entry:
370   %call = call i32 @omp_get_thread_num()
371   %cmp = icmp eq i32 %call, 0
372   br i1 %cmp, label %if.then, label %if.end
374 if.then:                                          ; preds = %entry
375   %tmp = load i32, ptr %a, align 4
376   %inc = add nsw i32 %tmp, 1
377   store i32 %inc, ptr %a, align 4
378   br label %if.end
380 if.end:                                           ; preds = %if.then, %entry
381   ret void
384 define internal void @.omp_outlined..4(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
385 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4
386 ; CHECK-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
387 ; CHECK-NEXT:  entry:
388 ; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
389 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
390 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
391 ; CHECK-NEXT:    br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
392 ; CHECK:       omp_if.then:
393 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[A]], align 4
394 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
395 ; CHECK-NEXT:    store i32 [[INC]], ptr [[A]], align 4
396 ; CHECK-NEXT:    call void @__kmpc_end_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
397 ; CHECK-NEXT:    br label [[OMP_IF_END]]
398 ; CHECK:       omp_if.end:
399 ; CHECK-NEXT:    ret void
401 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..4
402 ; CHECK1-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
403 ; CHECK1-NEXT:  entry:
404 ; CHECK1-NEXT:    [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
405 ; CHECK1-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
406 ; CHECK1-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
407 ; CHECK1-NEXT:    br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
408 ; CHECK1:       omp_if.then:
409 ; CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[A]], align 4
410 ; CHECK1-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
411 ; CHECK1-NEXT:    store i32 [[INC]], ptr [[A]], align 4
412 ; CHECK1-NEXT:    call void @__kmpc_end_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
413 ; CHECK1-NEXT:    br label [[OMP_IF_END]]
414 ; CHECK1:       omp_if.end:
415 ; CHECK1-NEXT:    ret void
416 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..4
417 ; CHECK2-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
418 ; CHECK2-NEXT:  entry:
419 ; CHECK2-NEXT:    [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
420 ; CHECK2-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
421 ; CHECK2-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
422 ; CHECK2-NEXT:    br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
423 ; CHECK2:       omp_if.then:
424 ; CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[A]], align 4
425 ; CHECK2-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
426 ; CHECK2-NEXT:    store i32 [[INC]], ptr [[A]], align 4
427 ; CHECK2-NEXT:    call void @__kmpc_end_master(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
428 ; CHECK2-NEXT:    br label [[OMP_IF_END]]
429 ; CHECK2:       omp_if.end:
430 ; CHECK2-NEXT:    ret void
431 entry:
432   %tmp = load i32, ptr %.global_tid., align 4
433   %tmp1 = call i32 @__kmpc_master(ptr nonnull @0, i32 %tmp)
434   %tmp2 = icmp eq i32 %tmp1, 0
435   br i1 %tmp2, label %omp_if.end, label %omp_if.then
437 omp_if.then:                                      ; preds = %entry
438   %tmp3 = load i32, ptr %a, align 4
439   %inc = add nsw i32 %tmp3, 1
440   store i32 %inc, ptr %a, align 4
441   call void @__kmpc_end_master(ptr nonnull @0, i32 %tmp)
442   br label %omp_if.end
444 omp_if.end:                                       ; preds = %entry, %omp_if.then
445   ret void
448 declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
450 declare i32 @omp_get_thread_num() inaccessiblememonly nofree nosync nounwind readonly
452 declare i32 @__kmpc_master(ptr, i32)
454 declare void @__kmpc_end_master(ptr, i32)
456 define internal void @.omp_outlined..5(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
457 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
458 ; CHECK-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
459 ; CHECK-NEXT:  entry:
460 ; CHECK-NEXT:    [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR19]]
461 ; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
462 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
463 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
464 ; CHECK-NEXT:    br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
465 ; CHECK:       omp_if.then:
466 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[A]], align 4
467 ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
468 ; CHECK-NEXT:    store i32 [[INC]], ptr [[A]], align 4
469 ; CHECK-NEXT:    call void @__kmpc_end_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
470 ; CHECK-NEXT:    br label [[OMP_IF_END]]
471 ; CHECK:       omp_if.end:
472 ; CHECK-NEXT:    call void @__kmpc_barrier(ptr noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
473 ; CHECK-NEXT:    ret void
475 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..5
476 ; CHECK1-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
477 ; CHECK1-NEXT:  entry:
478 ; CHECK1-NEXT:    [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR14]]
479 ; CHECK1-NEXT:    [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
480 ; CHECK1-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
481 ; CHECK1-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
482 ; CHECK1-NEXT:    br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
483 ; CHECK1:       omp_if.then:
484 ; CHECK1-NEXT:    [[TMP3:%.*]] = load i32, ptr [[A]], align 4
485 ; CHECK1-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
486 ; CHECK1-NEXT:    store i32 [[INC]], ptr [[A]], align 4
487 ; CHECK1-NEXT:    call void @__kmpc_end_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
488 ; CHECK1-NEXT:    br label [[OMP_IF_END]]
489 ; CHECK1:       omp_if.end:
490 ; CHECK1-NEXT:    call void @__kmpc_barrier(ptr noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
491 ; CHECK1-NEXT:    ret void
492 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..5
493 ; CHECK2-SAME: (ptr noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
494 ; CHECK2-NEXT:  entry:
495 ; CHECK2-NEXT:    [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR14]]
496 ; CHECK2-NEXT:    [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
497 ; CHECK2-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
498 ; CHECK2-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
499 ; CHECK2-NEXT:    br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
500 ; CHECK2:       omp_if.then:
501 ; CHECK2-NEXT:    [[TMP3:%.*]] = load i32, ptr [[A]], align 4
502 ; CHECK2-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
503 ; CHECK2-NEXT:    store i32 [[INC]], ptr [[A]], align 4
504 ; CHECK2-NEXT:    call void @__kmpc_end_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
505 ; CHECK2-NEXT:    br label [[OMP_IF_END]]
506 ; CHECK2:       omp_if.end:
507 ; CHECK2-NEXT:    call void @__kmpc_barrier(ptr noundef nonnull @[[GLOB1:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM]])
508 ; CHECK2-NEXT:    ret void
509 entry:
510   %omp_global_thread_num = call i32 @__kmpc_global_thread_num(ptr nonnull @0)
511   %tmp = load i32, ptr %.global_tid., align 4
512   %tmp1 = call i32 @__kmpc_single(ptr nonnull @0, i32 %tmp)
513   %tmp2 = icmp eq i32 %tmp1, 0
514   br i1 %tmp2, label %omp_if.end, label %omp_if.then
516 omp_if.then:                                      ; preds = %entry
517   %tmp3 = load i32, ptr %a, align 4
518   %inc = add nsw i32 %tmp3, 1
519   store i32 %inc, ptr %a, align 4
520   call void @__kmpc_end_single(ptr nonnull @0, i32 %tmp)
521   br label %omp_if.end
523 omp_if.end:                                       ; preds = %entry, %omp_if.then
524   call void @__kmpc_barrier(ptr nonnull @1, i32 %omp_global_thread_num) #6
525   ret void
528 define internal void @.omp_outlined..6(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
529 ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
530 ; CHECK-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
531 ; CHECK-NEXT:  entry:
532 ; CHECK-NEXT:    [[A1:%.*]] = alloca i32, align 4
533 ; CHECK-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
534 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 [[A1]]) #[[ATTR20:[0-9]+]]
535 ; CHECK-NEXT:    store i32 1, ptr [[A1]], align 4
536 ; CHECK-NEXT:    store ptr [[A1]], ptr [[DOTOMP_REDUCTION_RED_LIST]], align 8
537 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
538 ; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(ptr noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, ptr noundef nonnull align 8 [[DOTOMP_REDUCTION_RED_LIST]], ptr noundef nonnull @.omp.reduction.reduction_func, ptr noundef nonnull @.gomp_critical_user_.reduction.var)
539 ; CHECK-NEXT:    switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
540 ; CHECK-NEXT:      i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
541 ; CHECK-NEXT:      i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
542 ; CHECK-NEXT:    ]
543 ; CHECK:       .omp.reduction.case1:
544 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[A]], align 4
545 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[A1]], align 4
546 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
547 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[A]], align 4
548 ; CHECK-NEXT:    call void @__kmpc_end_reduce_nowait(ptr noundef nonnull @[[GLOB2]], i32 [[TMP2]], ptr noundef nonnull @.gomp_critical_user_.reduction.var)
549 ; CHECK-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
550 ; CHECK:       .omp.reduction.case2:
551 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[A1]], align 4
552 ; CHECK-NEXT:    [[TMP8:%.*]] = atomicrmw add ptr [[A]], i32 [[TMP7]] monotonic, align 4
553 ; CHECK-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
554 ; CHECK:       .omp.reduction.default:
555 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A1]])
556 ; CHECK-NEXT:    ret void
558 ; CHECK1-LABEL: define {{[^@]+}}@.omp_outlined..6
559 ; CHECK1-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
560 ; CHECK1-NEXT:  entry:
561 ; CHECK1-NEXT:    [[A1:%.*]] = alloca i32, align 4
562 ; CHECK1-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
563 ; CHECK1-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 [[A1]]) #[[ATTR0]]
564 ; CHECK1-NEXT:    store i32 1, ptr [[A1]], align 4
565 ; CHECK1-NEXT:    store ptr [[A1]], ptr [[DOTOMP_REDUCTION_RED_LIST]], align 8
566 ; CHECK1-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
567 ; CHECK1-NEXT:    [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(ptr noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, ptr noundef nonnull align 8 [[DOTOMP_REDUCTION_RED_LIST]], ptr noundef nonnull @.omp.reduction.reduction_func, ptr noundef nonnull @.gomp_critical_user_.reduction.var)
568 ; CHECK1-NEXT:    switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
569 ; CHECK1-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
570 ; CHECK1-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
571 ; CHECK1-NEXT:    ]
572 ; CHECK1:       .omp.reduction.case1:
573 ; CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[A]], align 4
574 ; CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[A1]], align 4
575 ; CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
576 ; CHECK1-NEXT:    store i32 [[ADD]], ptr [[A]], align 4
577 ; CHECK1-NEXT:    call void @__kmpc_end_reduce_nowait(ptr noundef nonnull @[[GLOB2]], i32 [[TMP2]], ptr noundef nonnull @.gomp_critical_user_.reduction.var)
578 ; CHECK1-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
579 ; CHECK1:       .omp.reduction.case2:
580 ; CHECK1-NEXT:    [[TMP7:%.*]] = load i32, ptr [[A1]], align 4
581 ; CHECK1-NEXT:    [[TMP8:%.*]] = atomicrmw add ptr [[A]], i32 [[TMP7]] monotonic, align 4
582 ; CHECK1-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
583 ; CHECK1:       .omp.reduction.default:
584 ; CHECK1-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A1]])
585 ; CHECK1-NEXT:    ret void
586 ; CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..6
587 ; CHECK2-SAME: (ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], ptr nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
588 ; CHECK2-NEXT:  entry:
589 ; CHECK2-NEXT:    [[A1:%.*]] = alloca i32, align 4
590 ; CHECK2-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
591 ; CHECK2-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noundef nonnull align 4 [[A1]]) #[[ATTR0]]
592 ; CHECK2-NEXT:    store i32 1, ptr [[A1]], align 4
593 ; CHECK2-NEXT:    store ptr [[A1]], ptr [[DOTOMP_REDUCTION_RED_LIST]], align 8
594 ; CHECK2-NEXT:    [[TMP2:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4
595 ; CHECK2-NEXT:    [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(ptr noundef nonnull @[[GLOB2:[0-9]+]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, ptr noundef nonnull align 8 [[DOTOMP_REDUCTION_RED_LIST]], ptr noundef nonnull @.omp.reduction.reduction_func, ptr noundef nonnull @.gomp_critical_user_.reduction.var)
596 ; CHECK2-NEXT:    switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
597 ; CHECK2-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
598 ; CHECK2-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
599 ; CHECK2-NEXT:    ]
600 ; CHECK2:       .omp.reduction.case1:
601 ; CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[A]], align 4
602 ; CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[A1]], align 4
603 ; CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
604 ; CHECK2-NEXT:    store i32 [[ADD]], ptr [[A]], align 4
605 ; CHECK2-NEXT:    call void @__kmpc_end_reduce_nowait(ptr noundef nonnull @[[GLOB2]], i32 [[TMP2]], ptr noundef nonnull @.gomp_critical_user_.reduction.var)
606 ; CHECK2-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
607 ; CHECK2:       .omp.reduction.case2:
608 ; CHECK2-NEXT:    [[TMP7:%.*]] = load i32, ptr [[A1]], align 4
609 ; CHECK2-NEXT:    [[TMP8:%.*]] = atomicrmw add ptr [[A]], i32 [[TMP7]] monotonic, align 4
610 ; CHECK2-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
611 ; CHECK2:       .omp.reduction.default:
612 ; CHECK2-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noundef nonnull [[A1]])
613 ; CHECK2-NEXT:    ret void
614 entry:
615   %a1 = alloca i32, align 4
616   %.omp.reduction.red_list = alloca [1 x ptr], align 8
617   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %a1)
618   store i32 1, ptr %a1, align 4
619   store ptr %a1, ptr %.omp.reduction.red_list, align 8
620   %tmp2 = load i32, ptr %.global_tid., align 4
621   %tmp4 = call i32 @__kmpc_reduce_nowait(ptr nonnull @2, i32 %tmp2, i32 1, i64 8, ptr nonnull %.omp.reduction.red_list, ptr nonnull @.omp.reduction.reduction_func, ptr nonnull @.gomp_critical_user_.reduction.var)
622   switch i32 %tmp4, label %.omp.reduction.default [
623   i32 1, label %.omp.reduction.case1
624   i32 2, label %.omp.reduction.case2
625   ]
627 .omp.reduction.case1:                             ; preds = %entry
628   %tmp5 = load i32, ptr %a, align 4
629   %tmp6 = load i32, ptr %a1, align 4
630   %add = add nsw i32 %tmp5, %tmp6
631   store i32 %add, ptr %a, align 4
632   call void @__kmpc_end_reduce_nowait(ptr nonnull @2, i32 %tmp2, ptr nonnull @.gomp_critical_user_.reduction.var)
633   br label %.omp.reduction.default
635 .omp.reduction.case2:                             ; preds = %entry
636   %tmp7 = load i32, ptr %a1, align 4
637   %tmp8 = atomicrmw add ptr %a, i32 %tmp7 monotonic
638   br label %.omp.reduction.default
640 .omp.reduction.default:                           ; preds = %.omp.reduction.case2, %.omp.reduction.case1, %entry
641   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %a1)
642   ret void
645 define internal void @.omp.reduction.reduction_func(ptr %arg, ptr %arg1) {
646 ; CHECK-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
647 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] {
648 ; CHECK-NEXT:  entry:
649 ; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[ARG1]], align 8
650 ; CHECK-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[ARG]], align 8
651 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
652 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP2]], align 4
653 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
654 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP4]], align 4
655 ; CHECK-NEXT:    ret void
657 ; CHECK1-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
658 ; CHECK1-SAME: (ptr nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], ptr nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] {
659 ; CHECK1-NEXT:  entry:
660 ; CHECK1-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[ARG1]], align 8
661 ; CHECK1-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[ARG]], align 8
662 ; CHECK1-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
663 ; CHECK1-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP2]], align 4
664 ; CHECK1-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
665 ; CHECK1-NEXT:    store i32 [[ADD]], ptr [[TMP4]], align 4
666 ; CHECK1-NEXT:    ret void
667 ; CHECK2-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
668 ; CHECK2-SAME: (ptr nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], ptr nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #[[ATTR10:[0-9]+]] {
669 ; CHECK2-NEXT:  entry:
670 ; CHECK2-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[ARG1]], align 8
671 ; CHECK2-NEXT:    [[TMP4:%.*]] = load ptr, ptr [[ARG]], align 8
672 ; CHECK2-NEXT:    [[TMP5:%.*]] = load i32, ptr [[TMP4]], align 4
673 ; CHECK2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[TMP2]], align 4
674 ; CHECK2-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
675 ; CHECK2-NEXT:    store i32 [[ADD]], ptr [[TMP4]], align 4
676 ; CHECK2-NEXT:    ret void
677 entry:
678   %tmp2 = load ptr, ptr %arg1, align 8
679   %tmp4 = load ptr, ptr %arg, align 8
680   %tmp5 = load i32, ptr %tmp4, align 4
681   %tmp6 = load i32, ptr %tmp2, align 4
682   %add = add nsw i32 %tmp5, %tmp6
683   store i32 %add, ptr %tmp4, align 4
684   ret void
687 declare i32 @__kmpc_single(ptr, i32)
689 declare void @__kmpc_end_single(ptr, i32)
691 declare void @__kmpc_barrier(ptr, i32)
693 declare i32 @__kmpc_global_thread_num(ptr) nofree nosync nounwind readonly
695 declare i32 @__kmpc_reduce_nowait(ptr, i32, i32, i64, ptr, ptr, ptr)
697 declare void @__kmpc_end_reduce_nowait(ptr, i32, ptr)
699 declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
701 declare !callback !2 void @__kmpc_fork_call(ptr, i32, ptr, ...)
703 declare void @unknown()
705 declare void @readonly() readonly
707 declare void @readnone() readnone
709 !llvm.module.flags = !{!8}
711 !0 = !{i32 1, !"wchar_size", i32 4}
712 !1 = !{!"clang"}
713 !2 = !{!3}
714 !3 = !{i64 2, i64 -1, i64 -1, i1 true}
715 !4 = !{!5, !5, i64 0}
716 !5 = !{!"int", !6, i64 0}
717 !6 = !{!"omnipotent char", !7, i64 0}
718 !7 = !{!"Simple C/C++ TBAA"}
719 !8 = !{i32 7, !"openmp", i32 50}