@@ -2589,26 +2589,67 @@ 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 { Zero, One, AllOnes, Least, Largest };
2594+ llvm::APFloat getInitFloatValue (ASTContext &Context, InitKind IK, QualType Ty) {
2595+ switch (IK) {
2596+ case InitKind::Zero:
2597+ return llvm::APFloat::getZero (Context.getFloatTypeSemantics (Ty));
2598+ case InitKind::One:
2599+ return llvm::APFloat::getOne (Context.getFloatTypeSemantics (Ty));
2600+ case InitKind::AllOnes:
2601+ return llvm::APFloat::getAllOnesValue (Context.getFloatTypeSemantics (Ty));
2602+ case InitKind::Least:
2603+ return llvm::APFloat::getLargest (Context.getFloatTypeSemantics (Ty),
2604+ /* Negative=*/ true );
2605+ case InitKind::Largest:
2606+ return llvm::APFloat::getLargest (Context.getFloatTypeSemantics (Ty));
2607+ break ;
2608+ }
2609+ llvm_unreachable (" unknown init kind" );
2610+ }
2611+
2612+ llvm::APInt getInitIntValue (ASTContext &Context, InitKind IK, QualType Ty) {
2613+ switch (IK) {
2614+ case InitKind::Zero:
2615+ return llvm::APInt (Context.getIntWidth (Ty), 0 );
2616+ case InitKind::One:
2617+ return llvm::APInt (Context.getIntWidth (Ty), 1 );
2618+ case InitKind::AllOnes:
2619+ return llvm::APInt::getAllOnes (Context.getIntWidth (Ty));
2620+ case InitKind::Least:
2621+ if (Ty->isSignedIntegerOrEnumerationType ())
2622+ return llvm::APInt::getSignedMinValue (Context.getIntWidth (Ty));
2623+ return llvm::APInt::getMinValue (Context.getIntWidth (Ty));
2624+ case InitKind::Largest:
2625+ if (Ty->isSignedIntegerOrEnumerationType ())
2626+ return llvm::APInt::getSignedMaxValue (Context.getIntWidth (Ty));
2627+ return llvm::APInt::getMaxValue (Context.getIntWidth (Ty));
2628+ break ;
2629+ }
2630+ llvm_unreachable (" unknown init kind" );
2631+ }
2632+
2633+ // / Loops through a type and generates an appropriate InitListExpr to
2634+ // / generate type initialization.
2635+ Expr *GenerateReductionInitRecipeExpr (ASTContext &Context,
2636+ SourceRange ExprRange, QualType Ty,
2637+ InitKind IK) {
25972638 Ty = Ty.getCanonicalType ();
25982639 llvm::SmallVector<Expr *> Exprs;
25992640
26002641 if (const RecordDecl *RD = Ty->getAsRecordDecl ()) {
26012642 for (auto *F : RD->fields ()) {
2602- if (Expr *NewExpr =
2603- GenerateReductionInitRecipeExpr (Context, ExprRange, F->getType ()))
2643+ if (Expr *NewExpr = GenerateReductionInitRecipeExpr (Context, ExprRange,
2644+ F->getType (), IK ))
26042645 Exprs.push_back (NewExpr);
26052646 else
26062647 return nullptr ;
26072648 }
26082649 } else if (const ConstantArrayType *AT = Context.getAsConstantArrayType (Ty)) {
26092650 for (uint64_t Idx = 0 ; Idx < AT->getZExtSize (); ++Idx) {
2610- if (Expr *NewExpr = GenerateReductionInitRecipeExpr (Context, ExprRange,
2611- AT->getElementType ()))
2651+ if (Expr *NewExpr = GenerateReductionInitRecipeExpr (
2652+ Context, ExprRange, AT->getElementType (), IK ))
26122653 Exprs.push_back (NewExpr);
26132654 else
26142655 return nullptr ;
@@ -2627,16 +2668,41 @@ static Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
26272668 } else {
26282669 assert (Ty->isScalarType ());
26292670
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 ()));
2671+ if (const auto *Cplx = Ty->getAs <ComplexType>()) {
2672+ // we can get here in error cases, so make sure we generate something that
2673+ // will work if we find ourselves wanting to enable this, so emit '0,0'
2674+ // for both ints and floats.
2675+
2676+ QualType EltTy = Cplx->getElementType ();
2677+ if (EltTy->isFloatingType ()) {
2678+ Exprs.push_back (FloatingLiteral::Create (
2679+ Context, getInitFloatValue (Context, InitKind::Zero, EltTy),
2680+ /* isExact=*/ true , EltTy, ExprRange.getBegin ()));
2681+ Exprs.push_back (FloatingLiteral::Create (
2682+ Context, getInitFloatValue (Context, InitKind::Zero, EltTy),
2683+ /* isExact=*/ true , EltTy, ExprRange.getBegin ()));
2684+ } else {
2685+ Exprs.push_back (IntegerLiteral::Create (
2686+ Context, getInitIntValue (Context, InitKind::Zero, EltTy), EltTy,
2687+ ExprRange.getBegin ()));
2688+ Exprs.push_back (IntegerLiteral::Create (
2689+ Context, getInitIntValue (Context, InitKind::Zero, EltTy), EltTy,
2690+ ExprRange.getBegin ()));
2691+ }
2692+
2693+ } else if (Ty->isFloatingType ()) {
2694+ Exprs.push_back (
2695+ FloatingLiteral::Create (Context, getInitFloatValue (Context, IK, Ty),
2696+ /* isExact=*/ true , Ty, ExprRange.getBegin ()));
2697+ } else if (Ty->isBooleanType ()) {
2698+ Exprs.push_back (CXXBoolLiteralExpr::Create (Context,
2699+ (IK == InitKind::One ||
2700+ IK == InitKind::AllOnes ||
2701+ IK == InitKind::Largest),
2702+ Ty, ExprRange.getBegin ()));
26362703 } else {
26372704 Exprs.push_back (IntegerLiteral::Create (
2638- Context, llvm::APInt (Context.getTypeSize (Ty), 1 ), Ty,
2639- ExprRange.getBegin ()));
2705+ Context, getInitIntValue (Context, IK, Ty), Ty, ExprRange.getBegin ()));
26402706 }
26412707 }
26422708
@@ -2646,6 +2712,8 @@ static Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
26462712 return InitExpr;
26472713}
26482714
2715+ } // namespace
2716+
26492717std::pair<VarDecl *, VarDecl *>
26502718SemaOpenACC::CreateInitRecipe (OpenACCClauseKind CK,
26512719 OpenACCReductionOperator ReductionOperator,
@@ -2796,20 +2864,37 @@ SemaOpenACC::CreateInitRecipe(OpenACCClauseKind CK,
27962864 // are used for code generation, we can just ignore/not bother doing any
27972865 // initialization here.
27982866 break ;
2799- case OpenACCReductionOperator::Max:
2800- case OpenACCReductionOperator::Min:
2801- case OpenACCReductionOperator::BitwiseAnd:
2802- // TODO: OpenACC: figure out init for these.
2867+ case OpenACCReductionOperator::Max: {
2868+ Expr *InitExpr = GenerateReductionInitRecipeExpr (
2869+ getASTContext (), VarExpr->getSourceRange (), VarTy, InitKind::Least);
2870+
2871+ Init = FinishValueInit (InitExpr);
2872+ break ;
2873+ }
2874+ case OpenACCReductionOperator::Min: {
2875+ Expr *InitExpr = GenerateReductionInitRecipeExpr (
2876+ getASTContext (), VarExpr->getSourceRange (), VarTy,
2877+ InitKind::Largest);
2878+
2879+ Init = FinishValueInit (InitExpr);
28032880 break ;
2881+ }
2882+ case OpenACCReductionOperator::BitwiseAnd: {
2883+ Expr *InitExpr = GenerateReductionInitRecipeExpr (
2884+ getASTContext (), VarExpr->getSourceRange (), VarTy,
2885+ InitKind::AllOnes);
28042886
2887+ Init = FinishValueInit (InitExpr);
2888+ break ;
2889+ }
28052890 case OpenACCReductionOperator::Multiplication:
28062891 case OpenACCReductionOperator::And: {
28072892 // '&&' initializes every field to 1. However, we need to loop through
28082893 // every field/element and generate an initializer for each of the
28092894 // elements.
28102895
28112896 Expr *InitExpr = GenerateReductionInitRecipeExpr (
2812- getASTContext (), VarExpr->getSourceRange (), VarTy);
2897+ getASTContext (), VarExpr->getSourceRange (), VarTy, InitKind::One );
28132898
28142899 Init = FinishValueInit (InitExpr);
28152900 break ;
0 commit comments