Yes, thanks for fixing this, David!

Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team

01.01.2015 12:51, David Majnemer пишет:
Should be fixed with r225060.

On Wed, Dec 31, 2014 at 6:11 PM, David Majnemer <[email protected] <mailto:[email protected]>> wrote:

    It looks like this caused PR22071, reverting r224323 makes the
    crash go away.

    On Mon, Dec 15, 2014 at 11:00 PM, Alexey Bataev
    <[email protected] <mailto:[email protected]>> wrote:

        Author: abataev
        Date: Tue Dec 16 01:00:22 2014
        New Revision: 224323

        URL: http://llvm.org/viewvc/llvm-project?rev=224323&view=rev
        Log:
        [OPENMP] Bugfix for processing of global variables in OpenMP
        regions.
        Currently, if global variable is marked as a private OpenMP
        variable, the compiler crashes in debug version or generates
        incorrect code in release version. It happens because in the
        OpenMP region the original global variable is used instead of
        the generated private copy. It happens because currently
        globals variables are not captured in the OpenMP region.
        This patch adds capturing of global variables iff private copy
        of the global variable must be used in the OpenMP region.
        Differential Revision: http://reviews.llvm.org/D6259

        Modified:
            cfe/trunk/include/clang/Sema/Sema.h
            cfe/trunk/lib/CodeGen/CGExpr.cpp
            cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
            cfe/trunk/lib/CodeGen/CodeGenFunction.h
        cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp
            cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp
            cfe/trunk/lib/Sema/SemaExpr.cpp
            cfe/trunk/lib/Sema/SemaOpenMP.cpp
        cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
        cfe/trunk/test/OpenMP/parallel_private_codegen.cpp

        Modified: cfe/trunk/include/clang/Sema/Sema.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/include/clang/Sema/Sema.h (original)
        +++ cfe/trunk/include/clang/Sema/Sema.h Tue Dec 16 01:00:22 2014
        @@ -3448,6 +3448,9 @@ public:
                                   TryCaptureKind Kind =
        TryCapture_Implicit,
                                   SourceLocation EllipsisLoc =
        SourceLocation());

        +  /// \brief Checks if the variable must be captured.
        +  bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc);
        +
           /// \brief Given a variable, determine the type that a
        reference to that
           /// variable will have in the given scope.
           QualType getCapturedDeclRefType(VarDecl *Var,
        SourceLocation Loc);
        @@ -7482,6 +7485,10 @@ private:
           void DestroyDataSharingAttributesStack();
           ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op,
          OpenMPClauseKind CKind);
        +  /// \brief Checks if the specified variable is used in one
        of the private
        +  /// clauses in OpenMP constructs.
        +  bool IsOpenMPCapturedVar(VarDecl *VD);
        +
         public:
           ExprResult
        PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc,
           Expr *Op);

        Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
        +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Dec 16 01:00:22 2014
        @@ -1906,6 +1906,21 @@ LValue CodeGenFunction::EmitDeclRefLValu
           QualType T = E->getType();

           if (const auto *VD = dyn_cast<VarDecl>(ND)) {
        +    // Check for captured variables.
        +    if (E->refersToEnclosingLocal()) {
        +      if (auto *FD = LambdaCaptureFields.lookup(VD))
        +        return EmitCapturedFieldLValue(*this, FD,
        CXXABIThisValue);
        +      else if (CapturedStmtInfo) {
        +        if (auto *V = LocalDeclMap.lookup(VD))
        +          return MakeAddrLValue(V, T, Alignment);
        +        else
        +          return EmitCapturedFieldLValue(*this,
        CapturedStmtInfo->lookup(VD),
        +  CapturedStmtInfo->getContextValue());
        +      } else
        +        return MakeAddrLValue(GetAddrOfBlockDecl(VD,
        VD->hasAttr<BlocksAttr>()),
        +                              T, Alignment);
        +    }
        +
             // Global Named registers access via intrinsics only
             if (VD->getStorageClass() == SC_Register &&
                 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
        @@ -1956,21 +1971,6 @@ LValue CodeGenFunction::EmitDeclRefLValu
                   *this, VD, T, V,
        getTypes().ConvertTypeForMem(VD->getType()),
                   Alignment, E->getExprLoc());

        -    // Use special handling for lambdas.
        -    if (!V) {
        -      if (FieldDecl *FD = LambdaCaptureFields.lookup(VD)) {
        -        return EmitCapturedFieldLValue(*this, FD,
        CXXABIThisValue);
        -      } else if (CapturedStmtInfo) {
        -        if (const FieldDecl *FD = CapturedStmtInfo->lookup(VD))
        -          return EmitCapturedFieldLValue(*this, FD,
        -  CapturedStmtInfo->getContextValue());
        -      }
        -
        -      assert(isa<BlockDecl>(CurCodeDecl) &&
        E->refersToEnclosingLocal());
        -      return MakeAddrLValue(GetAddrOfBlockDecl(VD,
        isBlockVariable),
        -                            T, Alignment);
        -    }
        -
             assert(V && "DeclRefExpr not entered in LocalDeclMap?");

             if (isBlockVariable)

        Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
        +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Dec 16 01:00:22
        2014
        @@ -20,6 +20,35 @@
         using namespace clang;
         using namespace CodeGen;

        +namespace {
        +/// \brief RAII for emitting code of CapturedStmt without
        function outlining.
        +class InlinedOpenMPRegion {
        +  CodeGenFunction &CGF;
        +  CodeGenFunction::CGCapturedStmtInfo *PrevCapturedStmtInfo;
        +  const Decl *StoredCurCodeDecl;
        +
        +  /// \brief A class to emit CapturedStmt construct as
        inlined statement without
        +  /// generating a function for outlined code.
        +  class CGInlinedOpenMPRegionInfo : public
        CodeGenFunction::CGCapturedStmtInfo {
        +  public:
        +    CGInlinedOpenMPRegionInfo() : CGCapturedStmtInfo() {}
        +  };
        +
        +public:
        +  InlinedOpenMPRegion(CodeGenFunction &CGF, const Stmt *S)
        +      : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo),
        +        StoredCurCodeDecl(CGF.CurCodeDecl) {
        +    CGF.CurCodeDecl = cast<CapturedStmt>(S)->getCapturedDecl();
        +    CGF.CapturedStmtInfo = new CGInlinedOpenMPRegionInfo();
        +  }
        +  ~InlinedOpenMPRegion() {
        +    delete CGF.CapturedStmtInfo;
        +    CGF.CapturedStmtInfo = PrevCapturedStmtInfo;
        +    CGF.CurCodeDecl = StoredCurCodeDecl;
        +  }
        +};
        +} // namespace
        +
         
//===----------------------------------------------------------------------===//
         //                              OpenMP Directive Emission
         
//===----------------------------------------------------------------------===//
        @@ -417,6 +446,7 @@ void CodeGenFunction::EmitOMPSimdDirecti
             }
           }

        +  InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
           RunCleanupsScope DirectiveScope(*this);

           CGDebugInfo *DI = getDebugInfo();
        @@ -561,6 +591,7 @@ void CodeGenFunction::EmitOMPWorksharing
         }

         void CodeGenFunction::EmitOMPForDirective(const
        OMPForDirective &S) {
        +  InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
           RunCleanupsScope DirectiveScope(*this);

           CGDebugInfo *DI = getDebugInfo();
        @@ -593,8 +624,8 @@ void CodeGenFunction::EmitOMPSingleDirec
         }

         void CodeGenFunction::EmitOMPMasterDirective(const
        OMPMasterDirective &S) {
        -  CGM.getOpenMPRuntime().EmitOMPMasterRegion(
        -      *this, [&]() -> void {
        + CGM.getOpenMPRuntime().EmitOMPMasterRegion(*this, [&]() ->
        void {
        +    InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
             RunCleanupsScope Scope(*this);
         EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
             EnsureInsertPoint();
        @@ -604,8 +635,10 @@ void CodeGenFunction::EmitOMPMasterDirec
         void CodeGenFunction::EmitOMPCriticalDirective(const
        OMPCriticalDirective &S) {
           CGM.getOpenMPRuntime().EmitOMPCriticalRegion(
               *this, S.getDirectiveName().getAsString(), [&]() -> void {
        +    InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
             RunCleanupsScope Scope(*this);
        -
        EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
        +    EmitStmt(
        + cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
             EnsureInsertPoint();
           }, S.getLocStart());
         }

        Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
        +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Dec 16
        01:00:22 2014
        @@ -182,6 +182,8 @@ public:
           /// \brief API for captured statement code generation.
           class CGCapturedStmtInfo {
           public:
        +    explicit CGCapturedStmtInfo(CapturedRegionKind K =
        CR_Default)
        +        : Kind(K), ThisValue(nullptr),
        CXXThisFieldDecl(nullptr) {}
             explicit CGCapturedStmtInfo(const CapturedStmt &S,
         CapturedRegionKind K = CR_Default)
               : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {
        @@ -614,7 +616,6 @@ public:
             addPrivate(const VarDecl *LocalVD,
                        const std::function<llvm::Value *()>
        &PrivateGen) {
               assert(PerformCleanup && "adding private to dead scope");
        -      assert(LocalVD->isLocalVarDecl() && "privatizing
        non-local variable");
               if (SavedLocals.count(LocalVD) > 0) return false;
               SavedLocals[LocalVD] = CGF.LocalDeclMap.lookup(LocalVD);
               CGF.LocalDeclMap.erase(LocalVD);

        Modified: cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp
        (original)
        +++ cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp Tue
        Dec 16 01:00:22 2014
        @@ -4563,16 +4563,12 @@ void RewriteModernObjC::GetBlockDeclRefE
                 GetBlockDeclRefExprs(*CI);
             }
           // Handle specific things.
        -  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
        -    if (DRE->refersToEnclosingLocal()) {
        +  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
        +    if (DRE->refersToEnclosingLocal() ||
        + HasLocalVariableExternalStorage(DRE->getDecl()))
               // FIXME: Handle enums.
        -      if (!isa<FunctionDecl>(DRE->getDecl()))
        -        BlockDeclRefs.push_back(DRE);
        -      if (HasLocalVariableExternalStorage(DRE->getDecl()))
        -        BlockDeclRefs.push_back(DRE);
        -    }
        -  }
        -
        +      BlockDeclRefs.push_back(DRE);
        +
           return;
         }

        @@ -4595,11 +4591,11 @@ void RewriteModernObjC::GetInnerBlockDec
             }
           // Handle specific things.
           if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
        -    if (DRE->refersToEnclosingLocal()) {
        -      if (!isa<FunctionDecl>(DRE->getDecl()) &&
        - !InnerContexts.count(DRE->getDecl()->getDeclContext()))
        +    if (DRE->refersToEnclosingLocal() ||
        + HasLocalVariableExternalStorage(DRE->getDecl())) {
        +      if (!InnerContexts.count(DRE->getDecl()->getDeclContext()))
                 InnerBlockDeclRefs.push_back(DRE);
        -      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
        +      if (VarDecl *Var = cast<VarDecl>(DRE->getDecl()))
                 if (Var->isFunctionOrMethodVarDecl())
                   ImportedLocalExternalDecls.insert(Var);
             }
        @@ -4776,7 +4772,8 @@ Stmt *RewriteModernObjC::RewriteBlockDec
           // Rewrite the byref variable into
        BYREFVAR->__forwarding->BYREFVAR
           // for each DeclRefExp where BYREFVAR is name of the variable.
           ValueDecl *VD = DeclRefExp->getDecl();
        -  bool isArrow = DeclRefExp->refersToEnclosingLocal();
        +  bool isArrow = DeclRefExp->refersToEnclosingLocal() ||
        +  HasLocalVariableExternalStorage(DeclRefExp->getDecl());

           FieldDecl *FD = FieldDecl::Create(*Context, nullptr,
        SourceLocation(),
         SourceLocation(),

        Modified: cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp (original)
        +++ cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp Tue Dec 16
        01:00:22 2014
        @@ -3671,16 +3671,12 @@ void RewriteObjC::GetBlockDeclRefExprs(S
                 GetBlockDeclRefExprs(*CI);
             }
           // Handle specific things.
        -  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
        -    if (DRE->refersToEnclosingLocal()) {
        +  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
        +    if (DRE->refersToEnclosingLocal() ||
        + HasLocalVariableExternalStorage(DRE->getDecl()))
               // FIXME: Handle enums.
        -      if (!isa<FunctionDecl>(DRE->getDecl()))
        -        BlockDeclRefs.push_back(DRE);
        -      if (HasLocalVariableExternalStorage(DRE->getDecl()))
        -        BlockDeclRefs.push_back(DRE);
        -    }
        -  }
        -
        +      BlockDeclRefs.push_back(DRE);
        +
           return;
         }

        @@ -3703,11 +3699,11 @@ void RewriteObjC::GetInnerBlockDeclRefEx
             }
           // Handle specific things.
           if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
        -    if (DRE->refersToEnclosingLocal()) {
        -      if (!isa<FunctionDecl>(DRE->getDecl()) &&
        - !InnerContexts.count(DRE->getDecl()->getDeclContext()))
        +    if (DRE->refersToEnclosingLocal() ||
        + HasLocalVariableExternalStorage(DRE->getDecl())) {
        +      if (!InnerContexts.count(DRE->getDecl()->getDeclContext()))
                 InnerBlockDeclRefs.push_back(DRE);
        -      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
        +      if (VarDecl *Var = cast<VarDecl>(DRE->getDecl()))
                 if (Var->isFunctionOrMethodVarDecl())
                   ImportedLocalExternalDecls.insert(Var);
             }
        @@ -3865,7 +3861,8 @@ Stmt *RewriteObjC::RewriteBlockDeclRefEx
           // Rewrite the byref variable into
        BYREFVAR->__forwarding->BYREFVAR
           // for each DeclRefExp where BYREFVAR is name of the variable.
           ValueDecl *VD = DeclRefExp->getDecl();
        -  bool isArrow = DeclRefExp->refersToEnclosingLocal();
        +  bool isArrow = DeclRefExp->refersToEnclosingLocal() ||
        +  HasLocalVariableExternalStorage(DeclRefExp->getDecl());

           FieldDecl *FD = FieldDecl::Create(*Context, nullptr,
        SourceLocation(),
         SourceLocation(),

        Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
        +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Dec 16 01:00:22 2014
        @@ -1602,10 +1602,8 @@ Sema::BuildDeclRefExpr(ValueDecl *D, Qua
               }

           bool refersToEnclosingScope =
        -    (CurContext != D->getDeclContext() &&
        -  D->getDeclContext()->isFunctionOrMethod()) ||
        -    (isa<VarDecl>(D) &&
        -     cast<VarDecl>(D)->isInitCapture());
        +      isa<VarDecl>(D) &&
        + NeedToCaptureVariable(cast<VarDecl>(D), NameInfo.getLoc());

           DeclRefExpr *E;
           if (isa<VarTemplateSpecializationDecl>(D)) {
        @@ -11799,7 +11797,7 @@ static DeclContext *getParentOfCapturing
                                          const bool Diagnose, Sema &S) {
           if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC) ||
        isLambdaCallOperator(DC))
             return getLambdaAwareParentOfDeclContext(DC);
        -  else {
        +  else if (Var->hasLocalStorage()) {
             if (Diagnose)
                diagnoseUncapturableValueReference(S, Loc, Var, DC);
           }
        @@ -12241,7 +12239,7 @@ bool Sema::tryCaptureVariable(VarDecl *V
                                       QualType &CaptureType,
                                       QualType &DeclRefType,
                      const unsigned *const FunctionScopeIndexToStopAt) {
        -  bool Nested = false;
        +  bool Nested = Var->isInitCapture();

           DeclContext *DC = CurContext;
           const unsigned MaxFunctionScopesIndex =
        FunctionScopeIndexToStopAt
        @@ -12259,8 +12257,13 @@ bool Sema::tryCaptureVariable(VarDecl *V

           // If the variable is declared in the current context (and
        is not an
           // init-capture), there is no need to capture it.
        -  if (!Var->isInitCapture() && Var->getDeclContext() == DC)
        return true;
        -  if (!Var->hasLocalStorage()) return true;
        +  if (!Nested && Var->getDeclContext() == DC) return true;
        +
        +  // Capture global variables if it is required to use
        private copy of this
        +  // variable.
        +  bool IsGlobal = !Var->hasLocalStorage();
        +  if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedVar(Var)))
        +    return true;

           // Walk up the stack to determine whether we can capture
        the variable,
           // performing the "simple" checks that don't depend on
        type. We stop when
        @@ -12281,8 +12284,17 @@ bool Sema::tryCaptureVariable(VarDecl *V
                     ExprLoc,
                     BuildAndDiagnose,
                     *this);
        -    if (!ParentDC) return true;
        -
        +    // We need to check for the parent *first* because, if we
        *have*
        +    // private-captured a global variable, we need to
        recursively capture it in
        +    // intermediate blocks, lambdas, etc.
        +    if (!ParentDC) {
        +      if (IsGlobal) {
        +        FunctionScopesIndex = MaxFunctionScopesIndex - 1;
        +        break;
        +      }
        +      return true;
        +    }
        +
             FunctionScopeInfo  *FSI =
        FunctionScopes[FunctionScopesIndex];
             CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FSI);

        @@ -12508,6 +12520,14 @@ bool Sema::tryCaptureVariable(VarDecl *V
                                     DeclRefType, nullptr);
         }

        +bool Sema::NeedToCaptureVariable(VarDecl *Var, SourceLocation
        Loc) {
        +  QualType CaptureType;
        +  QualType DeclRefType;
        +  return !tryCaptureVariable(Var, Loc, TryCapture_Implicit,
        SourceLocation(),
        +  /*BuildAndDiagnose=*/false, CaptureType,
        +                             DeclRefType, nullptr);
        +}
        +
         QualType Sema::getCapturedDeclRefType(VarDecl *Var,
        SourceLocation Loc) {
           QualType CaptureType;
           QualType DeclRefType;

        Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
        +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Dec 16 01:00:22 2014
        @@ -551,6 +551,19 @@ void Sema::InitDataSharingAttributesStac

         #define DSAStack static_cast<DSAStackTy
        *>(VarDataSharingAttributesStack)

        +bool Sema::IsOpenMPCapturedVar(VarDecl *VD) {
        +  assert(LangOpts.OpenMP && "OpenMP is not allowed");
        +  if (DSAStack->getCurrentDirective() != OMPD_unknown) {
        +    auto DVarPrivate = DSAStack->getTopDSA(VD,
        /*FromParent=*/false);
        +    if (DVarPrivate.CKind != OMPC_unknown &&
        isOpenMPPrivate(DVarPrivate.CKind))
        +      return true;
        +    DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate,
        MatchesAlways(),
        +  /*FromParent=*/false);
        +    return DVarPrivate.CKind != OMPC_unknown;
        +  }
        +  return false;
        +}
        +
         void Sema::DestroyDataSharingAttributesStack() { delete
        DSAStack; }

         void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
        @@ -4378,7 +4391,7 @@ OMPClause *Sema::ActOnOpenMPFirstprivate
               VDInitRefExpr = DeclRefExpr::Create(
                   Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
                   /*TemplateKWLoc*/ SourceLocation(), VDInit,
        -          /*isEnclosingLocal*/ false, ELoc, Type,
        +          /*isEnclosingLocal*/ true, ELoc, Type,
                   /*VK*/ VK_LValue);
               VDInit->setIsUsed();
               auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
        @@ -4392,8 +4405,14 @@ OMPClause *Sema::ActOnOpenMPFirstprivate
               else
         VDPrivate->setInit(Result.getAs<Expr>());
             } else {
        -      AddInitializerToDecl(VDPrivate,
        DefaultLvalueConversion(DE).get(),
        -                           /*DirectInit*/ false,
        /*TypeMayContainAuto*/ false);
        +      AddInitializerToDecl(
        +          VDPrivate, DefaultLvalueConversion(
        +  DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
        +  SourceLocation(), DE->getDecl(),
        +  /*isEnclosingLocal=*/true,
        +  DE->getExprLoc(), DE->getType(),
        +  /*VK=*/VK_LValue)).get(),
        +          /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
             }
             if (VDPrivate->isInvalidDecl()) {
               if (IsImplicitClause) {

        Modified: cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
        (original)
        +++ cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
        Tue Dec 16 01:00:22 2014
        @@ -1,6 +1,8 @@
         // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple
        %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
         // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11
        -triple %itanium_abi_triple -emit-pch -o %t %s
         // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple
        %itanium_abi_triple -std=c++11 -include-pch %t -verify %s
        -emit-llvm -o - | FileCheck %s
        +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++
        -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s
        -o - | FileCheck -check-prefix=LAMBDA %s
        +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks
        -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - |
        FileCheck -check-prefix=BLOCKS %s
         // expected-no-diagnostics
         #ifndef HEADER
         #define HEADER
        @@ -12,7 +14,7 @@ struct St {
           ~St() {}
         };

        -volatile int g;
        +volatile int g = 1212;

         template <class T>
         struct S {
        @@ -47,6 +49,83 @@ T tmain() {
         }

         int main() {
        +#ifdef LAMBDA
        +  // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
        +  // LAMBDA-LABEL: @main
        +  // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
        +  [&]() {
        +  // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
        +  // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds
        %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +  // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}**
        [[G_LOCAL_REF]]
        +  // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]]
        to i8*
        +  // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32
        1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
        +#pragma omp parallel firstprivate(g)
        +  {
        +    // LAMBDA: define{{.*}} internal{{.*}} void
        [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
        +    // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
        +    // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
        +    // LAMBDA: [[ARG:%.+]] = load %{{.+}}** [[ARG_REF]]
        +    // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr inbounds
        %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +    // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_REF_ADDR]]
        +    // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}*
        [[G_REF]]
        +    // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]],
        i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
        +    // LAMBDA: call i32 @__kmpc_cancel_barrier(
        +    g = 1;
        +    // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
        [[G_PRIVATE_ADDR]],
        +    // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr
        inbounds %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +    // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
        i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
        +    // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
        +    [&]() {
        +      // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}*
        [[ARG_PTR:%.+]])
        +      // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}**
        [[ARG_PTR_REF:%.+]],
        +      g = 2;
        +      // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}** [[ARG_PTR_REF]]
        +      // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds
        %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +      // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_PTR_REF]]
        +      // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
        [[G_REF]]
        +    }();
        +  }
        +  }();
        +  return 0;
        +#elif defined(BLOCKS)
        +  // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
        +  // BLOCKS-LABEL: @main
        +  // BLOCKS: call void {{%.+}}(i8*
        +  ^{
        +  // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
        +  // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds
        %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +  // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}**
        [[G_LOCAL_REF]]
        +  // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]]
        to i8*
        +  // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32
        1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
        +#pragma omp parallel firstprivate(g)
        +  {
        +    // BLOCKS: define{{.*}} internal{{.*}} void
        [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
        +    // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
        +    // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
        +    // BLOCKS: [[ARG:%.+]] = load %{{.+}}** [[ARG_REF]]
        +    // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr inbounds
        %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +    // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_REF_ADDR]]
        +    // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}*
        [[G_REF]]
        +    // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]],
        i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
        +    // BLOCKS: call i32 @__kmpc_cancel_barrier(
        +    g = 1;
        +    // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
        [[G_PRIVATE_ADDR]],
        +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
        +    // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
        +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
        +    // BLOCKS: call void {{%.+}}(i8*
        +    ^{
        +      // BLOCKS: define {{.+}} void {{@.+}}(i8*
        +      g = 2;
        +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
        +      // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
        +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
        +      // BLOCKS: ret
        +    }();
        +  }
        +  }();
        +  return 0;
        +#else
           S<float> test;
           int t_var = 0;
           int vec[] = {1, 2};
        @@ -58,6 +137,7 @@ int main() {
             s_arr[0] = var;
           }
           return tmain<int>();
        +#endif
         }

         // CHECK: define {{.*}}i{{[0-9]+}} @main()

        Modified: cfe/trunk/test/OpenMP/parallel_private_codegen.cpp
        URL:
        
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_private_codegen.cpp?rev=224323&r1=224322&r2=224323&view=diff
        
==============================================================================
        --- cfe/trunk/test/OpenMP/parallel_private_codegen.cpp (original)
        +++ cfe/trunk/test/OpenMP/parallel_private_codegen.cpp Tue Dec
        16 01:00:22 2014
        @@ -1,6 +1,8 @@
         // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple
        x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
         // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11
        -triple x86_64-unknown-unknown -emit-pch -o %t %s
         // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple
        x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s
        -emit-llvm -o - | FileCheck %s
        +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++
        -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s
        -o - | FileCheck -check-prefix=LAMBDA %s
        +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks
        -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - |
        FileCheck -check-prefix=BLOCKS %s
         // expected-no-diagnostics
         #ifndef HEADER
         #define HEADER
        @@ -14,6 +16,8 @@ struct S {
           ~S() {}
         };

        +volatile int g = 1212;
        +
         // CHECK: [[S_FLOAT_TY:%.+]] = type { float }
         // CHECK: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*,
        i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* }
         // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
        @@ -22,7 +26,7 @@ struct S {
         template <typename T>
         T tmain() {
           S<T> test;
        -  T t_var;
        +  T t_var = T();
           T vec[] = {1, 2};
           S<T> s_arr[] = {1, 2};
           S<T> var(3);
        @@ -35,8 +39,75 @@ T tmain() {
         }

         int main() {
        +#ifdef LAMBDA
        +  // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
        +  // LAMBDA-LABEL: @main
        +  // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
        +  [&]() {
        +  // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
        +  // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds
        %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +  // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}**
        [[G_LOCAL_REF]]
        +  // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]]
        to i8*
        +  // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32
        1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
        +#pragma omp parallel private(g)
        +  {
        +    // LAMBDA: define{{.*}} internal{{.*}} void
        [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
        +    // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
        +    // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
        +    // LAMBDA: call i32 @__kmpc_cancel_barrier(
        +    g = 1;
        +    // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
        [[G_PRIVATE_ADDR]],
        +    // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr
        inbounds %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +    // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
        i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
        +    // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
        +    [&]() {
        +      // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}*
        [[ARG_PTR:%.+]])
        +      // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}**
        [[ARG_PTR_REF:%.+]],
        +      g = 2;
        +      // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}** [[ARG_PTR_REF]]
        +      // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds
        %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +      // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_PTR_REF]]
        +      // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
        [[G_REF]]
        +    }();
        +  }
        +  }();
        +  return 0;
        +#elif defined(BLOCKS)
        +  // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
        +  // BLOCKS-LABEL: @main
        +  // BLOCKS: call void {{%.+}}(i8*
        +  ^{
        +  // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
        +  // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds
        %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
        +  // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}**
        [[G_LOCAL_REF]]
        +  // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]]
        to i8*
        +  // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32
        1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
        +#pragma omp parallel private(g)
        +  {
        +    // BLOCKS: define{{.*}} internal{{.*}} void
        [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
        +    // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
        +    // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
        +    // BLOCKS: call i32 @__kmpc_cancel_barrier(
        +    g = 1;
        +    // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
        [[G_PRIVATE_ADDR]],
        +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
        +    // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
        +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
        +    // BLOCKS: call void {{%.+}}(i8*
        +    ^{
        +      // BLOCKS: define {{.+}} void {{@.+}}(i8*
        +      g = 2;
        +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
        +      // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
        +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
        +      // BLOCKS: ret
        +    }();
        +  }
        +  }();
        +  return 0;
        +#else
           S<float> test;
        -  int t_var;
        +  int t_var = 0;
           int vec[] = {1, 2};
           S<float> s_arr[] = {1, 2};
           S<float> var(3);
        @@ -46,6 +117,7 @@ int main() {
             s_arr[0] = var;
           }
           return tmain<int>();
        +#endif
         }

         // CHECK: define i{{[0-9]+}} @main()


        _______________________________________________
        cfe-commits mailing list
        [email protected] <mailto:[email protected]>
        http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to