blob: 0801f631ee17c82493ab066a4b024c195300b538 [file] [log] [blame]
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001// Test host codegen.
2// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
3// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
4// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
5// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
6// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s
7// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
8
9// Test target codegen - host bc file has to be created first.
10// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc
11// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
12// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s
13// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
14// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc
15// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
16// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s
17// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
18
19// expected-no-diagnostics
20#ifndef HEADER
21#define HEADER
22
23// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
24// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
25// CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
26
27// CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
28// CHECK-DAG: [[S1:%.+]] = type { double }
29// CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 }
30// CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* }
31// CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* }
32
33// TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 }
34
George Rokos29d0f002017-05-27 03:03:13 +000035// CHECK-DAG: $[[REGFN:\.omp_offloading\..+]] = comdat
36
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +000037// We have 8 target regions, but only 7 that actually will generate offloading
38// code, only 6 will have mapped arguments, and only 4 have all-constant map
39// sizes.
40
41// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 2]
42// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
43// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
44// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 288]
45// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [9 x i32] [i32 288, i32 35, i32 288, i32 35, i32 35, i32 288, i32 288, i32 35, i32 35]
46// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 40]
47// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i32] [i32 288, i32 288, i32 35]
48// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [4 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2, i[[SZ]] 1, i[[SZ]] 40]
49// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [4 x i32] [i32 288, i32 288, i32 288, i32 35]
50// CHECK-DAG: [[MAPT7:@.+]] = private unnamed_addr constant [5 x i32] [i32 35, i32 288, i32 288, i32 288, i32 35]
51// CHECK-DAG: @{{.*}} = private constant i8 0
52// CHECK-DAG: @{{.*}} = private constant i8 0
53// CHECK-DAG: @{{.*}} = private constant i8 0
54// CHECK-DAG: @{{.*}} = private constant i8 0
55// CHECK-DAG: @{{.*}} = private constant i8 0
56// CHECK-DAG: @{{.*}} = private constant i8 0
57// CHECK-DAG: @{{.*}} = private constant i8 0
58
59// TCHECK: @{{.+}} = constant [[ENTTY]]
60// TCHECK: @{{.+}} = constant [[ENTTY]]
61// TCHECK: @{{.+}} = constant [[ENTTY]]
62// TCHECK: @{{.+}} = constant [[ENTTY]]
63// TCHECK: @{{.+}} = constant [[ENTTY]]
64// TCHECK: @{{.+}} = constant [[ENTTY]]
65// TCHECK: @{{.+}} = constant [[ENTTY]]
66// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
67
68// Check if offloading descriptor is created.
69// CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]]
70// CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]]
71// CHECK: [[DEVBEGIN:@.+]] = external constant i8
72// CHECK: [[DEVEND:@.+]] = external constant i8
George Rokos29d0f002017-05-27 03:03:13 +000073// CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }], comdat($[[REGFN]])
74// CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }, comdat($[[REGFN]])
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +000075
76// Check target registration is registered as a Ctor.
George Rokos29d0f002017-05-27 03:03:13 +000077// CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* @[[REGFN]] to void ()*), i8* bitcast (void (i8*)* @[[REGFN]] to i8*) }]
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +000078
79
80template<typename tx, typename ty>
81struct TT{
82 tx X;
83 ty Y;
84};
85
86// CHECK: define {{.*}}[[FOO:@.+]](
87int foo(int n) {
88 int a = 0;
89 short aa = 0;
90 float b[10];
91 float bn[n];
92 double c[5][10];
93 double cn[5][n];
94 TT<long long, char> d;
95
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000096 // CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i32* null, i32 1, i32 0)
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +000097 // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
98 // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
99 // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
100 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
101 // CHECK: [[FAIL]]
102 // CHECK: call void [[HVT0:@.+]]()
103 // CHECK-NEXT: br label %[[END]]
104 // CHECK: [[END]]
105 #pragma omp target parallel
106 {
107 }
108
109 // CHECK: store i32 0, i32* [[RHV:%.+]], align 4
110 // CHECK: store i32 -1, i32* [[RHV]], align 4
111 // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
112 // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
113 // CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}})
114 #pragma omp target parallel if(target: 0)
115 {
116 a += 1;
117 }
118
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +0000119 // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i32* getelementptr inbounds ([1 x i32], [1 x i32]* [[MAPT2]], i32 0, i32 0), i32 1, i32 0)
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000120 // CHECK-DAG: [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
121 // CHECK-DAG: [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
122 // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
123 // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR]], i32 0, i32 [[IDX0]]
124 // CHECK-DAG: store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
125 // CHECK-DAG: store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
126 // CHECK-DAG: [[BP0]] = inttoptr i[[SZ]] %{{.+}} to i8*
127 // CHECK-DAG: [[P0]] = inttoptr i[[SZ]] %{{.+}} to i8*
128
129 // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
130 // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
131 // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
132 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
133 // CHECK: [[FAIL]]
134 // CHECK: call void [[HVT2:@.+]](i[[SZ]] {{[^,]+}})
135 // CHECK-NEXT: br label %[[END]]
136 // CHECK: [[END]]
137 #pragma omp target parallel if(target: 1)
138 {
139 aa += 1;
140 }
141
142 // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
143 // CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
144 // CHECK: [[IFTHEN]]
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +0000145 // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT3]], i32 0, i32 0), i32 1, i32 0)
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000146 // CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
147 // CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
148
149 // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
150 // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
151 // CHECK-DAG: store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
152 // CHECK-DAG: store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
153 // CHECK-DAG: [[BP0]] = inttoptr i[[SZ]] %{{.+}} to i8*
154 // CHECK-DAG: [[P0]] = inttoptr i[[SZ]] %{{.+}} to i8*
155
156 // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
157 // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
158 // CHECK-DAG: store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]]
159 // CHECK-DAG: store i8* [[P1:%[^,]+]], i8** [[PADDR1]]
160 // CHECK-DAG: [[BP1]] = inttoptr i[[SZ]] %{{.+}} to i8*
161 // CHECK-DAG: [[P1]] = inttoptr i[[SZ]] %{{.+}} to i8*
162 // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
163 // CHECK-NEXT: br label %[[IFEND:.+]]
164
165 // CHECK: [[IFELSE]]
166 // CHECK: store i32 -1, i32* [[RHV]], align 4
167 // CHECK-NEXT: br label %[[IFEND:.+]]
168
169 // CHECK: [[IFEND]]
170 // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
171 // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
172 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
173 // CHECK: [[FAIL]]
174 // CHECK: call void [[HVT3:@.+]]({{[^,]+}}, {{[^,]+}})
175 // CHECK-NEXT: br label %[[END]]
176 // CHECK: [[END]]
177 #pragma omp target parallel if(target: n>10)
178 {
179 a += 1;
180 aa += 1;
181 }
182
183 // We capture 3 VLA sizes in this target region
184 // CHECK-64: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
185 // CHECK-64: [[A_ADDR:%.+]] = bitcast i[[SZ]]* [[A_CADDR:%.+]] to i32*
186 // CHECK-64: store i32 [[A_VAL]], i32* [[A_ADDR]],
187 // CHECK-64: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
188
189 // CHECK-32: [[A_VAL:%.+]] = load i32, i32* %{{.+}},
190 // CHECK-32: store i32 [[A_VAL]], i32* [[A_CADDR:%.+]],
191 // CHECK-32: [[A_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CADDR]],
192
193 // CHECK: [[BNSIZE:%.+]] = mul nuw i[[SZ]] [[VLA0:%.+]], 4
194 // CHECK: [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
195 // CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
196
197 // CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 20
198 // CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
199 // CHECK: [[TRY]]
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +0000200 // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([9 x i32], [9 x i32]* [[MAPT4]], i32 0, i32 0), i32 1, i32 0)
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000201 // CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
202 // CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
203 // CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
204
205 // CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX0:[0-9]+]]
206 // CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX0]]
207 // CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX0]]
208 // CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX1:[0-9]+]]
209 // CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX1]]
210 // CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX1]]
211 // CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX2:[0-9]+]]
212 // CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX2]]
213 // CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX2]]
214 // CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX3:[0-9]+]]
215 // CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX3]]
216 // CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX3]]
217 // CHECK-DAG: [[SADDR4:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX4:[0-9]+]]
218 // CHECK-DAG: [[BPADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX4]]
219 // CHECK-DAG: [[PADDR4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX4]]
220 // CHECK-DAG: [[SADDR5:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX5:[0-9]+]]
221 // CHECK-DAG: [[BPADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX5]]
222 // CHECK-DAG: [[PADDR5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX5]]
223 // CHECK-DAG: [[SADDR6:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX6:[0-9]+]]
224 // CHECK-DAG: [[BPADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX6]]
225 // CHECK-DAG: [[PADDR6:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX6]]
226 // CHECK-DAG: [[SADDR7:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX7:[0-9]+]]
227 // CHECK-DAG: [[BPADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX7]]
228 // CHECK-DAG: [[PADDR7:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX7]]
229 // CHECK-DAG: [[SADDR8:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S]], i32 0, i32 [[IDX8:[0-9]+]]
230 // CHECK-DAG: [[BPADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP]], i32 0, i32 [[IDX8]]
231 // CHECK-DAG: [[PADDR8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P]], i32 0, i32 [[IDX8]]
232
233 // The names below are not necessarily consistent with the names used for the
234 // addresses above as some are repeated.
235 // CHECK-DAG: [[BP0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
236 // CHECK-DAG: [[P0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
237 // CHECK-DAG: store i8* [[BP0]], i8** {{%[^,]+}}
238 // CHECK-DAG: store i8* [[P0]], i8** {{%[^,]+}}
239 // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
240
241 // CHECK-DAG: [[BP1:%[^,]+]] = inttoptr i[[SZ]] [[VLA1]] to i8*
242 // CHECK-DAG: [[P1:%[^,]+]] = inttoptr i[[SZ]] [[VLA1]] to i8*
243 // CHECK-DAG: store i8* [[BP1]], i8** {{%[^,]+}}
244 // CHECK-DAG: store i8* [[P1]], i8** {{%[^,]+}}
245 // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
246
247 // CHECK-DAG: store i8* inttoptr (i[[SZ]] 5 to i8*), i8** {{%[^,]+}}
248 // CHECK-DAG: store i8* inttoptr (i[[SZ]] 5 to i8*), i8** {{%[^,]+}}
249 // CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
250
251 // CHECK-DAG: [[BP3:%[^,]+]] = inttoptr i[[SZ]] [[A_CVAL]] to i8*
252 // CHECK-DAG: [[P3:%[^,]+]] = inttoptr i[[SZ]] [[A_CVAL]] to i8*
253 // CHECK-DAG: store i8* [[BP3]], i8** {{%[^,]+}}
254 // CHECK-DAG: store i8* [[P3]], i8** {{%[^,]+}}
255 // CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
256
257 // CHECK-DAG: [[BP4:%[^,]+]] = bitcast [10 x float]* %{{.+}} to i8*
258 // CHECK-DAG: [[P4:%[^,]+]] = bitcast [10 x float]* %{{.+}} to i8*
259 // CHECK-DAG: store i8* [[BP4]], i8** {{%[^,]+}}
260 // CHECK-DAG: store i8* [[P4]], i8** {{%[^,]+}}
261 // CHECK-DAG: store i[[SZ]] 40, i[[SZ]]* {{%[^,]+}}
262
263 // CHECK-DAG: [[BP5:%[^,]+]] = bitcast float* %{{.+}} to i8*
264 // CHECK-DAG: [[P5:%[^,]+]] = bitcast float* %{{.+}} to i8*
265 // CHECK-DAG: store i8* [[BP5]], i8** {{%[^,]+}}
266 // CHECK-DAG: store i8* [[P5]], i8** {{%[^,]+}}
267 // CHECK-DAG: store i[[SZ]] [[BNSIZE]], i[[SZ]]* {{%[^,]+}}
268
269 // CHECK-DAG: [[BP6:%[^,]+]] = bitcast [5 x [10 x double]]* %{{.+}} to i8*
270 // CHECK-DAG: [[P6:%[^,]+]] = bitcast [5 x [10 x double]]* %{{.+}} to i8*
271 // CHECK-DAG: store i8* [[BP6]], i8** {{%[^,]+}}
272 // CHECK-DAG: store i8* [[P6]], i8** {{%[^,]+}}
273 // CHECK-DAG: store i[[SZ]] 400, i[[SZ]]* {{%[^,]+}}
274
275 // CHECK-DAG: [[BP7:%[^,]+]] = bitcast double* %{{.+}} to i8*
276 // CHECK-DAG: [[P7:%[^,]+]] = bitcast double* %{{.+}} to i8*
277 // CHECK-DAG: store i8* [[BP7]], i8** {{%[^,]+}}
278 // CHECK-DAG: store i8* [[P7]], i8** {{%[^,]+}}
279 // CHECK-DAG: store i[[SZ]] [[CNSIZE]], i[[SZ]]* {{%[^,]+}}
280
281 // CHECK-DAG: [[BP8:%[^,]+]] = bitcast [[TT]]* %{{.+}} to i8*
282 // CHECK-DAG: [[P8:%[^,]+]] = bitcast [[TT]]* %{{.+}} to i8*
283 // CHECK-DAG: store i8* [[BP8]], i8** {{%[^,]+}}
284 // CHECK-DAG: store i8* [[P8]], i8** {{%[^,]+}}
285 // CHECK-DAG: store i[[SZ]] {{12|16}}, i[[SZ]]* {{%[^,]+}}
286
287 // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
288 // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
289 // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
290 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
291
292 // CHECK: [[FAIL]]
293 // CHECK: call void [[HVT4:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
294 // CHECK-NEXT: br label %[[END]]
295 // CHECK: [[END]]
296 #pragma omp target parallel if(target: n>20)
297 {
298 a += 1;
299 b[2] += 1.0;
300 bn[3] += 1.0;
301 c[1][2] += 1.0;
302 cn[1][3] += 1.0;
303 d.X += 1;
304 d.Y += 1;
305 }
306
307 return a;
308}
309
310// Check that the offloading functions are emitted and that the arguments are
311// correct and loaded correctly for the target regions in foo().
312
313// CHECK: define internal void [[HVT0]]()
314// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*))
315//
316//
317// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid.)
318// CHECK: ret void
319// CHECK-NEXT: }
320
321
322// CHECK: define internal void [[HVT1]](i[[SZ]] %{{.+}})
323// Create stack storage and store argument in there.
324// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
325// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
326// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
327// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
328// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
329// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
330// CHECK-64: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i32*
331// CHECK-64: store i32 [[AA]], i32* [[AA_C]], align
332// CHECK-32: store i32 [[AA]], i32* [[AA_CASTED]], align
333// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
334// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
335//
336//
337// CHECK: define internal {{.*}}void [[OMP_OUTLINED1]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
338// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
339// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
340// CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32*
341// CHECK-64: [[AA:%.+]] = load i32, i32* [[AA_CADDR]], align
342// CHECK-32: [[AA:%.+]] = load i32, i32* [[AA_ADDR]], align
343// CHECK: ret void
344// CHECK-NEXT: }
345
346// CHECK: define internal void [[HVT2]](i[[SZ]] %{{.+}})
347// Create stack storage and store argument in there.
348// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
349// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
350// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
351// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
352// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
353// CHECK: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
354// CHECK: store i16 [[AA]], i16* [[AA_C]], align
355// CHECK: [[PARAM:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
356// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]])* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM]])
357//
358//
359// CHECK: define internal {{.*}}void [[OMP_OUTLINED2]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}})
360// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
361// CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
362// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
363// CHECK: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
364// CHECK: ret void
365// CHECK-NEXT: }
366
367// CHECK: define internal void [[HVT3]]
368// Create stack storage and store argument in there.
369// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
370// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
371// CHECK: [[A_CASTED:%.+]] = alloca i[[SZ]], align
372// CHECK: [[AA_CASTED:%.+]] = alloca i[[SZ]], align
373// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
374// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
375// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
376// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
377// CHECK-64-DAG:[[A:%.+]] = load i32, i32* [[A_CADDR]], align
378// CHECK-32-DAG:[[A:%.+]] = load i32, i32* [[A_ADDR]], align
379// CHECK-64-DAG:[[A_C:%.+]] = bitcast i[[SZ]]* [[A_CASTED]] to i32*
380// CHECK-64-DAG:store i32 [[A]], i32* [[A_C]], align
381// CHECK-32-DAG:store i32 [[A]], i32* [[A_CASTED]], align
382// CHECK-DAG: [[AA:%.+]] = load i16, i16* [[AA_CADDR]], align
383// CHECK-DAG: [[AA_C:%.+]] = bitcast i[[SZ]]* [[AA_CASTED]] to i16*
384// CHECK-DAG: store i16 [[AA]], i16* [[AA_C]], align
385// CHECK-DAG: [[PARAM1:%.+]] = load i[[SZ]], i[[SZ]]* [[A_CASTED]], align
386// CHECK-DAG: [[PARAM2:%.+]] = load i[[SZ]], i[[SZ]]* [[AA_CASTED]], align
387// CHECK-DAG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]])* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[PARAM1]], i[[SZ]] [[PARAM2]])
388//
389//
390// CHECK: define internal {{.*}}void [[OMP_OUTLINED3]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}})
391// CHECK: [[A_ADDR:%.+]] = alloca i[[SZ]], align
392// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align
393// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[A_ADDR]], align
394// CHECK-DAG: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align
395// CHECK-64-DAG:[[A_CADDR:%.+]] = bitcast i[[SZ]]* [[A_ADDR]] to i32*
396// CHECK-DAG: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
397// CHECK: ret void
398// CHECK-NEXT: }
399
400// CHECK: define internal void [[HVT4]]
401// Create local storage for each capture.
402// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
403// CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]*
404// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
405// CHECK: [[LOCAL_BN:%.+]] = alloca float*
406// CHECK: [[LOCAL_C:%.+]] = alloca [5 x [10 x double]]*
407// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
408// CHECK: [[LOCAL_VLA3:%.+]] = alloca i[[SZ]]
409// CHECK: [[LOCAL_CN:%.+]] = alloca double*
410// CHECK: [[LOCAL_D:%.+]] = alloca [[TT]]*
411// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
412// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
413// CHECK-DAG: store [10 x float]* [[ARG_B:%.+]], [10 x float]** [[LOCAL_B]]
414// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
415// CHECK-DAG: store float* [[ARG_BN:%.+]], float** [[LOCAL_BN]]
416// CHECK-DAG: store [5 x [10 x double]]* [[ARG_C:%.+]], [5 x [10 x double]]** [[LOCAL_C]]
417// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
418// CHECK-DAG: store i[[SZ]] [[ARG_VLA3:%.+]], i[[SZ]]* [[LOCAL_VLA3]]
419// CHECK-DAG: store double* [[ARG_CN:%.+]], double** [[LOCAL_CN]]
420// CHECK-DAG: store [[TT]]* [[ARG_D:%.+]], [[TT]]** [[LOCAL_D]]
421
422// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
423// CHECK-DAG: [[REF_B:%.+]] = load [10 x float]*, [10 x float]** [[LOCAL_B]],
424// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
425// CHECK-DAG: [[REF_BN:%.+]] = load float*, float** [[LOCAL_BN]],
426// CHECK-DAG: [[REF_C:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[LOCAL_C]],
427// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
428// CHECK-DAG: [[VAL_VLA3:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA3]],
429// CHECK-DAG: [[REF_CN:%.+]] = load double*, double** [[LOCAL_CN]],
430// CHECK-DAG: [[REF_D:%.+]] = load [[TT]]*, [[TT]]** [[LOCAL_D]],
431
432// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
433// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
434// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
435// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
436// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
437// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
438
439// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 9, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], [10 x float]*, i[[SZ]], float*, [5 x [10 x double]]*, i[[SZ]], i[[SZ]], double*, [[TT]]*)* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], [10 x float]* [[REF_B]], i[[SZ]] [[VAL_VLA1]], float* [[REF_BN]], [5 x [10 x double]]* [[REF_C]], i[[SZ]] [[VAL_VLA2]], i[[SZ]] [[VAL_VLA3]], double* [[REF_CN]], [[TT]]* [[REF_D]])
440//
441//
442// CHECK: define internal {{.*}}void [[OMP_OUTLINED4]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, [10 x float]* {{.+}}, i[[SZ]] %{{.+}}, float* %{{.+}}, [5 x [10 x double]]* {{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, double* %{{.+}}, [[TT]]* {{.+}})
443// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
444
445template<typename tx>
446tx ftemplate(int n) {
447 tx a = 0;
448 short aa = 0;
449 tx b[10];
450
451 #pragma omp target parallel if(target: n>40)
452 {
453 a += 1;
454 aa += 1;
455 b[2] += 1;
456 }
457
458 return a;
459}
460
461static
462int fstatic(int n) {
463 int a = 0;
464 short aa = 0;
465 char aaa = 0;
466 int b[10];
467
468 #pragma omp target parallel if(target: n>50)
469 {
470 a += 1;
471 aa += 1;
472 aaa += 1;
473 b[2] += 1;
474 }
475
476 return a;
477}
478
479struct S1 {
480 double a;
481
482 int r1(int n){
483 int b = n+1;
484 short int c[2][n];
485
486 #pragma omp target parallel if(target: n>60)
487 {
488 this->a = (double)b + 1.5;
489 c[1][1] = ++a;
490 }
491
492 return c[1][1] + (int)b;
493 }
494};
495
496// CHECK: define {{.*}}@{{.*}}bar{{.*}}
497int bar(int n){
498 int a = 0;
499
500 // CHECK: call {{.*}}i32 [[FOO]](i32 {{.*}})
501 a += foo(n);
502
503 S1 S;
504 // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}})
505 a += S.r1(n);
506
507 // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}})
508 a += fstatic(n);
509
510 // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}})
511 a += ftemplate<int>(n);
512
513 return a;
514}
515
516//
517// CHECK: define {{.*}}[[FS1]]
518//
519// CHECK: i8* @llvm.stacksave()
520// CHECK-64: [[B_ADDR:%.+]] = bitcast i[[SZ]]* [[B_CADDR:%.+]] to i32*
521// CHECK-64: store i32 %{{.+}}, i32* [[B_ADDR]],
522// CHECK-64: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_CADDR]],
523
524// CHECK-32: store i32 %{{.+}}, i32* [[B_ADDR:%.+]],
525// CHECK-32: [[B_CVAL:%.+]] = load i[[SZ]], i[[SZ]]* [[B_ADDR]],
526
527// We capture 2 VLA sizes in this target region
528// CHECK: [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
529// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
530
531// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 60
532// CHECK: br i1 [[IF]], label %[[TRY:[^,]+]], label %[[FAIL:[^,]+]]
533// CHECK: [[TRY]]
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +0000534// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i32* getelementptr inbounds ([5 x i32], [5 x i32]* [[MAPT7]], i32 0, i32 0), i32 1, i32 0)
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000535// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
536// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
537// CHECK-DAG: [[SR]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
538// CHECK-DAG: [[SADDR0:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX0:[0-9]+]]
539// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX0]]
540// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX0]]
541// CHECK-DAG: [[SADDR1:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX1:[0-9]+]]
542// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX1]]
543// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX1]]
544// CHECK-DAG: [[SADDR2:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX2:[0-9]+]]
545// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX2]]
546// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX2]]
547// CHECK-DAG: [[SADDR3:%.+]] = getelementptr inbounds [5 x i[[SZ]]], [5 x i[[SZ]]]* [[S]], i32 [[IDX3:[0-9]+]]
548// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP]], i32 [[IDX3]]
549// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P]], i32 [[IDX3]]
550
551// The names below are not necessarily consistent with the names used for the
552// addresses above as some are repeated.
553// CHECK-DAG: [[BP0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
554// CHECK-DAG: [[P0:%[^,]+]] = inttoptr i[[SZ]] [[VLA0]] to i8*
555// CHECK-DAG: store i8* [[BP0]], i8** {{%[^,]+}}
556// CHECK-DAG: store i8* [[P0]], i8** {{%[^,]+}}
557// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
558
559// CHECK-DAG: store i8* inttoptr (i[[SZ]] 2 to i8*), i8** {{%[^,]+}}
560// CHECK-DAG: store i8* inttoptr (i[[SZ]] 2 to i8*), i8** {{%[^,]+}}
561// CHECK-DAG: store i[[SZ]] {{4|8}}, i[[SZ]]* {{%[^,]+}}
562
563// CHECK-DAG: [[BP2:%[^,]+]] = inttoptr i[[SZ]] [[B_CVAL]] to i8*
564// CHECK-DAG: [[P2:%[^,]+]] = inttoptr i[[SZ]] [[B_CVAL]] to i8*
565// CHECK-DAG: store i8* [[BP2]], i8** {{%[^,]+}}
566// CHECK-DAG: store i8* [[P2]], i8** {{%[^,]+}}
567// CHECK-DAG: store i[[SZ]] 4, i[[SZ]]* {{%[^,]+}}
568
569// CHECK-DAG: [[BP3:%[^,]+]] = bitcast [[S1]]* %{{.+}} to i8*
570// CHECK-DAG: [[P3:%[^,]+]] = bitcast [[S1]]* %{{.+}} to i8*
571// CHECK-DAG: store i8* [[BP3]], i8** {{%[^,]+}}
572// CHECK-DAG: store i8* [[P3]], i8** {{%[^,]+}}
573// CHECK-DAG: store i[[SZ]] 8, i[[SZ]]* {{%[^,]+}}
574
575// CHECK-DAG: [[BP4:%[^,]+]] = bitcast i16* %{{.+}} to i8*
576// CHECK-DAG: [[P4:%[^,]+]] = bitcast i16* %{{.+}} to i8*
577// CHECK-DAG: store i8* [[BP4]], i8** {{%[^,]+}}
578// CHECK-DAG: store i8* [[P4]], i8** {{%[^,]+}}
579// CHECK-DAG: store i[[SZ]] [[CSIZE]], i[[SZ]]* {{%[^,]+}}
580
581// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
582// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
583// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
584// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
585
586// CHECK: [[FAIL]]
587// CHECK: call void [[HVT7:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
588// CHECK-NEXT: br label %[[END]]
589// CHECK: [[END]]
590
591//
592// CHECK: define {{.*}}[[FSTATIC]]
593//
594// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
595// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
596// CHECK: [[IFTHEN]]
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +0000597// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i32* getelementptr inbounds ([4 x i32], [4 x i32]* [[MAPT6]], i32 0, i32 0), i32 1, i32 0)
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000598// CHECK-DAG: [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
599// CHECK-DAG: [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
600
601// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 0
602// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 0
603// CHECK-DAG: store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
604// CHECK-DAG: store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
605// CHECK-DAG: [[BP0]] = inttoptr i[[SZ]] [[VAL0:%.+]] to i8*
606// CHECK-DAG: [[P0]] = inttoptr i[[SZ]] [[VAL0]] to i8*
607
608// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 1
609// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 1
610// CHECK-DAG: store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]]
611// CHECK-DAG: store i8* [[P1:%[^,]+]], i8** [[PADDR1]]
612// CHECK-DAG: [[BP1]] = inttoptr i[[SZ]] [[VAL1:%.+]] to i8*
613// CHECK-DAG: [[P1]] = inttoptr i[[SZ]] [[VAL1]] to i8*
614
615// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 2
616// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 2
617// CHECK-DAG: store i8* [[BP2:%[^,]+]], i8** [[BPADDR2]]
618// CHECK-DAG: store i8* [[P2:%[^,]+]], i8** [[PADDR2]]
619
620// CHECK-DAG: [[BPADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP]], i32 0, i32 3
621// CHECK-DAG: [[PADDR3:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P]], i32 0, i32 3
622// CHECK-DAG: store i8* [[BP3:%[^,]+]], i8** [[BPADDR3]]
623// CHECK-DAG: store i8* [[P3:%[^,]+]], i8** [[PADDR3]]
624// CHECK-DAG: [[BP3]] = bitcast [10 x i32]* %{{.+}} to i8*
625// CHECK-DAG: [[P3]] = bitcast [10 x i32]* %{{.+}} to i8*
626
627// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
628// CHECK-NEXT: br label %[[IFEND:.+]]
629
630// CHECK: [[IFELSE]]
631// CHECK: store i32 -1, i32* [[RHV]], align 4
632// CHECK-NEXT: br label %[[IFEND:.+]]
633
634// CHECK: [[IFEND]]
635// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
636// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
637// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
638// CHECK: [[FAIL]]
639// CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
640// CHECK-NEXT: br label %[[END]]
641// CHECK: [[END]]
642
643//
644// CHECK: define {{.*}}[[FTEMPLATE]]
645//
646// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
647// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
648// CHECK: [[IFTHEN]]
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +0000649// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i32* getelementptr inbounds ([3 x i32], [3 x i32]* [[MAPT5]], i32 0, i32 0), i32 1, i32 0)
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +0000650// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
651// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
652
653// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0
654// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0
655// CHECK-DAG: store i8* [[BP0:%[^,]+]], i8** [[BPADDR0]]
656// CHECK-DAG: store i8* [[P0:%[^,]+]], i8** [[PADDR0]]
657// CHECK-DAG: [[BP0]] = inttoptr i[[SZ]] [[VAL0:%.+]] to i8*
658// CHECK-DAG: [[P0]] = inttoptr i[[SZ]] [[VAL0]] to i8*
659
660// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1
661// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1
662// CHECK-DAG: store i8* [[BP1:%[^,]+]], i8** [[BPADDR1]]
663// CHECK-DAG: store i8* [[P1:%[^,]+]], i8** [[PADDR1]]
664// CHECK-DAG: [[BP1]] = inttoptr i[[SZ]] [[VAL1:%.+]] to i8*
665// CHECK-DAG: [[P1]] = inttoptr i[[SZ]] [[VAL1]] to i8*
666
667// CHECK-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2
668// CHECK-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2
669// CHECK-DAG: store i8* [[BP2:%[^,]+]], i8** [[BPADDR2]]
670// CHECK-DAG: store i8* [[P2:%[^,]+]], i8** [[PADDR2]]
671// CHECK-DAG: [[BP2]] = bitcast [10 x i32]* %{{.+}} to i8*
672// CHECK-DAG: [[P2]] = bitcast [10 x i32]* %{{.+}} to i8*
673
674// CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 4
675// CHECK-NEXT: br label %[[IFEND:.+]]
676
677// CHECK: [[IFELSE]]
678// CHECK: store i32 -1, i32* [[RHV]], align 4
679// CHECK-NEXT: br label %[[IFEND:.+]]
680
681// CHECK: [[IFEND]]
682// CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 4
683// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0
684// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
685// CHECK: [[FAIL]]
686// CHECK: call void [[HVT5:@.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}})
687// CHECK-NEXT: br label %[[END]]
688// CHECK: [[END]]
689
690
691
692// Check that the offloading functions are emitted and that the arguments are
693// correct and loaded correctly for the target regions of the callees of bar().
694
695// CHECK: define internal void [[HVT7]]
696// Create local storage for each capture.
697// CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1]]*
698// CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]]
699// CHECK: [[LOCAL_VLA1:%.+]] = alloca i[[SZ]]
700// CHECK: [[LOCAL_VLA2:%.+]] = alloca i[[SZ]]
701// CHECK: [[LOCAL_C:%.+]] = alloca i16*
702// CHECK: [[LOCAL_B_CASTED:%.+]] = alloca i[[SZ]]
703// CHECK-DAG: store [[S1]]* [[ARG_THIS:%.+]], [[S1]]** [[LOCAL_THIS]]
704// CHECK-DAG: store i[[SZ]] [[ARG_B:%.+]], i[[SZ]]* [[LOCAL_B]]
705// CHECK-DAG: store i[[SZ]] [[ARG_VLA1:%.+]], i[[SZ]]* [[LOCAL_VLA1]]
706// CHECK-DAG: store i[[SZ]] [[ARG_VLA2:%.+]], i[[SZ]]* [[LOCAL_VLA2]]
707// CHECK-DAG: store i16* [[ARG_C:%.+]], i16** [[LOCAL_C]]
708// Store captures in the context.
709// CHECK-DAG: [[REF_THIS:%.+]] = load [[S1]]*, [[S1]]** [[LOCAL_THIS]],
710// CHECK-64-DAG:[[CONV_BP:%.+]] = bitcast i[[SZ]]* [[LOCAL_B]] to i32*
711// CHECK-DAG: [[VAL_VLA1:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA1]],
712// CHECK-DAG: [[VAL_VLA2:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_VLA2]],
713// CHECK-DAG: [[REF_C:%.+]] = load i16*, i16** [[LOCAL_C]],
714
715// CHECK-64-DAG:[[CONV_B:%.+]] = load i32, i32* [[CONV_BP]]
716// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_B_CASTED]] to i32*
717// CHECK-64-DAG:store i32 [[CONV_B]], i32* [[CONV]], align
718// CHECK-32-DAG:[[LOCAL_BV:%.+]] = load i32, i32* [[LOCAL_B]]
719// CHECK-32-DAG:store i32 [[LOCAL_BV]], i32* [[LOCAL_B_CASTED]], align
720// CHECK-DAG: [[REF_B:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_B_CASTED]],
721
722// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 5, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]], i[[SZ]], i[[SZ]], i16*)* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), [[S1]]* [[REF_THIS]], i[[SZ]] [[REF_B]], i[[SZ]] [[VAL_VLA1]], i[[SZ]] [[VAL_VLA2]], i16* [[REF_C]])
723//
724//
725// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* %{{.+}})
726// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
727
728
729// CHECK: define internal void [[HVT6]]
730// Create local storage for each capture.
731// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
732// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
733// CHECK: [[LOCAL_AAA:%.+]] = alloca i[[SZ]]
734// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
735// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
736// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
737// CHECK: [[LOCAL_AAA_CASTED:%.+]] = alloca i[[SZ]]
738// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
739// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
740// CHECK-DAG: store i[[SZ]] [[ARG_AAA:%.+]], i[[SZ]]* [[LOCAL_AAA]]
741// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
742// Store captures in the context.
743// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
744// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
745// CHECK-DAG: [[CONV_AAAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA]] to i8*
746// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
747
748// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
749// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
750// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
751// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
752// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
753// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
754
755// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
756// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
757// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
758// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
759
760// CHECK-DAG: [[CONV_AAA:%.+]] = load i8, i8* [[CONV_AAAP]]
761// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AAA_CASTED]] to i8*
762// CHECK-DAG: store i8 [[CONV_AAA]], i8* [[CONV]], align
763// CHECK-DAG: [[REF_AAA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AAA_CASTED]],
764
765// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED6:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], i[[SZ]] [[REF_AAA]], [10 x i32]* [[REF_B]])
766//
767//
768// CHECK: define internal {{.*}}void [[OMP_OUTLINED6]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
769// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
770
771// CHECK: define internal void [[HVT5]]
772// Create local storage for each capture.
773// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
774// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
775// CHECK: [[LOCAL_B:%.+]] = alloca [10 x i32]*
776// CHECK: [[LOCAL_A_CASTED:%.+]] = alloca i[[SZ]]
777// CHECK: [[LOCAL_AA_CASTED:%.+]] = alloca i[[SZ]]
778// CHECK-DAG: store i[[SZ]] [[ARG_A:%.+]], i[[SZ]]* [[LOCAL_A]]
779// CHECK-DAG: store i[[SZ]] [[ARG_AA:%.+]], i[[SZ]]* [[LOCAL_AA]]
780// CHECK-DAG: store [10 x i32]* [[ARG_B:%.+]], [10 x i32]** [[LOCAL_B]]
781// Store captures in the context.
782// CHECK-64-DAG:[[CONV_AP:%.+]] = bitcast i[[SZ]]* [[LOCAL_A]] to i32*
783// CHECK-DAG: [[CONV_AAP:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA]] to i16*
784// CHECK-DAG: [[REF_B:%.+]] = load [10 x i32]*, [10 x i32]** [[LOCAL_B]],
785
786// CHECK-64-DAG:[[CONV_A:%.+]] = load i32, i32* [[CONV_AP]]
787// CHECK-64-DAG:[[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_A_CASTED]] to i32*
788// CHECK-64-DAG:store i32 [[CONV_A]], i32* [[CONV]], align
789// CHECK-32-DAG:[[LOCAL_AV:%.+]] = load i32, i32* [[LOCAL_A]]
790// CHECK-32-DAG:store i32 [[LOCAL_AV]], i32* [[LOCAL_A_CASTED]], align
791// CHECK-DAG: [[REF_A:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_A_CASTED]],
792
793// CHECK-DAG: [[CONV_AA:%.+]] = load i16, i16* [[CONV_AAP]]
794// CHECK-DAG: [[CONV:%.+]] = bitcast i[[SZ]]* [[LOCAL_AA_CASTED]] to i16*
795// CHECK-DAG: store i16 [[CONV_AA]], i16* [[CONV]], align
796// CHECK-DAG: [[REF_AA:%.+]] = load i[[SZ]], i[[SZ]]* [[LOCAL_AA_CASTED]],
797
798// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]], [10 x i32]*)* [[OMP_OUTLINED7:@.+]] to void (i32*, i32*, ...)*), i[[SZ]] [[REF_A]], i[[SZ]] [[REF_AA]], [10 x i32]* [[REF_B]])
799//
800//
801// CHECK: define internal {{.*}}void [[OMP_OUTLINED7]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, [10 x i32]* {{.+}})
802// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
803
804#endif