[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / Attributor / IPConstantProp / openmp_parallel_for.ll
blob950d7a27856acb87e9ad4c79d4dc393d44a0dac4
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4 ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
7 ;    void bar(int, float, double);
9 ;    void foo(int N) {
10 ;      float p = 3;
11 ;      double q = 5;
12 ;      N = 7;
14 ;    #pragma omp parallel for firstprivate(q)
15 ;      for (int i = 2; i < N; i++) {
16 ;        bar(i, p, q);
17 ;      }
18 ;    }
20 ; Verify the constant value of q is propagated into the outlined function.
22 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
24 %struct.ident_t = type { i32, i32, i32, i32, i8* }
26 @.str = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
27 @0 = private unnamed_addr global %struct.ident_t { i32 0, i32 514, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8
28 @1 = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8
31 ; CHECK: @[[_STR:[a-zA-Z0-9_$"\\.-]+]] = private unnamed_addr constant [23 x i8] c"
32 ; CHECK: @[[GLOB0:[0-9]+]] = private unnamed_addr global [[STRUCT_IDENT_T:%.*]] { i32 0, i32 514, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8
33 ; CHECK: @[[GLOB1:[0-9]+]] = private unnamed_addr global [[STRUCT_IDENT_T:%.*]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32 0) }, align 8
35 define dso_local void @foo(i32 %N) {
36 ; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@foo
37 ; IS__TUNIT_OPM-SAME: (i32 [[N:%.*]]) {
38 ; IS__TUNIT_OPM-NEXT:  entry:
39 ; IS__TUNIT_OPM-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
40 ; IS__TUNIT_OPM-NEXT:    [[P:%.*]] = alloca float, align 4
41 ; IS__TUNIT_OPM-NEXT:    store i32 [[N]], i32* [[N_ADDR]], align 4
42 ; IS__TUNIT_OPM-NEXT:    store float 3.000000e+00, float* [[P]], align 4
43 ; IS__TUNIT_OPM-NEXT:    store i32 7, i32* [[N_ADDR]], align 4
44 ; IS__TUNIT_OPM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef)
45 ; IS__TUNIT_OPM-NEXT:    ret void
47 ; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@foo
48 ; IS__TUNIT_NPM-SAME: (i32 [[N:%.*]]) {
49 ; IS__TUNIT_NPM-NEXT:  entry:
50 ; IS__TUNIT_NPM-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
51 ; IS__TUNIT_NPM-NEXT:    [[P:%.*]] = alloca float, align 4
52 ; IS__TUNIT_NPM-NEXT:    store i32 [[N]], i32* [[N_ADDR]], align 4
53 ; IS__TUNIT_NPM-NEXT:    store float 3.000000e+00, float* [[P]], align 4
54 ; IS__TUNIT_NPM-NEXT:    store i32 7, i32* [[N_ADDR]], align 4
55 ; IS__TUNIT_NPM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]], i64 undef)
56 ; IS__TUNIT_NPM-NEXT:    ret void
58 ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo
59 ; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) {
60 ; IS__CGSCC_OPM-NEXT:  entry:
61 ; IS__CGSCC_OPM-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
62 ; IS__CGSCC_OPM-NEXT:    [[P:%.*]] = alloca float, align 4
63 ; IS__CGSCC_OPM-NEXT:    store i32 [[N]], i32* [[N_ADDR]], align 4
64 ; IS__CGSCC_OPM-NEXT:    store float 3.000000e+00, float* [[P]], align 4
65 ; IS__CGSCC_OPM-NEXT:    store i32 7, i32* [[N_ADDR]], align 4
66 ; IS__CGSCC_OPM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]], i64 noundef 4617315517961601024)
67 ; IS__CGSCC_OPM-NEXT:    ret void
69 ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo
70 ; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) {
71 ; IS__CGSCC_NPM-NEXT:  entry:
72 ; IS__CGSCC_NPM-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
73 ; IS__CGSCC_NPM-NEXT:    [[P:%.*]] = alloca float, align 4
74 ; IS__CGSCC_NPM-NEXT:    store i32 [[N]], i32* [[N_ADDR]], align 4
75 ; IS__CGSCC_NPM-NEXT:    store float 3.000000e+00, float* [[P]], align 4
76 ; IS__CGSCC_NPM-NEXT:    store i32 7, i32* [[N_ADDR]], align 4
77 ; IS__CGSCC_NPM-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB1]], i32 noundef 3, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N_ADDR]], float* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P]], i64 noundef 4617315517961601024)
78 ; IS__CGSCC_NPM-NEXT:    ret void
80 entry:
81   %N.addr = alloca i32, align 4
82   %p = alloca float, align 4
83   store i32 %N, i32* %N.addr, align 4
84   store float 3.000000e+00, float* %p, align 4
85   store i32 7, i32* %N.addr, align 4
86   call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull @1, i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* nonnull %N.addr, float* nonnull %p, i64 4617315517961601024)
87   ret void
90 define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %N, float* dereferenceable(4) %p, i64 %q) {
91 ; IS________OPM-LABEL: define {{[^@]+}}@.omp_outlined.
92 ; IS________OPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) {
93 ; IS________OPM-NEXT:  entry:
94 ; IS________OPM-NEXT:    [[Q_ADDR:%.*]] = alloca i64, align 8
95 ; IS________OPM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
96 ; IS________OPM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
97 ; IS________OPM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
98 ; IS________OPM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
99 ; IS________OPM-NEXT:    store i64 4617315517961601024, i64* [[Q_ADDR]], align 8
100 ; IS________OPM-NEXT:    [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double*
101 ; IS________OPM-NEXT:    [[TMP:%.*]] = load i32, i32* [[N]], align 4
102 ; IS________OPM-NEXT:    [[SUB3:%.*]] = add nsw i32 [[TMP]], -3
103 ; IS________OPM-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2
104 ; IS________OPM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
105 ; IS________OPM:       omp.precond.then:
106 ; IS________OPM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
107 ; IS________OPM-NEXT:    store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4
108 ; IS________OPM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
109 ; IS________OPM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
110 ; IS________OPM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
111 ; IS________OPM-NEXT:    call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1)
112 ; IS________OPM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
113 ; IS________OPM-NEXT:    [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]]
114 ; IS________OPM-NEXT:    br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
115 ; IS________OPM:       cond.true:
116 ; IS________OPM-NEXT:    br label [[COND_END:%.*]]
117 ; IS________OPM:       cond.false:
118 ; IS________OPM-NEXT:    [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
119 ; IS________OPM-NEXT:    br label [[COND_END]]
120 ; IS________OPM:       cond.end:
121 ; IS________OPM-NEXT:    [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ]
122 ; IS________OPM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
123 ; IS________OPM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
124 ; IS________OPM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
125 ; IS________OPM:       omp.inner.for.cond:
126 ; IS________OPM-NEXT:    [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ]
127 ; IS________OPM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
128 ; IS________OPM-NEXT:    [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]]
129 ; IS________OPM-NEXT:    br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]]
130 ; IS________OPM:       omp.inner.for.cond.cleanup:
131 ; IS________OPM-NEXT:    br label [[OMP_INNER_FOR_END:%.*]]
132 ; IS________OPM:       omp.inner.for.body:
133 ; IS________OPM-NEXT:    [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
134 ; IS________OPM-NEXT:    [[TMP10:%.*]] = load float, float* [[P]], align 4
135 ; IS________OPM-NEXT:    [[TMP11:%.*]] = load double, double* [[CONV]], align 8
136 ; IS________OPM-NEXT:    call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]])
137 ; IS________OPM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
138 ; IS________OPM:       omp.body.continue:
139 ; IS________OPM-NEXT:    br label [[OMP_INNER_FOR_INC]]
140 ; IS________OPM:       omp.inner.for.inc:
141 ; IS________OPM-NEXT:    [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1
142 ; IS________OPM-NEXT:    br label [[OMP_INNER_FOR_COND]]
143 ; IS________OPM:       omp.inner.for.end:
144 ; IS________OPM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
145 ; IS________OPM:       omp.loop.exit:
146 ; IS________OPM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
147 ; IS________OPM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 [[TMP12]])
148 ; IS________OPM-NEXT:    br label [[OMP_PRECOND_END]]
149 ; IS________OPM:       omp.precond.end:
150 ; IS________OPM-NEXT:    ret void
152 ; IS________NPM-LABEL: define {{[^@]+}}@.omp_outlined.
153 ; IS________NPM-SAME: (i32* noalias nocapture nofree readonly [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[N:%.*]], float* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]]) {
154 ; IS________NPM-NEXT:  entry:
155 ; IS________NPM-NEXT:    [[Q_ADDR:%.*]] = alloca i64, align 8
156 ; IS________NPM-NEXT:    [[DOTOMP_LB:%.*]] = alloca i32, align 4
157 ; IS________NPM-NEXT:    [[DOTOMP_UB:%.*]] = alloca i32, align 4
158 ; IS________NPM-NEXT:    [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
159 ; IS________NPM-NEXT:    [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
160 ; IS________NPM-NEXT:    store i64 4617315517961601024, i64* [[Q_ADDR]], align 8
161 ; IS________NPM-NEXT:    [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double*
162 ; IS________NPM-NEXT:    [[TMP:%.*]] = load i32, i32* [[N]], align 4
163 ; IS________NPM-NEXT:    [[SUB3:%.*]] = add nsw i32 [[TMP]], -3
164 ; IS________NPM-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2
165 ; IS________NPM-NEXT:    br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]]
166 ; IS________NPM:       omp.precond.then:
167 ; IS________NPM-NEXT:    store i32 0, i32* [[DOTOMP_LB]], align 4
168 ; IS________NPM-NEXT:    store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4
169 ; IS________NPM-NEXT:    store i32 1, i32* [[DOTOMP_STRIDE]], align 4
170 ; IS________NPM-NEXT:    store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
171 ; IS________NPM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
172 ; IS________NPM-NEXT:    call void @__kmpc_for_static_init_4(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 [[TMP5]], i32 noundef 34, i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_IS_LAST]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_LB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_UB]], i32* noundef nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]], i32 noundef 1, i32 noundef 1)
173 ; IS________NPM-NEXT:    [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
174 ; IS________NPM-NEXT:    [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]]
175 ; IS________NPM-NEXT:    br i1 [[CMP6]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
176 ; IS________NPM:       cond.true:
177 ; IS________NPM-NEXT:    br label [[COND_END:%.*]]
178 ; IS________NPM:       cond.false:
179 ; IS________NPM-NEXT:    [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
180 ; IS________NPM-NEXT:    br label [[COND_END]]
181 ; IS________NPM:       cond.end:
182 ; IS________NPM-NEXT:    [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]] ], [ [[TMP7]], [[COND_FALSE]] ]
183 ; IS________NPM-NEXT:    store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
184 ; IS________NPM-NEXT:    [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
185 ; IS________NPM-NEXT:    br label [[OMP_INNER_FOR_COND:%.*]]
186 ; IS________NPM:       omp.inner.for.cond:
187 ; IS________NPM-NEXT:    [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]], [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ]
188 ; IS________NPM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
189 ; IS________NPM-NEXT:    [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]], [[TMP9]]
190 ; IS________NPM-NEXT:    br i1 [[CMP8]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]]
191 ; IS________NPM:       omp.inner.for.cond.cleanup:
192 ; IS________NPM-NEXT:    br label [[OMP_INNER_FOR_END:%.*]]
193 ; IS________NPM:       omp.inner.for.body:
194 ; IS________NPM-NEXT:    [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
195 ; IS________NPM-NEXT:    [[TMP10:%.*]] = load float, float* [[P]], align 4
196 ; IS________NPM-NEXT:    [[TMP11:%.*]] = load double, double* [[CONV]], align 8
197 ; IS________NPM-NEXT:    call void @bar(i32 [[ADD10]], float [[TMP10]], double [[TMP11]])
198 ; IS________NPM-NEXT:    br label [[OMP_BODY_CONTINUE:%.*]]
199 ; IS________NPM:       omp.body.continue:
200 ; IS________NPM-NEXT:    br label [[OMP_INNER_FOR_INC]]
201 ; IS________NPM:       omp.inner.for.inc:
202 ; IS________NPM-NEXT:    [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1
203 ; IS________NPM-NEXT:    br label [[OMP_INNER_FOR_COND]]
204 ; IS________NPM:       omp.inner.for.end:
205 ; IS________NPM-NEXT:    br label [[OMP_LOOP_EXIT:%.*]]
206 ; IS________NPM:       omp.loop.exit:
207 ; IS________NPM-NEXT:    [[TMP12:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
208 ; IS________NPM-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 [[TMP12]])
209 ; IS________NPM-NEXT:    br label [[OMP_PRECOND_END]]
210 ; IS________NPM:       omp.precond.end:
211 ; IS________NPM-NEXT:    ret void
213 entry:
214   %q.addr = alloca i64, align 8
215   %.omp.lb = alloca i32, align 4
216   %.omp.ub = alloca i32, align 4
217   %.omp.stride = alloca i32, align 4
218   %.omp.is_last = alloca i32, align 4
219   store i64 %q, i64* %q.addr, align 8
220   %conv = bitcast i64* %q.addr to double*
221   %tmp = load i32, i32* %N, align 4
222   %sub3 = add nsw i32 %tmp, -3
223   %cmp = icmp sgt i32 %tmp, 2
224   br i1 %cmp, label %omp.precond.then, label %omp.precond.end
226 omp.precond.then:                                 ; preds = %entry
227   store i32 0, i32* %.omp.lb, align 4
228   store i32 %sub3, i32* %.omp.ub, align 4
229   store i32 1, i32* %.omp.stride, align 4
230   store i32 0, i32* %.omp.is_last, align 4
231   %tmp5 = load i32, i32* %.global_tid., align 4
232   call void @__kmpc_for_static_init_4(%struct.ident_t* nonnull @0, i32 %tmp5, i32 34, i32* nonnull %.omp.is_last, i32* nonnull %.omp.lb, i32* nonnull %.omp.ub, i32* nonnull %.omp.stride, i32 1, i32 1)
233   %tmp6 = load i32, i32* %.omp.ub, align 4
234   %cmp6 = icmp sgt i32 %tmp6, %sub3
235   br i1 %cmp6, label %cond.true, label %cond.false
237 cond.true:                                        ; preds = %omp.precond.then
238   br label %cond.end
240 cond.false:                                       ; preds = %omp.precond.then
241   %tmp7 = load i32, i32* %.omp.ub, align 4
242   br label %cond.end
244 cond.end:                                         ; preds = %cond.false, %cond.true
245   %cond = phi i32 [ %sub3, %cond.true ], [ %tmp7, %cond.false ]
246   store i32 %cond, i32* %.omp.ub, align 4
247   %tmp8 = load i32, i32* %.omp.lb, align 4
248   br label %omp.inner.for.cond
250 omp.inner.for.cond:                               ; preds = %omp.inner.for.inc, %cond.end
251   %.omp.iv.0 = phi i32 [ %tmp8, %cond.end ], [ %add11, %omp.inner.for.inc ]
252   %tmp9 = load i32, i32* %.omp.ub, align 4
253   %cmp8 = icmp sgt i32 %.omp.iv.0, %tmp9
254   br i1 %cmp8, label %omp.inner.for.cond.cleanup, label %omp.inner.for.body
256 omp.inner.for.cond.cleanup:                       ; preds = %omp.inner.for.cond
257   br label %omp.inner.for.end
259 omp.inner.for.body:                               ; preds = %omp.inner.for.cond
260   %add10 = add nsw i32 %.omp.iv.0, 2
261   %tmp10 = load float, float* %p, align 4
262   %tmp11 = load double, double* %conv, align 8
263   call void @bar(i32 %add10, float %tmp10, double %tmp11)
264   br label %omp.body.continue
266 omp.body.continue:                                ; preds = %omp.inner.for.body
267   br label %omp.inner.for.inc
269 omp.inner.for.inc:                                ; preds = %omp.body.continue
270   %add11 = add nsw i32 %.omp.iv.0, 1
271   br label %omp.inner.for.cond
273 omp.inner.for.end:                                ; preds = %omp.inner.for.cond.cleanup
274   br label %omp.loop.exit
276 omp.loop.exit:                                    ; preds = %omp.inner.for.end
277   %tmp12 = load i32, i32* %.global_tid., align 4
278   call void @__kmpc_for_static_fini(%struct.ident_t* nonnull @0, i32 %tmp12)
279   br label %omp.precond.end
281 omp.precond.end:                                  ; preds = %omp.loop.exit, %entry
282   ret void
285 declare dso_local void @__kmpc_for_static_init_4(%struct.ident_t*, i32, i32, i32*, i32*, i32*, i32*, i32, i32)
287 declare dso_local void @bar(i32, float, double)
289 declare dso_local void @__kmpc_for_static_fini(%struct.ident_t*, i32)
291 declare !callback !0 dso_local void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...)
293 !1 = !{i64 2, i64 -1, i64 -1, i1 true}
294 !0 = !{!1}
296 ; CHECK: [[META0:![0-9]+]] = !{!1}
297 ; CHECK: [[META1:![0-9]+]] = !{i64 2, i64 -1, i64 -1, i1 true}