1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs
2 // Check that the CHECK lines are generated for clang-generated functions
3 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck --check-prefix=OMP %s
4 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck --check-prefix=NOOMP %s
6 const int size = 1024 * 1024 * 32;
15 #pragma omp parallel for
16 for (i = 0; i < size; ++i) {
28 #pragma omp parallel for
29 for (i = 0; i < size; ++i) {
35 // OMP-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
36 // OMP-NEXT: [[I:%.*]] = alloca i32, align 4
37 // OMP-NEXT: store i32 0, ptr [[RETVAL]], align 4
38 // OMP-NEXT: store i32 0, ptr [[I]], align 4
39 // OMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2:[0-9]+]], i32 0, ptr @main.omp_outlined)
40 // OMP-NEXT: call void @foo()
41 // OMP-NEXT: ret i32 0
44 // OMP-LABEL: @main.omp_outlined(
46 // OMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
47 // OMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
48 // OMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
49 // OMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
50 // OMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
51 // OMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
52 // OMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
53 // OMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
54 // OMP-NEXT: [[I:%.*]] = alloca i32, align 4
55 // OMP-NEXT: store ptr [[DOTGLOBAL_TID_:%.*]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
56 // OMP-NEXT: store ptr [[DOTBOUND_TID_:%.*]], ptr [[DOTBOUND_TID__ADDR]], align 8
57 // OMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
58 // OMP-NEXT: store i32 33554431, ptr [[DOTOMP_UB]], align 4
59 // OMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
60 // OMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
61 // OMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
62 // OMP-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
63 // OMP-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
64 // OMP-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
65 // OMP-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431
66 // OMP-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
68 // OMP-NEXT: br label [[COND_END:%.*]]
70 // OMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
71 // OMP-NEXT: br label [[COND_END]]
73 // OMP-NEXT: [[COND:%.*]] = phi i32 [ 33554431, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
74 // OMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
75 // OMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
76 // OMP-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
77 // OMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
78 // OMP: omp.inner.for.cond:
79 // OMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
80 // OMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
81 // OMP-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
82 // OMP-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
83 // OMP: omp.inner.for.body:
84 // OMP-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
85 // OMP-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
86 // OMP-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
87 // OMP-NEXT: store i32 [[ADD]], ptr [[I]], align 4
88 // OMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[I]], align 4
89 // OMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP8]] to i64
90 // OMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], ptr @A, i64 0, i64 [[IDXPROM]]
91 // OMP-NEXT: store double 0.000000e+00, ptr [[ARRAYIDX]], align 8
92 // OMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
93 // OMP: omp.body.continue:
94 // OMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
95 // OMP: omp.inner.for.inc:
96 // OMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
97 // OMP-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1
98 // OMP-NEXT: store i32 [[ADD2]], ptr [[DOTOMP_IV]], align 4
99 // OMP-NEXT: br label [[OMP_INNER_FOR_COND]]
100 // OMP: omp.inner.for.end:
101 // OMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
102 // OMP: omp.loop.exit:
103 // OMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]])
104 // OMP-NEXT: ret void
109 // OMP-NEXT: [[I:%.*]] = alloca i32, align 4
110 // OMP-NEXT: store i32 0, ptr [[I]], align 4
111 // OMP-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB2]], i32 0, ptr @foo.omp_outlined)
112 // OMP-NEXT: ret void
115 // OMP-LABEL: @foo.omp_outlined(
117 // OMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8
118 // OMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8
119 // OMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
120 // OMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
121 // OMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
122 // OMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
123 // OMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
124 // OMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
125 // OMP-NEXT: [[I:%.*]] = alloca i32, align 4
126 // OMP-NEXT: store ptr [[DOTGLOBAL_TID_:%.*]], ptr [[DOTGLOBAL_TID__ADDR]], align 8
127 // OMP-NEXT: store ptr [[DOTBOUND_TID_:%.*]], ptr [[DOTBOUND_TID__ADDR]], align 8
128 // OMP-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4
129 // OMP-NEXT: store i32 33554431, ptr [[DOTOMP_UB]], align 4
130 // OMP-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4
131 // OMP-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4
132 // OMP-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8
133 // OMP-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4
134 // OMP-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1)
135 // OMP-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
136 // OMP-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431
137 // OMP-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
139 // OMP-NEXT: br label [[COND_END:%.*]]
141 // OMP-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
142 // OMP-NEXT: br label [[COND_END]]
144 // OMP-NEXT: [[COND:%.*]] = phi i32 [ 33554431, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
145 // OMP-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4
146 // OMP-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4
147 // OMP-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4
148 // OMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
149 // OMP: omp.inner.for.cond:
150 // OMP-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
151 // OMP-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4
152 // OMP-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
153 // OMP-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
154 // OMP: omp.inner.for.body:
155 // OMP-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
156 // OMP-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
157 // OMP-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
158 // OMP-NEXT: store i32 [[ADD]], ptr [[I]], align 4
159 // OMP-NEXT: [[TMP8:%.*]] = load i32, ptr [[I]], align 4
160 // OMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP8]] to i64
161 // OMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], ptr @A, i64 0, i64 [[IDXPROM]]
162 // OMP-NEXT: store double 1.000000e+00, ptr [[ARRAYIDX]], align 8
163 // OMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
164 // OMP: omp.body.continue:
165 // OMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
166 // OMP: omp.inner.for.inc:
167 // OMP-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4
168 // OMP-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1
169 // OMP-NEXT: store i32 [[ADD2]], ptr [[DOTOMP_IV]], align 4
170 // OMP-NEXT: br label [[OMP_INNER_FOR_COND]]
171 // OMP: omp.inner.for.end:
172 // OMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
173 // OMP: omp.loop.exit:
174 // OMP-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]])
175 // OMP-NEXT: ret void
178 // NOOMP-LABEL: @main(
179 // NOOMP-NEXT: entry:
180 // NOOMP-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
181 // NOOMP-NEXT: [[I:%.*]] = alloca i32, align 4
182 // NOOMP-NEXT: store i32 0, ptr [[RETVAL]], align 4
183 // NOOMP-NEXT: store i32 0, ptr [[I]], align 4
184 // NOOMP-NEXT: store i32 0, ptr [[I]], align 4
185 // NOOMP-NEXT: br label [[FOR_COND:%.*]]
187 // NOOMP-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4
188 // NOOMP-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 33554432
189 // NOOMP-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
191 // NOOMP-NEXT: [[TMP1:%.*]] = load i32, ptr [[I]], align 4
192 // NOOMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64
193 // NOOMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], ptr @A, i64 0, i64 [[IDXPROM]]
194 // NOOMP-NEXT: store double 0.000000e+00, ptr [[ARRAYIDX]], align 8
195 // NOOMP-NEXT: br label [[FOR_INC:%.*]]
197 // NOOMP-NEXT: [[TMP2:%.*]] = load i32, ptr [[I]], align 4
198 // NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
199 // NOOMP-NEXT: store i32 [[INC]], ptr [[I]], align 4
200 // NOOMP-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
202 // NOOMP-NEXT: call void @foo()
203 // NOOMP-NEXT: ret i32 0
206 // NOOMP-LABEL: @foo(
207 // NOOMP-NEXT: entry:
208 // NOOMP-NEXT: [[I:%.*]] = alloca i32, align 4
209 // NOOMP-NEXT: store i32 0, ptr [[I]], align 4
210 // NOOMP-NEXT: store i32 0, ptr [[I]], align 4
211 // NOOMP-NEXT: br label [[FOR_COND:%.*]]
213 // NOOMP-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4
214 // NOOMP-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 33554432
215 // NOOMP-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
217 // NOOMP-NEXT: [[TMP1:%.*]] = load i32, ptr [[I]], align 4
218 // NOOMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64
219 // NOOMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], ptr @A, i64 0, i64 [[IDXPROM]]
220 // NOOMP-NEXT: store double 1.000000e+00, ptr [[ARRAYIDX]], align 8
221 // NOOMP-NEXT: br label [[FOR_INC:%.*]]
223 // NOOMP-NEXT: [[TMP2:%.*]] = load i32, ptr [[I]], align 4
224 // NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
225 // NOOMP-NEXT: store i32 [[INC]], ptr [[I]], align 4
226 // NOOMP-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
228 // NOOMP-NEXT: ret void