[OPENMP]Do not crash for const firstprivates.
If the variable is a firstprivate variable and it was not emitted beause this a constant variable with the constant initializer, we can use the initial value instead of the variable itself. It also fixes the problem with the compiler crash in this case. llvm-svn: 361564
This commit is contained in:
parent
5554a5fcbd
commit
e0ef04f8cb
|
@ -758,7 +758,25 @@ bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
|
||||||
DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
|
DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
|
||||||
/*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
|
/*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
|
||||||
(*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
|
(*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
|
||||||
LValue OriginalLVal = EmitLValue(&DRE);
|
LValue OriginalLVal;
|
||||||
|
if (!FD) {
|
||||||
|
// Check if the firstprivate variable is just a constant value.
|
||||||
|
ConstantEmission CE = tryEmitAsConstant(&DRE);
|
||||||
|
if (CE && !CE.isReference()) {
|
||||||
|
// Constant value, no need to create a copy.
|
||||||
|
++IRef;
|
||||||
|
++InitsRef;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (CE && CE.isReference()) {
|
||||||
|
OriginalLVal = CE.getReferenceLValue(*this, &DRE);
|
||||||
|
} else {
|
||||||
|
assert(!CE && "Expected non-constant firstprivate.");
|
||||||
|
OriginalLVal = EmitLValue(&DRE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OriginalLVal = EmitLValue(&DRE);
|
||||||
|
}
|
||||||
QualType Type = VD->getType();
|
QualType Type = VD->getType();
|
||||||
if (Type->isArrayType()) {
|
if (Type->isArrayType()) {
|
||||||
// Emit VarDecl with copy init for arrays.
|
// Emit VarDecl with copy init for arrays.
|
||||||
|
|
|
@ -335,8 +335,9 @@ int main() {
|
||||||
s_arr[0] = var;
|
s_arr[0] = var;
|
||||||
sivar = 2;
|
sivar = 2;
|
||||||
}
|
}
|
||||||
#pragma omp parallel allocate(omp_default_mem_alloc: t_var) firstprivate(t_var)
|
const int a = 0;
|
||||||
{}
|
#pragma omp parallel allocate(omp_default_mem_alloc: t_var) firstprivate(t_var, a)
|
||||||
|
{ t_var = a; }
|
||||||
return tmain<int>();
|
return tmain<int>();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -346,6 +347,7 @@ int main() {
|
||||||
// CHECK: [[T_VAR:%.+]] = alloca i32,
|
// CHECK: [[T_VAR:%.+]] = alloca i32,
|
||||||
// CHECK: [[T_VARCAST:%.+]] = alloca [[iz:i64|i32]],
|
// CHECK: [[T_VARCAST:%.+]] = alloca [[iz:i64|i32]],
|
||||||
// CHECK: [[SIVARCAST:%.+]] = alloca [[iz]],
|
// CHECK: [[SIVARCAST:%.+]] = alloca [[iz]],
|
||||||
|
// CHECK: [[A:%.+]] = alloca i32,
|
||||||
// CHECK: [[T_VARCAST1:%.+]] = alloca [[iz:i64|i32]],
|
// CHECK: [[T_VARCAST1:%.+]] = alloca [[iz:i64|i32]],
|
||||||
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
|
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
|
||||||
// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]],
|
// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]],
|
||||||
|
@ -420,6 +422,7 @@ int main() {
|
||||||
// CHECK-32: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]],
|
// CHECK-32: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]],
|
||||||
// CHECK-64: [[T_VAR_VAL:%.+]] = load i32, i32* [[BC]],
|
// CHECK-64: [[T_VAR_VAL:%.+]] = load i32, i32* [[BC]],
|
||||||
// CHECK: store i32 [[T_VAR_VAL]], i32* [[T_VAR_PRIV]],
|
// CHECK: store i32 [[T_VAR_VAL]], i32* [[T_VAR_PRIV]],
|
||||||
|
// CHECK: store i32 0, i32* [[T_VAR_PRIV]],
|
||||||
// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[T_VAR_VOID_PTR]], i8* inttoptr ([[iz]] 1 to i8*))
|
// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[T_VAR_VOID_PTR]], i8* inttoptr ([[iz]] 1 to i8*))
|
||||||
// CHECK: ret void
|
// CHECK: ret void
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue