forked from OSchip/llvm-project
[OPENMP] Fix PR35013: Fix passing VLAs captures to outlined functions.
Fixed passing of VLAs and variably-modified types to outlined functions. Synchronized passing with the types codegen. llvm-svn: 316488
This commit is contained in:
parent
95af9e654f
commit
1b48c5e56b
|
@ -254,6 +254,12 @@ static QualType getCanonicalParamType(ASTContext &C, QualType T) {
|
|||
}
|
||||
if (T->isPointerType())
|
||||
return C.getPointerType(getCanonicalParamType(C, T->getPointeeType()));
|
||||
if (auto *A = T->getAsArrayTypeUnsafe()) {
|
||||
if (auto *VLA = dyn_cast<VariableArrayType>(A))
|
||||
return getCanonicalParamType(C, VLA->getElementType());
|
||||
else if (!A->isVariablyModifiedType())
|
||||
return C.getCanonicalType(T);
|
||||
}
|
||||
return C.getCanonicalParamType(T);
|
||||
}
|
||||
|
||||
|
@ -327,7 +333,7 @@ static llvm::Function *emitOutlinedFunctionPrologue(
|
|||
II = &Ctx.Idents.get("vla");
|
||||
}
|
||||
if (ArgType->isVariablyModifiedType())
|
||||
ArgType = getCanonicalParamType(Ctx, ArgType.getNonReferenceType());
|
||||
ArgType = getCanonicalParamType(Ctx, ArgType);
|
||||
auto *Arg =
|
||||
ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr, FD->getLocation(), II,
|
||||
ArgType, ImplicitParamDecl::Other);
|
||||
|
|
|
@ -524,7 +524,7 @@ int main() {
|
|||
// CHECK: store float [[UP]], float* [[T_VAR1_LHS]],
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
|
||||
// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* {{.+}} %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
|
||||
|
||||
// Reduction list for runtime.
|
||||
// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
|
||||
|
@ -725,7 +725,7 @@ int main() {
|
|||
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
|
||||
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* {{.+}} %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
|
||||
|
||||
// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]],
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ int main() {
|
|||
// CHECK: fadd float 5.550000e+02, %
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
|
||||
// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* {{.+}} %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
|
||||
|
||||
// Reduction list for runtime.
|
||||
// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
|
||||
|
@ -503,7 +503,7 @@ int main() {
|
|||
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
|
||||
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* {{.+}} %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
|
||||
|
||||
// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]],
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ int main (int argc, char **argv) {
|
|||
// CHECK-DEBUG: ret i32
|
||||
// CHECK-DEBUG-NEXT: }
|
||||
|
||||
// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i{{[0-9]+}}{{.*}} [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]])
|
||||
// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i{{[0-9]+}}{{.*}} [[VLA_SIZE:%.+]], i32* {{.+}} [[VLA_ADDR:%[^)]+]])
|
||||
// CHECK-SAME: #[[FN_ATTRS:[0-9]+]]
|
||||
// CHECK: store i32* [[VLA_ADDR]], i32** [[VLA_PTR_ADDR:%.+]],
|
||||
// CHECK: [[VLA_REF:%.+]] = load i32*, i32** [[VLA_PTR_ADDR]]
|
||||
|
@ -64,7 +64,7 @@ int main (int argc, char **argv) {
|
|||
// CHECK: call {{.*}}void @{{.+terminate.*|abort}}(
|
||||
// CHECK-NEXT: unreachable
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-DEBUG: define internal void [[OMP_OUTLINED_DEBUG:@.+]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]])
|
||||
// CHECK-DEBUG: define internal void [[OMP_OUTLINED_DEBUG:@.+]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* {{.+}} [[VLA_ADDR:%[^)]+]])
|
||||
// CHECK-DEBUG-SAME: #[[FN_ATTRS:[0-9]+]]
|
||||
// CHECK-DEBUG: store i32* [[VLA_ADDR]], i32** [[VLA_PTR_ADDR:%.+]],
|
||||
// CHECK-DEBUG: [[VLA_REF:%.+]] = load i32*, i32** [[VLA_PTR_ADDR]]
|
||||
|
@ -80,7 +80,7 @@ int main (int argc, char **argv) {
|
|||
// CHECK-DAG: declare {{.*}}void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
|
||||
// CHECK-DEBUG-DAG: define linkonce_odr void [[FOO]](i32 %argc)
|
||||
// CHECK-DEBUG-DAG: declare void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
|
||||
// CHECK-DEBUG-DAG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]])
|
||||
// CHECK-DEBUG-DAG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* {{.+}} [[VLA_ADDR:%[^)]+]])
|
||||
// CHECK-DEBUG-DAG: call void [[OMP_OUTLINED_DEBUG]]
|
||||
|
||||
// CHECK: define linkonce_odr {{[a-z\_\b]*[ ]?i32}} [[TMAIN]](i8** %argc)
|
||||
|
|
|
@ -223,7 +223,7 @@ int foo(int n, double *ptr) {
|
|||
|
||||
// make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the
|
||||
// target region
|
||||
// TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
|
||||
// TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* {{.+}} [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* {{.+}} [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
|
||||
// TCHECK: [[A2_ADDR:%.+]] = alloca i{{[0-9]+}},
|
||||
// TCHECK: [[B_ADDR:%.+]] = alloca [10 x float]*,
|
||||
// TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}},
|
||||
|
|
|
@ -428,7 +428,7 @@ int foo(int n) {
|
|||
// 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]])
|
||||
//
|
||||
//
|
||||
// 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]]* {{.+}})
|
||||
// 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]]* {{.+}})
|
||||
// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
|
||||
|
||||
template<typename tx>
|
||||
|
@ -703,7 +703,7 @@ int bar(int n){
|
|||
// 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]])
|
||||
//
|
||||
//
|
||||
// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* %{{.+}})
|
||||
// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* {{.+}})
|
||||
// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
|
||||
|
||||
|
||||
|
|
|
@ -441,7 +441,7 @@ int foo(int n) {
|
|||
// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%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]])
|
||||
//
|
||||
//
|
||||
// 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]]* {{.+}})
|
||||
// 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]]* {{.+}})
|
||||
// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
|
||||
|
||||
template<typename tx>
|
||||
|
@ -718,7 +718,7 @@ int bar(int n){
|
|||
// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%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]])
|
||||
//
|
||||
//
|
||||
// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* %{{.+}})
|
||||
// CHECK: define internal {{.*}}void [[OMP_OUTLINED5]](i32* noalias %.global_tid., i32* noalias %.bound_tid., [[S1]]* %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i[[SZ]] %{{.+}}, i16* {{.+}})
|
||||
// To reduce complexity, we're only going as far as validating the signature of the outlined parallel function.
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// RUN: %clang_cc1 -verify -triple powerpc64le-unknown-linux-gnu -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
int a;
|
||||
|
||||
|
@ -20,3 +19,24 @@ void foo() {
|
|||
|
||||
// CHECK: define internal void [[OUTLINED]](i32* {{[^,]+}}, i32* {{[^,]+}}, i64 {{[^,]+}}, i32** {{[^,]+}}, i64 {{[^,]+}}, i32**** {{[^,]+}})
|
||||
|
||||
// CHECK-LABEL: bar
|
||||
void bar(int n, int *a) {
|
||||
// CHECK: [[N:%.+]] = alloca i32,
|
||||
// CHECK: [[A:%.+]] = alloca i32*,
|
||||
// CHECK: [[P:%.+]] = alloca i32*,
|
||||
// CHECK: @__kmpc_global_thread_num
|
||||
// CHECK: [[BC:%.+]] = bitcast i32** [[A]] to i32*
|
||||
// CHECK: store i32* [[BC]], i32** [[P]],
|
||||
// CHECK: call void @__kmpc_serialized_parallel
|
||||
// CHECK: call void [[OUTLINED:@[^(]+]](i32* %{{[^,]+}}, i32* %{{[^,]+}}, i64 %{{[^,]+}}, i32** [[P]], i32** [[A]])
|
||||
// CHECK: call void @__kmpc_end_serialized_parallel
|
||||
// CHECK: ret void
|
||||
// expected-warning@+1 {{incompatible pointer types initializing 'int (*)[n]' with an expression of type 'int **'}}
|
||||
int(*p)[n] = &a;
|
||||
#pragma omp parallel if(0)
|
||||
// expected-warning@+1 {{comparison of distinct pointer types ('int (*)[n]' and 'int **')}}
|
||||
if (p == &a) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: define internal void [[OUTLINED]](i32* {{[^,]+}}, i32* {{[^,]+}}, i64 {{[^,]+}}, i32** {{[^,]+}}, i32** {{[^,]+}})
|
||||
|
|
Loading…
Reference in New Issue