@@ -4935,13 +4935,34 @@ void CGOpenMPRuntime::emitPrivateReduction(
4935
4935
if (const auto *DRE = dyn_cast<DeclRefExpr>(Privates)) {
4936
4936
if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
4937
4937
const Expr *InitExpr = VD->getInit();
4938
- if (InitExpr && !PrivateType->isAggregateType() &&
4939
- !PrivateType->isAnyComplexType()) {
4938
+ if (InitExpr) {
4940
4939
Expr::EvalResult Result;
4941
4940
if (InitExpr->EvaluateAsRValue(Result, CGF.getContext())) {
4942
4941
APValue &InitValue = Result.Val;
4943
4942
if (InitValue.isInt())
4944
4943
InitVal = llvm::ConstantInt::get(LLVMType, InitValue.getInt());
4944
+ else if (InitValue.isFloat())
4945
+ InitVal = llvm::ConstantFP::get(LLVMType, InitValue.getFloat());
4946
+ else if (InitValue.isComplexInt()) {
4947
+ // For complex int: create struct { real, imag }
4948
+ llvm::Constant *Real = llvm::ConstantInt::get(
4949
+ cast<llvm::StructType>(LLVMType)->getElementType(0),
4950
+ InitValue.getComplexIntReal());
4951
+ llvm::Constant *Imag = llvm::ConstantInt::get(
4952
+ cast<llvm::StructType>(LLVMType)->getElementType(1),
4953
+ InitValue.getComplexIntImag());
4954
+ InitVal = llvm::ConstantStruct::get(
4955
+ cast<llvm::StructType>(LLVMType), {Real, Imag});
4956
+ } else if (InitValue.isComplexFloat()) {
4957
+ llvm::Constant *Real = llvm::ConstantFP::get(
4958
+ cast<llvm::StructType>(LLVMType)->getElementType(0),
4959
+ InitValue.getComplexFloatReal());
4960
+ llvm::Constant *Imag = llvm::ConstantFP::get(
4961
+ cast<llvm::StructType>(LLVMType)->getElementType(1),
4962
+ InitValue.getComplexFloatImag());
4963
+ InitVal = llvm::ConstantStruct::get(
4964
+ cast<llvm::StructType>(LLVMType), {Real, Imag});
4965
+ }
4945
4966
}
4946
4967
}
4947
4968
}
@@ -4950,11 +4971,10 @@ void CGOpenMPRuntime::emitPrivateReduction(
4950
4971
InitVal = llvm::Constant::getNullValue(LLVMType);
4951
4972
}
4952
4973
std::string ReductionVarNameStr;
4953
- if (const auto *DRE = dyn_cast<DeclRefExpr>(Privates->IgnoreParenCasts())) {
4974
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(Privates->IgnoreParenCasts()))
4954
4975
ReductionVarNameStr = DRE->getDecl()->getNameAsString();
4955
- } else {
4976
+ else
4956
4977
ReductionVarNameStr = "unnamed_priv_var";
4957
- }
4958
4978
4959
4979
// Create an internal shared variable
4960
4980
std::string SharedName =
@@ -5027,18 +5047,11 @@ void CGOpenMPRuntime::emitPrivateReduction(
5027
5047
}
5028
5048
if (const auto *DRE = dyn_cast<DeclRefExpr>(Privates)) {
5029
5049
if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
5030
- const Expr *InitExpr = VD->getInit();
5031
- if (InitExpr && (PrivateType->isAggregateType() ||
5032
- PrivateType->isAnyComplexType())) {
5050
+ if (const Expr *InitExpr = VD->getInit()) {
5033
5051
CGF.EmitAnyExprToMem(InitExpr, SharedResult,
5034
5052
PrivateType.getQualifiers(), true);
5035
5053
return;
5036
5054
}
5037
- if (!InitVal->isNullValue()) {
5038
- CGF.EmitStoreOfScalar(InitVal,
5039
- CGF.MakeAddrLValue(SharedResult, PrivateType));
5040
- return;
5041
- }
5042
5055
}
5043
5056
}
5044
5057
CGF.EmitNullInitialization(SharedResult, PrivateType);
@@ -5086,9 +5099,8 @@ void CGOpenMPRuntime::emitPrivateReduction(
5086
5099
}
5087
5100
};
5088
5101
EmitCriticalReduction(ReductionGen);
5089
- }
5090
- // Handle built-in reduction operations.
5091
- else {
5102
+ } else {
5103
+ // Handle built-in reduction operations.
5092
5104
const Expr *ReductionClauseExpr = ReductionOp->IgnoreParenCasts();
5093
5105
if (const auto *Cleanup = dyn_cast<ExprWithCleanups>(ReductionClauseExpr))
5094
5106
ReductionClauseExpr = Cleanup->getSubExpr()->IgnoreParenCasts();
@@ -5106,10 +5118,6 @@ void CGOpenMPRuntime::emitPrivateReduction(
5106
5118
if (!AssignRHS)
5107
5119
return;
5108
5120
5109
- const Expr *CombinerExpr = AssignRHS->IgnoreParenImpCasts();
5110
- if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(CombinerExpr))
5111
- CombinerExpr = MTE->getSubExpr()->IgnoreParenImpCasts();
5112
-
5113
5121
auto ReductionGen = [&](CodeGenFunction &CGF, PrePostActionTy &Action) {
5114
5122
Action.Enter(CGF);
5115
5123
const auto *OmpOutDRE =
@@ -5414,7 +5422,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
5414
5422
} else {
5415
5423
// Emit as a critical region.
5416
5424
auto &&CritRedGen = [E, Loc](CodeGenFunction &CGF, const Expr *,
5417
- const Expr *, const Expr *) {
5425
+ const Expr *, const Expr *) {
5418
5426
CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
5419
5427
std::string Name = RT.getName({"atomic_reduction"});
5420
5428
RT.emitCriticalRegion(
@@ -5467,6 +5475,14 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
5467
5475
if (LHSExprs.size() != Privates.size() ||
5468
5476
LHSExprs.size() != ReductionOps.size())
5469
5477
return;
5478
+ assert(!LHSExprs.empty() && "PrivateVarReduction: LHSExprs is empty");
5479
+ assert(!Privates.empty() && "PrivateVarReduction: Privates is empty");
5480
+ assert(!ReductionOps.empty() &&
5481
+ "PrivateVarReduction: ReductionOps is empty");
5482
+ assert(LHSExprs.size() == Privates.size() &&
5483
+ "PrivateVarReduction: Privates size mismatch");
5484
+ assert(LHSExprs.size() == ReductionOps.size() &&
5485
+ "PrivateVarReduction: ReductionOps size mismatch");
5470
5486
for (unsigned I :
5471
5487
llvm::seq<unsigned>(std::min(ReductionOps.size(), LHSExprs.size()))) {
5472
5488
emitPrivateReduction(CGF, Loc, Privates[I], LHSExprs[I], RHSExprs[I],
0 commit comments