@@ -2589,26 +2589,63 @@ SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
25892589 return BuildOpenACCAsteriskSizeExpr (AsteriskLoc);
25902590}
25912591
2592- // / Loops through a type and generates an appropriate InitListExpr to generate
2593- // / type initialization.
2594- static Expr *GenerateReductionInitRecipeExpr (ASTContext &Context,
2595- SourceRange ExprRange,
2596- QualType Ty) {
2592+ namespace {
2593+ enum class InitKind { One, AllOnes, Least, Largest };
2594+ llvm::APFloat getInitFloatValue (ASTContext &Context, InitKind IK, QualType Ty) {
2595+ switch (IK) {
2596+ case InitKind::One:
2597+ return llvm::APFloat::getOne (Context.getFloatTypeSemantics (Ty));
2598+ case InitKind::AllOnes:
2599+ return llvm::APFloat::getAllOnesValue (Context.getFloatTypeSemantics (Ty));
2600+ case InitKind::Least:
2601+ return llvm::APFloat::getSmallestNormalized (
2602+ Context.getFloatTypeSemantics (Ty), /* Negative=*/ true );
2603+ case InitKind::Largest:
2604+ return llvm::APFloat::getLargest (Context.getFloatTypeSemantics (Ty));
2605+ break ;
2606+ }
2607+ llvm_unreachable (" unknown init kind" );
2608+ }
2609+
2610+ llvm::APInt getInitIntValue (ASTContext &Context, InitKind IK, QualType Ty) {
2611+ switch (IK) {
2612+ case InitKind::One:
2613+ return llvm::APInt (Context.getIntWidth (Ty), 1 );
2614+ case InitKind::AllOnes:
2615+ return llvm::APInt::getAllOnes (Context.getIntWidth (Ty));
2616+ case InitKind::Least:
2617+ if (Ty->isSignedIntegerOrEnumerationType ())
2618+ return llvm::APInt::getSignedMinValue (Context.getIntWidth (Ty));
2619+ return llvm::APInt::getMinValue (Context.getIntWidth (Ty));
2620+ case InitKind::Largest:
2621+ if (Ty->isSignedIntegerOrEnumerationType ())
2622+ return llvm::APInt::getSignedMaxValue (Context.getIntWidth (Ty));
2623+ return llvm::APInt::getMaxValue (Context.getIntWidth (Ty));
2624+ break ;
2625+ }
2626+ llvm_unreachable (" unknown init kind" );
2627+ }
2628+
2629+ // / Loops through a type and generates an appropriate InitListExpr to
2630+ // / generate type initialization.
2631+ Expr *GenerateReductionInitRecipeExpr (ASTContext &Context,
2632+ SourceRange ExprRange, QualType Ty,
2633+ InitKind IK) {
25972634 Ty = Ty.getCanonicalType ();
25982635 llvm::SmallVector<Expr *> Exprs;
25992636
26002637 if (const RecordDecl *RD = Ty->getAsRecordDecl ()) {
26012638 for (auto *F : RD->fields ()) {
2602- if (Expr *NewExpr =
2603- GenerateReductionInitRecipeExpr (Context, ExprRange, F->getType ()))
2639+ if (Expr *NewExpr = GenerateReductionInitRecipeExpr (Context, ExprRange,
2640+ F->getType (), IK ))
26042641 Exprs.push_back (NewExpr);
26052642 else
26062643 return nullptr ;
26072644 }
26082645 } else if (const ConstantArrayType *AT = Context.getAsConstantArrayType (Ty)) {
26092646 for (uint64_t Idx = 0 ; Idx < AT->getZExtSize (); ++Idx) {
2610- if (Expr *NewExpr = GenerateReductionInitRecipeExpr (Context, ExprRange,
2611- AT->getElementType ()))
2647+ if (Expr *NewExpr = GenerateReductionInitRecipeExpr (
2648+ Context, ExprRange, AT->getElementType (), IK ))
26122649 Exprs.push_back (NewExpr);
26132650 else
26142651 return nullptr ;
@@ -2627,16 +2664,40 @@ static Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
26272664 } else {
26282665 assert (Ty->isScalarType ());
26292666
2630- // TODO: OpenACC: This currently only works for '1', but we need to figure
2631- // out a way to do least/largest/all-1s.
2632- if (Ty->isFloatingType ()) {
2633- Exprs.push_back (FloatingLiteral::Create (
2634- Context, llvm::APFloat::getOne (Context.getFloatTypeSemantics (Ty)),
2635- /* isExact=*/ true , Ty, ExprRange.getBegin ()));
2667+ if (const auto *Cplx = Ty->getAs <ComplexType>()) {
2668+ // we can get here in error cases, so make sure we generate something that
2669+ // will work if we find ourselves wanting to enable this.
2670+
2671+ QualType EltTy = Cplx->getElementType ();
2672+ if (EltTy->isFloatingType ()) {
2673+ Exprs.push_back (FloatingLiteral::Create (
2674+ Context, getInitFloatValue (Context, IK, EltTy),
2675+ /* isExact=*/ true , EltTy, ExprRange.getBegin ()));
2676+ Exprs.push_back (FloatingLiteral::Create (
2677+ Context, getInitFloatValue (Context, IK, EltTy),
2678+ /* isExact=*/ true , EltTy, ExprRange.getBegin ()));
2679+ } else {
2680+ Exprs.push_back (
2681+ IntegerLiteral::Create (Context, getInitIntValue (Context, IK, EltTy),
2682+ EltTy, ExprRange.getBegin ()));
2683+ Exprs.push_back (
2684+ IntegerLiteral::Create (Context, getInitIntValue (Context, IK, EltTy),
2685+ EltTy, ExprRange.getBegin ()));
2686+ }
2687+
2688+ } else if (Ty->isFloatingType ()) {
2689+ Exprs.push_back (
2690+ FloatingLiteral::Create (Context, getInitFloatValue (Context, IK, Ty),
2691+ /* isExact=*/ true , Ty, ExprRange.getBegin ()));
2692+ } else if (Ty->isBooleanType ()) {
2693+ Exprs.push_back (CXXBoolLiteralExpr::Create (Context,
2694+ (IK == InitKind::One ||
2695+ IK == InitKind::AllOnes ||
2696+ IK == InitKind::Largest),
2697+ Ty, ExprRange.getBegin ()));
26362698 } else {
26372699 Exprs.push_back (IntegerLiteral::Create (
2638- Context, llvm::APInt (Context.getTypeSize (Ty), 1 ), Ty,
2639- ExprRange.getBegin ()));
2700+ Context, getInitIntValue (Context, IK, Ty), Ty, ExprRange.getBegin ()));
26402701 }
26412702 }
26422703
@@ -2646,6 +2707,8 @@ static Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
26462707 return InitExpr;
26472708}
26482709
2710+ } // namespace
2711+
26492712std::pair<VarDecl *, VarDecl *>
26502713SemaOpenACC::CreateInitRecipe (OpenACCClauseKind CK,
26512714 OpenACCReductionOperator ReductionOperator,
@@ -2796,20 +2859,37 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
27962859 // are used for code generation, we can just ignore/not bother doing any
27972860 // initialization here.
27982861 break ;
2799- case OpenACCReductionOperator::Max:
2800- case OpenACCReductionOperator::Min:
2801- case OpenACCReductionOperator::BitwiseAnd:
2802- // TODO: OpenACC: figure out init for these.
2862+ case OpenACCReductionOperator::Max: {
2863+ Expr *InitExpr = GenerateReductionInitRecipeExpr (
2864+ getASTContext (), VarExpr->getSourceRange (), VarTy, InitKind::Least);
2865+
2866+ Init = FinishValueInit (InitExpr);
2867+ break ;
2868+ }
2869+ case OpenACCReductionOperator::Min: {
2870+ Expr *InitExpr = GenerateReductionInitRecipeExpr (
2871+ getASTContext (), VarExpr->getSourceRange (), VarTy,
2872+ InitKind::Largest);
2873+
2874+ Init = FinishValueInit (InitExpr);
28032875 break ;
2876+ }
2877+ case OpenACCReductionOperator::BitwiseAnd: {
2878+ Expr *InitExpr = GenerateReductionInitRecipeExpr (
2879+ getASTContext (), VarExpr->getSourceRange (), VarTy,
2880+ InitKind::AllOnes);
28042881
2882+ Init = FinishValueInit (InitExpr);
2883+ break ;
2884+ }
28052885 case OpenACCReductionOperator::Multiplication:
28062886 case OpenACCReductionOperator::And: {
28072887 // '&&' initializes every field to 1. However, we need to loop through
28082888 // every field/element and generate an initializer for each of the
28092889 // elements.
28102890
28112891 Expr *InitExpr = GenerateReductionInitRecipeExpr (
2812- getASTContext (), VarExpr->getSourceRange (), VarTy);
2892+ getASTContext (), VarExpr->getSourceRange (), VarTy, InitKind::One );
28132893
28142894 Init = FinishValueInit (InitExpr);
28152895 break ;
0 commit comments