r259776 - [OPENMP 4.0] Fixed support of array sections/array subscripts.

Hahnfeld, Jonas via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 17 04:18:59 PDT 2016


Hi Alexey,

I think this now also affects the released version of Clang 3.8.0.
Can this be merged for 3.8.1 if such a version will exist somewhen?

Thanks,
Jonas

> -----Original Message-----
> From: cfe-commits [mailto:cfe-commits-bounces at lists.llvm.org] On Behalf
> Of Alexey Bataev via cfe-commits
> Sent: Thursday, February 04, 2016 12:27 PM
> To: cfe-commits at lists.llvm.org
> Subject: r259776 - [OPENMP 4.0] Fixed support of array sections/array
> subscripts.
>
> Author: abataev
> Date: Thu Feb  4 05:27:03 2016
> New Revision: 259776
>
> URL: http://llvm.org/viewvc/llvm-project?rev=259776&view=rev
> Log:
> [OPENMP 4.0] Fixed support of array sections/array subscripts.
> Codegen for array sections/array subscripts worked only for expressions with
> arrays as base. Patch fixes codegen for bases with pointer/reference types.
>
> Modified:
>     cfe/trunk/include/clang/AST/ExprOpenMP.h
>     cfe/trunk/lib/AST/Expr.cpp
>     cfe/trunk/lib/CodeGen/CGExpr.cpp
>     cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
>     cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
>     cfe/trunk/lib/CodeGen/CodeGenFunction.h
>     cfe/trunk/lib/Sema/SemaExpr.cpp
>     cfe/trunk/lib/Sema/SemaOpenMP.cpp
>     cfe/trunk/test/OpenMP/for_reduction_codegen.cpp
>     cfe/trunk/test/OpenMP/task_codegen.cpp
>
> Modified: cfe/trunk/include/clang/AST/ExprOpenMP.h
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/include/clang/AST/ExprOpenMP.h?rev=259776&r1=25977
> 5&r2=259776&view=diff
> ==========================================================
> ====================
> --- cfe/trunk/include/clang/AST/ExprOpenMP.h (original)
> +++ cfe/trunk/include/clang/AST/ExprOpenMP.h Thu Feb  4 05:27:03 2016
> @@ -85,7 +85,7 @@ public:
>    void setBase(Expr *E) { SubExprs[BASE] = E; }
>
>    /// \brief Return original type of the base expression for array section.
> -  static QualType getBaseOriginalType(Expr *Base);
> +  static QualType getBaseOriginalType(const Expr *Base);
>
>    /// \brief Get lower bound of array section.
>    Expr *getLowerBound() { return
> cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
>
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/AST/Expr.cpp?rev=259776&r1=259775&r2=259776&vie
> w=diff
> ==========================================================
> ====================
> --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Thu Feb  4 05:27:03 2016
> @@ -4026,16 +4026,18 @@ unsigned AtomicExpr::getNumSubExprs(Atom
>    llvm_unreachable("unknown atomic op");  }
>
> -QualType OMPArraySectionExpr::getBaseOriginalType(Expr *Base) {
> +QualType OMPArraySectionExpr::getBaseOriginalType(const Expr *Base) {
>    unsigned ArraySectionCount = 0;
>    while (auto *OASE = dyn_cast<OMPArraySectionExpr>(Base-
> >IgnoreParens())) {
>      Base = OASE->getBase();
>      ++ArraySectionCount;
>    }
> -  while (auto *ASE = dyn_cast<ArraySubscriptExpr>(Base->IgnoreParens()))
> {
> +  while (auto *ASE =
> +             dyn_cast<ArraySubscriptExpr>(Base->IgnoreParenImpCasts()))
> + {
>      Base = ASE->getBase();
>      ++ArraySectionCount;
>    }
> +  Base = Base->IgnoreParenImpCasts();
>    auto OriginalTy = Base->getType();
>    if (auto *DRE = dyn_cast<DeclRefExpr>(Base))
>      if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
>
> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=259776&r1=259775&r2=259
> 776&view=diff
> ==========================================================
> ====================
> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Feb  4 05:27:03 2016
> @@ -1949,6 +1949,21 @@ LValue CodeGenFunction::EmitLoadOfRefere
>    return MakeAddrLValue(Addr, RefTy->getPointeeType(), Source);  }
>
> +Address CodeGenFunction::EmitLoadOfPointer(Address Ptr,
> +                                           const PointerType *PtrTy,
> +                                           AlignmentSource *Source) {
> +  llvm::Value *Addr = Builder.CreateLoad(Ptr);
> +  return Address(Addr, getNaturalTypeAlignment(PtrTy->getPointeeType(),
> Source,
> +
> +/*forPointeeType=*/true)); }
> +
> +LValue CodeGenFunction::EmitLoadOfPointerLValue(Address PtrAddr,
> +                                                const PointerType
> +*PtrTy) {
> +  AlignmentSource Source;
> +  Address Addr = EmitLoadOfPointer(PtrAddr, PtrTy, &Source);
> +  return MakeAddrLValue(Addr, PtrTy->getPointeeType(), Source); }
> +
>  static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
>                                        const Expr *E, const VarDecl *VD) {
>    QualType T = E->getType();
> @@ -2934,21 +2949,54 @@ LValue CodeGenFunction::EmitArraySubscri
>    return LV;
>  }
>
> +static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const
> Expr *Base,
> +                                       AlignmentSource &AlignSource,
> +                                       QualType BaseTy, QualType ElTy,
> +                                       bool IsLowerBound) {
> +  LValue BaseLVal;
> +  if (auto *ASE = dyn_cast<OMPArraySectionExpr>(Base-
> >IgnoreParenImpCasts())) {
> +    BaseLVal = CGF.EmitOMPArraySectionExpr(ASE, IsLowerBound);
> +    if (BaseTy->isArrayType()) {
> +      Address Addr = BaseLVal.getAddress();
> +      AlignSource = BaseLVal.getAlignmentSource();
> +
> +      // If the array type was an incomplete type, we need to make sure
> +      // the decay ends up being the right type.
> +      llvm::Type *NewTy = CGF.ConvertType(BaseTy);
> +      Addr = CGF.Builder.CreateElementBitCast(Addr, NewTy);
> +
> +      // Note that VLA pointers are always decayed, so we don't need to do
> +      // anything here.
> +      if (!BaseTy->isVariableArrayType()) {
> +        assert(isa<llvm::ArrayType>(Addr.getElementType()) &&
> +               "Expected pointer to array");
> +        Addr = CGF.Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(),
> +                                           "arraydecay");
> +      }
> +
> +      return CGF.Builder.CreateElementBitCast(Addr,
> +                                              CGF.ConvertTypeForMem(ElTy));
> +    }
> +    CharUnits Align = CGF.getNaturalTypeAlignment(ElTy, &AlignSource);
> +    return Address(CGF.Builder.CreateLoad(BaseLVal.getAddress()),
> +Align);
> +  }
> +  return CGF.EmitPointerWithAlignment(Base, &AlignSource); }
> +
>  LValue CodeGenFunction::EmitOMPArraySectionExpr(const
> OMPArraySectionExpr *E,
>                                                  bool IsLowerBound) {
> -  LValue Base;
> +  QualType BaseTy;
>    if (auto *ASE =
>            dyn_cast<OMPArraySectionExpr>(E->getBase()-
> >IgnoreParenImpCasts()))
> -    Base = EmitOMPArraySectionExpr(ASE, IsLowerBound);
> +    BaseTy = OMPArraySectionExpr::getBaseOriginalType(ASE);
>    else
> -    Base = EmitLValue(E->getBase());
> -  QualType BaseTy = Base.getType();
> -  llvm::Value *Idx = nullptr;
> +    BaseTy = E->getBase()->getType();
>    QualType ResultExprTy;
>    if (auto *AT = getContext().getAsArrayType(BaseTy))
>      ResultExprTy = AT->getElementType();
>    else
>      ResultExprTy = BaseTy->getPointeeType();
> +  llvm::Value *Idx = nullptr;
>    if (IsLowerBound || (!IsLowerBound && E->getColonLoc().isInvalid())) {
>      // Requesting lower bound or upper bound, but without provided length
> and
>      // without ':' symbol for the default length -> length = 1.
> @@ -2960,9 +3008,9 @@ LValue CodeGenFunction::EmitOMPArraySect
>      } else
>        Idx = llvm::ConstantInt::getNullValue(IntPtrTy);
>    } else {
> -    // Try to emit length or lower bound as constant. If this is possible, 
> 1 is
> -    // subtracted from constant length or lower bound. Otherwise, emit LLVM
> IR
> -    // (LB + Len) - 1.
> +    // Try to emit length or lower bound as constant. If this is possible, 
> 1
> +    // is subtracted from constant length or lower bound. Otherwise, emit
> LLVM
> +    // IR (LB + Len) - 1.
>      auto &C = CGM.getContext();
>      auto *Length = E->getLength();
>      llvm::APSInt ConstLength;
> @@ -3008,12 +3056,15 @@ LValue CodeGenFunction::EmitOMPArraySect
>          Idx = llvm::ConstantInt::get(IntPtrTy, ConstLength + 
> ConstLowerBound);
>      } else {
>        // Idx = ArraySize - 1;
> -      if (auto *VAT = C.getAsVariableArrayType(BaseTy)) {
> +      QualType ArrayTy = BaseTy->isPointerType()
> +                             ? 
> E->getBase()->IgnoreParenImpCasts()->getType()
> +                             : BaseTy;
> +      if (auto *VAT = C.getAsVariableArrayType(ArrayTy)) {
>          Length = VAT->getSizeExpr();
>          if (Length->isIntegerConstantExpr(ConstLength, C))
>            Length = nullptr;
>        } else {
> -        auto *CAT = C.getAsConstantArrayType(BaseTy);
> +        auto *CAT = C.getAsConstantArrayType(ArrayTy);
>          ConstLength = CAT->getSize();
>        }
>        if (Length) {
> @@ -3032,52 +3083,56 @@ LValue CodeGenFunction::EmitOMPArraySect
>    }
>    assert(Idx);
>
> -  llvm::Value *EltPtr;
> -  QualType FixedSizeEltType = ResultExprTy;
> +  Address EltPtr = Address::invalid();
> +  AlignmentSource AlignSource;
>    if (auto *VLA = getContext().getAsVariableArrayType(ResultExprTy)) {
> +    // The base must be a pointer, which is not an aggregate.  Emit
> +    // it.  It needs to be emitted first in case it's what captures
> +    // the VLA bounds.
> +    Address Base =
> +        emitOMPArraySectionBase(*this, E->getBase(), AlignSource, BaseTy,
> +                                VLA->getElementType(), IsLowerBound);
>      // The element count here is the total number of non-VLA elements.
> -    llvm::Value *numElements = getVLASize(VLA).first;
> -    FixedSizeEltType = getFixedSizeElementType(getContext(), VLA);
> +    llvm::Value *NumElements = getVLASize(VLA).first;
>
>      // Effectively, the multiply by the VLA size is part of the GEP.
>      // GEP indexes are signed, and scaling an index isn't permitted to
>      // signed-overflow, so we use the same semantics for our explicit
>      // multiply.  We suppress this if overflow is not undefined behavior.
> -    if (getLangOpts().isSignedOverflowDefined()) {
> -      Idx = Builder.CreateMul(Idx, numElements);
> -      EltPtr = Builder.CreateGEP(Base.getPointer(), Idx, "arrayidx");
> -    } else {
> -      Idx = Builder.CreateNSWMul(Idx, numElements);
> -      EltPtr = Builder.CreateInBoundsGEP(Base.getPointer(), Idx, 
> "arrayidx");
> -    }
> -  } else if (BaseTy->isConstantArrayType()) {
> -    llvm::Value *ArrayPtr = Base.getPointer();
> -    llvm::Value *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
> -    llvm::Value *Args[] = {Zero, Idx};
> -
>      if (getLangOpts().isSignedOverflowDefined())
> -      EltPtr = Builder.CreateGEP(ArrayPtr, Args, "arrayidx");
> +      Idx = Builder.CreateMul(Idx, NumElements);
>      else
> -      EltPtr = Builder.CreateInBoundsGEP(ArrayPtr, Args, "arrayidx");
> -  } else {
> -    // The base must be a pointer, which is not an aggregate.  Emit it.
> -    if (getLangOpts().isSignedOverflowDefined())
> -      EltPtr = Builder.CreateGEP(Base.getPointer(), Idx, "arrayidx");
> +      Idx = Builder.CreateNSWMul(Idx, NumElements);
> +    EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(),
> +
> + !getLangOpts().isSignedOverflowDefined());
> +  } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
> +    // If this is A[i] where A is an array, the frontend will have decayed 
> the
> +    // base to be a ArrayToPointerDecay implicit cast.  While correct, it 
> is
> +    // inefficient at -O0 to emit a "gep A, 0, 0" when codegen'ing it, then 
> a
> +    // "gep x, i" here.  Emit one "gep A, 0, i".
> +    assert(Array->getType()->isArrayType() &&
> +           "Array to pointer decay must have array source type!");
> +    LValue ArrayLV;
> +    // For simple multidimensional array indexing, set the 'accessed' flag 
> for
> +    // better bounds-checking of the base expression.
> +    if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
> +      ArrayLV = EmitArraySubscriptExpr(ASE, /*Accessed*/ true);
>      else
> -      EltPtr = Builder.CreateInBoundsGEP(Base.getPointer(), Idx, 
> "arrayidx");
> -  }
> -
> -  CharUnits EltAlign =
> -    Base.getAlignment().alignmentOfArrayElement(
> - 
> getContext().getTypeSizeInChars(FixedSizeEltType));
> -
> -  // Limit the alignment to that of the result type.
> -  LValue LV = MakeAddrLValue(Address(EltPtr, EltAlign), ResultExprTy,
> -                             Base.getAlignmentSource());
> +      ArrayLV = EmitLValue(Array);
>
> -  LV.getQuals().setAddressSpace(BaseTy.getAddressSpace());
> +    // Propagate the alignment from the array itself to the result.
> +    EltPtr = emitArraySubscriptGEP(
> +        *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
> +        ResultExprTy, !getLangOpts().isSignedOverflowDefined());
> +    AlignSource = ArrayLV.getAlignmentSource();  } else {
> +    Address Base = emitOMPArraySectionBase(*this, E->getBase(),
> AlignSource,
> +                                           BaseTy, ResultExprTy, 
> IsLowerBound);
> +    EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy,
> +
> + !getLangOpts().isSignedOverflowDefined());
> +  }
>
> -  return LV;
> +  return MakeAddrLValue(EltPtr, ResultExprTy, AlignSource);
>  }
>
>  LValue CodeGenFunction::
>
> Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=259776&r1=25
> 9775&r2=259776&view=diff
> ==========================================================
> ====================
> --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Thu Feb  4 05:27:03
> 2016
> @@ -272,18 +272,10 @@ public:
>
>  } // anonymous namespace
>
> -static LValue emitLoadOfPointerLValue(CodeGenFunction &CGF, Address
> PtrAddr,
> -                                      QualType Ty) {
> -  AlignmentSource Source;
> -  CharUnits Align = CGF.getNaturalPointeeTypeAlignment(Ty, &Source);
> -  return CGF.MakeAddrLValue(Address(CGF.Builder.CreateLoad(PtrAddr),
> Align),
> -                            Ty->getPointeeType(), Source);
> -}
> -
>  LValue
> CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction
> &CGF) {
> -  return emitLoadOfPointerLValue(CGF,
> - 
> CGF.GetAddrOfLocalVar(getThreadIDVariable()),
> -                                 getThreadIDVariable()->getType());
> +  return CGF.EmitLoadOfPointerLValue(
> +      CGF.GetAddrOfLocalVar(getThreadIDVariable()),
> +      getThreadIDVariable()->getType()->castAs<PointerType>());
>  }
>
>  void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt
> * /*S*/) { @@ -2567,8 +2559,9 @@
> emitProxyTaskFunction(CodeGenModule &CGM
>    // tt->task_data.shareds);
>    auto *GtidParam = CGF.EmitLoadOfScalar(
>        CGF.GetAddrOfLocalVar(&GtidArg), /*Volatile=*/false, KmpInt32Ty, 
> Loc);
> -  LValue TDBase = emitLoadOfPointerLValue(
> -      CGF, CGF.GetAddrOfLocalVar(&TaskTypeArg),
> KmpTaskTWithPrivatesPtrQTy);
> +  LValue TDBase = CGF.EmitLoadOfPointerLValue(
> +      CGF.GetAddrOfLocalVar(&TaskTypeArg),
> +      KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
>    auto *KmpTaskTWithPrivatesQTyRD =
>        cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
>    LValue Base =
> @@ -2632,8 +2625,9 @@ static llvm::Value *emitDestructorsFunct
>    CGF.StartFunction(GlobalDecl(), KmpInt32Ty, DestructorFn,
> DestructorFnInfo,
>                      Args);
>
> -  LValue Base = emitLoadOfPointerLValue(
> -      CGF, CGF.GetAddrOfLocalVar(&TaskTypeArg),
> KmpTaskTWithPrivatesPtrQTy);
> +  LValue Base = CGF.EmitLoadOfPointerLValue(
> +      CGF.GetAddrOfLocalVar(&TaskTypeArg),
> +      KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
>    auto *KmpTaskTWithPrivatesQTyRD =
>        cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
>    auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
> @@ -2711,16 +2705,17 @@ emitTaskPrivateMappingFunction(CodeGenMo
>                      TaskPrivatesMapFnInfo, Args);
>
>    // *privi = &.privates.privi;
> -  LValue Base = emitLoadOfPointerLValue(
> -      CGF, CGF.GetAddrOfLocalVar(&TaskPrivatesArg),
> TaskPrivatesArg.getType());
> +  LValue Base = CGF.EmitLoadOfPointerLValue(
> +      CGF.GetAddrOfLocalVar(&TaskPrivatesArg),
> +      TaskPrivatesArg.getType()->castAs<PointerType>());
>    auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->getAsTagDecl());
>    Counter = 0;
>    for (auto *Field : PrivatesQTyRD->fields()) {
>      auto FieldLVal = CGF.EmitLValueForField(Base, Field);
>      auto *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
>      auto RefLVal = CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(VD), VD-
> >getType());
> -    auto RefLoadLVal =
> -        emitLoadOfPointerLValue(CGF, RefLVal.getAddress(),
> RefLVal.getType());
> +    auto RefLoadLVal = CGF.EmitLoadOfPointerLValue(
> +        RefLVal.getAddress(),
> + RefLVal.getType()->castAs<PointerType>());
>      CGF.EmitStoreOfScalar(FieldLVal.getPointer(), RefLoadLVal);
>      ++Counter;
>    }
>
> Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=259776&r1=25977
> 5&r2=259776&view=diff
> ==========================================================
> ====================
> --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Thu Feb  4 05:27:03 2016
> @@ -672,6 +672,54 @@ void CodeGenFunction::EmitOMPLastprivate
>    }
>  }
>
> +static Address castToBase(CodeGenFunction &CGF, QualType BaseTy,
> QualType ElTy,
> +                          LValue BaseLV, llvm::Value *Addr) {
> +  Address Tmp = Address::invalid();
> +  Address TopTmp = Address::invalid();
> +  Address MostTopTmp = Address::invalid();
> +  BaseTy = BaseTy.getNonReferenceType();
> +  while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
> +         !CGF.getContext().hasSameType(BaseTy, ElTy)) {
> +    Tmp = CGF.CreateMemTemp(BaseTy);
> +    if (TopTmp.isValid())
> +      CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);
> +    else
> +      MostTopTmp = Tmp;
> +    TopTmp = Tmp;
> +    BaseTy = BaseTy->getPointeeType();
> +  }
> +  llvm::Type *Ty = BaseLV.getPointer()->getType();
> +  if (Tmp.isValid())
> +    Ty = Tmp.getElementType();
> +  Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);
> +  if (Tmp.isValid()) {
> +    CGF.Builder.CreateStore(Addr, Tmp);
> +    return MostTopTmp;
> +  }
> +  return Address(Addr, BaseLV.getAlignment()); }
> +
> +static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy,
> QualType ElTy,
> +                          LValue BaseLV) {
> +  BaseTy = BaseTy.getNonReferenceType();
> +  while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
> +         !CGF.getContext().hasSameType(BaseTy, ElTy)) {
> +    if (auto *PtrTy = BaseTy->getAs<PointerType>())
> +      BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
> +    else {
> +      BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(),
> + 
> BaseTy->castAs<ReferenceType>());
> +    }
> +    BaseTy = BaseTy->getPointeeType();
> +  }
> +  return CGF.MakeAddrLValue(
> +      Address(
> +          CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
> +              BaseLV.getPointer(), CGF.ConvertTypeForMem(ElTy)-
> >getPointerTo()),
> +          BaseLV.getAlignment()),
> +      BaseLV.getType(), BaseLV.getAlignmentSource()); }
> +
>  void CodeGenFunction::EmitOMPReductionClauseInit(
>      const OMPExecutableDirective &D,
>      CodeGenFunction::OMPPrivateScope &PrivateScope) { @@ -697,21 +745,9
> @@ void CodeGenFunction::EmitOMPReductionCl
>          auto OASELValueUB =
>              EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);
>          auto OriginalBaseLValue = EmitLValue(DE);
> -        auto BaseLValue = OriginalBaseLValue;
> -        auto *Zero = Builder.getInt64(/*C=*/0);
> -        llvm::SmallVector<llvm::Value *, 4> Indexes;
> -        Indexes.push_back(Zero);
> -        auto *ItemTy =
> -            OASELValueLB.getPointer()->getType()->getPointerElementType();
> -        auto *Ty = BaseLValue.getPointer()->getType()-
> >getPointerElementType();
> -        while (Ty != ItemTy) {
> -          Indexes.push_back(Zero);
> -          Ty = Ty->getPointerElementType();
> -        }
> -        BaseLValue = MakeAddrLValue(
> -            Address(Builder.CreateInBoundsGEP(BaseLValue.getPointer(),
> Indexes),
> -                    OASELValueLB.getAlignment()),
> -            OASELValueLB.getType(), OASELValueLB.getAlignmentSource());
> +        LValue BaseLValue =
> +            loadToBegin(*this, OrigVD->getType(), OASELValueLB.getType(),
> +                        OriginalBaseLValue);
>          // Store the address of the original variable associated with the 
> LHS
>          // implicit variable.
>          PrivateScope.addPrivate(LHSVD, [this, OASELValueLB]() -> Address {
> @@ -719,8 +755,8 @@ void CodeGenFunction::EmitOMPReductionCl
>          });
>          // Emit reduction copy.
>          bool IsRegistered = PrivateScope.addPrivate(
> -            OrigVD, [this, PrivateVD, BaseLValue, OASELValueLB, 
> OASELValueUB,
> -                     OriginalBaseLValue]() -> Address {
> +            OrigVD, [this, OrigVD, PrivateVD, BaseLValue, OASELValueLB,
> +                     OASELValueUB, OriginalBaseLValue]() -> Address {
>                // Emit VarDecl with copy init for arrays.
>                // Get the address of the original variable captured in 
> current
>                // captured region.
> @@ -744,9 +780,9 @@ void CodeGenFunction::EmitOMPReductionCl
>                auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),
> 
> OASELValueLB.getPointer());
>                auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);
> -              Ptr = Builder.CreatePointerBitCastOrAddrSpaceCast(
> -                  Ptr, OriginalBaseLValue.getPointer()->getType());
> -              return Address(Ptr, OriginalBaseLValue.getAlignment());
> +              return castToBase(*this, OrigVD->getType(),
> +                                OASELValueLB.getType(), OriginalBaseLValue,
> +                                Ptr);
>              });
>          assert(IsRegistered && "private var already registered as 
> private");
>          // Silence the warning about unused variable.
> @@ -762,21 +798,8 @@ void CodeGenFunction::EmitOMPReductionCl
>          auto *OrigVD = cast<VarDecl>(DE->getDecl());
>          auto ASELValue = EmitLValue(ASE);
>          auto OriginalBaseLValue = EmitLValue(DE);
> -        auto BaseLValue = OriginalBaseLValue;
> -        auto *Zero = Builder.getInt64(/*C=*/0);
> -        llvm::SmallVector<llvm::Value *, 4> Indexes;
> -        Indexes.push_back(Zero);
> -        auto *ItemTy =
> -            ASELValue.getPointer()->getType()->getPointerElementType();
> -        auto *Ty = BaseLValue.getPointer()->getType()-
> >getPointerElementType();
> -        while (Ty != ItemTy) {
> -          Indexes.push_back(Zero);
> -          Ty = Ty->getPointerElementType();
> -        }
> -        BaseLValue = MakeAddrLValue(
> -            Address(Builder.CreateInBoundsGEP(BaseLValue.getPointer(),
> Indexes),
> -                    ASELValue.getAlignment()),
> -            ASELValue.getType(), ASELValue.getAlignmentSource());
> +        LValue BaseLValue = loadToBegin(
> +            *this, OrigVD->getType(), ASELValue.getType(),
> + OriginalBaseLValue);
>          // Store the address of the original variable associated with the 
> LHS
>          // implicit variable.
>          PrivateScope.addPrivate(LHSVD, [this, ASELValue]() -> Address { 
> @@ -
> 784,7 +807,7 @@ void CodeGenFunction::EmitOMPReductionCl
>          });
>          // Emit reduction copy.
>          bool IsRegistered = PrivateScope.addPrivate(
> -            OrigVD, [this, PrivateVD, BaseLValue, ASELValue,
> +            OrigVD, [this, OrigVD, PrivateVD, BaseLValue, ASELValue,
>                       OriginalBaseLValue]() -> Address {
>                // Emit private VarDecl with reduction init.
>                EmitDecl(*PrivateVD);
> @@ -792,9 +815,8 @@ void CodeGenFunction::EmitOMPReductionCl
>                auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),
>                                                     ASELValue.getPointer());
>                auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);
> -              Ptr = Builder.CreatePointerBitCastOrAddrSpaceCast(
> -                  Ptr, OriginalBaseLValue.getPointer()->getType());
> -              return Address(Ptr, OriginalBaseLValue.getAlignment());
> +              return castToBase(*this, OrigVD->getType(), 
> ASELValue.getType(),
> +                                OriginalBaseLValue, Ptr);
>              });
>          assert(IsRegistered && "private var already registered as 
> private");
>          // Silence the warning about unused variable.
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=259776&r1=259775
> &r2=259776&view=diff
> ==========================================================
> ====================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Feb  4 05:27:03 2016
> @@ -1574,6 +1574,10 @@ public:
>                                AlignmentSource *Source = nullptr);
>    LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType
> *RefTy);
>
> +  Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy,
> +                            AlignmentSource *Source = nullptr);  LValue
> + EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy);
> +
>    /// CreateTempAlloca - This creates a alloca and inserts it into the 
> entry
>    /// block. The caller is responsible for setting an appropriate alignment 
> on
>    /// the alloca.
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=259776&r1=259775&r2=2597
> 76&view=diff
> ==========================================================
> ====================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Feb  4 05:27:03 2016
> @@ -4148,12 +4148,18 @@ ExprResult Sema::ActOnOMPArraySectionExp
>      ExprResult Result = CheckPlaceholderExpr(LowerBound);
>      if (Result.isInvalid())
>        return ExprError();
> +    Result = DefaultLvalueConversion(Result.get());
> +    if (Result.isInvalid())
> +      return ExprError();
>      LowerBound = Result.get();
>    }
>    if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
>      ExprResult Result = CheckPlaceholderExpr(Length);
>      if (Result.isInvalid())
>        return ExprError();
> +    Result = DefaultLvalueConversion(Result.get());
> +    if (Result.isInvalid())
> +      return ExprError();
>      Length = Result.get();
>    }
>
> @@ -4260,6 +4266,13 @@ ExprResult Sema::ActOnOMPArraySectionExp
>      return ExprError();
>    }
>
> +  if (!Base->getType()->isSpecificPlaceholderType(
> +          BuiltinType::OMPArraySection)) {
> +    ExprResult Result = DefaultFunctionArrayLvalueConversion(Base);
> +    if (Result.isInvalid())
> +      return ExprError();
> +    Base = Result.get();
> +  }
>    return new (Context)
>        OMPArraySectionExpr(Base, LowerBound, Length,
> Context.OMPArraySectionTy,
>                            VK_LValue, OK_Ordinary, ColonLoc, RBLoc);
>
> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=259776&r1=259775&r2=
> 259776&view=diff
> ==========================================================
> ====================
> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Feb  4 05:27:03 2016
> @@ -7745,9 +7745,9 @@ OMPClause *Sema::ActOnOpenMPReductionCla
>      if (DE) {
>        auto D = DE->getDecl();
>        VD = cast<VarDecl>(D);
> -      Type = Context.getBaseElementType(VD->getType());
> +      Type =
> + Context.getBaseElementType(VD->getType().getNonReferenceType());
>      } else if (ASE) {
> -      Type = ASE->getType();
> +      Type = ASE->getType().getNonReferenceType();
>        auto *Base = ASE->getBase()->IgnoreParenImpCasts();
>        while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
>          Base = TempASE->getBase()->IgnoreParenImpCasts();
> @@ -7765,6 +7765,7 @@ OMPClause *Sema::ActOnOpenMPReductionCla
>          Type = ATy->getElementType();
>        else
>          Type = BaseType->getPointeeType();
> +      Type = Type.getNonReferenceType();
>        auto *Base = OASE->getBase()->IgnoreParenImpCasts();
>        while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
>          Base = TempOASE->getBase()->IgnoreParenImpCasts();
> @@ -7806,7 +7807,7 @@ OMPClause *Sema::ActOnOpenMPReductionCla
>      //  for all threads of the team.
>      if (!ASE && !OASE) {
>        VarDecl *VDDef = VD->getDefinition();
> -      if (Type->isReferenceType() && VDDef) {
> +      if (VD->getType()->isReferenceType() && VDDef) {
>          DSARefChecker Check(DSAStack);
>          if (Check.Visit(VDDef->getInit())) {
>            Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; @@ -
> 8737,8 +8738,12 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe
>          auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
>          if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
>              (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) 
> ||
> -            (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
> -             !ASE->getBase()->getType()->isArrayType())) {
> +            (ASE &&
> +             !ASE->getBase()
> +                  ->getType()
> +                  .getNonReferenceType()
> +                  ->isPointerType() &&
> +
> + !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
>            Diag(ELoc,
> diag::err_omp_expected_var_name_member_expr_or_array_item)
>                << 0 << RefExpr->getSourceRange();
>            continue;
>
> Modified: cfe/trunk/test/OpenMP/for_reduction_codegen.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/test/OpenMP/for_reduction_codegen.cpp?rev=259776&r
> 1=259775&r2=259776&view=diff
> ==========================================================
> ====================
> --- cfe/trunk/test/OpenMP/for_reduction_codegen.cpp (original)
> +++ cfe/trunk/test/OpenMP/for_reduction_codegen.cpp Thu Feb  4
> 05:27:03
> +++ 2016
> @@ -52,6 +52,8 @@ T tmain() {
>    return T();
>  }
>
> +extern S<float> **foo();
> +
>  int main() {
>  #ifdef LAMBDA
>    // LAMBDA: [[G:@.+]] = global double
> @@ -182,6 +184,9 @@ int main() {
>    S<float> s_arr[] = {1, 2};
>    S<float> &var = test;
>    S<float> var1, arrs[10][4];
> +  S<float> **var2 = foo();
> +  S<float> vvar2[2];
> +  S<float> (&var3)[2] = s_arr;
>  #pragma omp parallel
>  #pragma omp for reduction(+:t_var) reduction(&:var) reduction(&& : var1)
> reduction(min: t_var1)
>    for (int i = 0; i < 2; ++i) {
> @@ -196,6 +201,22 @@ int main() {
>  #pragma omp for reduction(+:arr) reduction(&:arrs)
>    for (int i = 0; i < 10; ++i)
>      ++arr[1][i];
> +#pragma omp parallel
> +#pragma omp for reduction(& : var2[0 : 5][1 : 6])
> +  for (int i = 0; i < 10; ++i)
> +    ;
> +#pragma omp parallel
> +#pragma omp for reduction(& : vvar2[0 : 5])
> +  for (int i = 0; i < 10; ++i)
> +    ;
> +#pragma omp parallel
> +#pragma omp for reduction(& : var3[1 : 2])
> +  for (int i = 0; i < 10; ++i)
> +    ;
> +#pragma omp parallel
> +#pragma omp for reduction(& : var3)
> +  for (int i = 0; i < 10; ++i)
> +    ;
>    return tmain<int>();
>  #endif
>  }
> @@ -206,6 +227,10 @@ int main() {
>  // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, 
> i{{[0-9]+}}*, ...)*,
> ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, 
> i{{[0-
> 9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, 
> [[S_FLOAT_TY]]*,
> [[S_FLOAT_TY]]*, float*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*)*
> [[MAIN_MICROTASK:@.+]] to void  // CHECK: call void (%{{.+}}*, i{{[0-9]+}},
> void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* 
> @{{.+}},
> i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void 
> (i{{[0-9]+}}*,
> i{{[0-9]+}}*, i64, i64, i32*, [2 x i32]*, [10 x [4 x [[S_FLOAT_TY]]]]*)*
> [[MAIN_MICROTASK1:@.+]] to void  // CHECK: call void (%{{.+}}*, i{{[0-9]+}},
> void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* 
> @{{.+}},
> i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void 
> (i{{[0-9]+}}*,
> i{{[0-9]+}}*, i64, i64, i32*, [10 x [4 x [[S_FLOAT_TY]]]]*)*
> [[MAIN_MICROTASK2:@.+]] to void
> +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*,
> +i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}},
> +i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void
> +(i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)*
> +[[MAIN_MICROTASK3:@.+]] to void // CHECK: call void (%{{.+}}*,
> +i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)
> + at __kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*,
> +i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x
> +[[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK4:@.+]] to void // CHECK: call void
> +(%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)
> + at __kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*,
> +i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x
> +[[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK5:@.+]] to void // CHECK: call void
> +(%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...)
> + at __kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*,
> +i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x
> +[[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK6:@.+]] to void
>  // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()  // CHECK: call {{.*}}
> [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
>  // CHECK: ret
> @@ -861,6 +886,122 @@ int main() {
>
>  // CHECK: ret void
>
> +// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias
> +[[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]***
> +dereferenceable(8) %{{.+}})
> +
> +// CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***,
> +
> +// Reduction list for runtime.
> +// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
> +
> +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}**
> +[[GTID_ADDR_ADDR:%.+]], // CHECK: [[VAR2_ORIG:%.+]] = load
> +[[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]],
> +
> +// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]], //
> +CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]**
> +%{{.+}}, i64 0 // CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % //
> +CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]],
> +[[S_FLOAT_TY]]* %{{.+}}, i64 1 // CHECK: load [[S_FLOAT_TY]]**,
> +[[S_FLOAT_TY]]*** [[VAR2_ORIG]], // CHECK: getelementptr inbounds
> +[[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 4 // CHECK: load
> +[[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % // CHECK: getelementptr inbounds
> +[[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 6 // CHECK: [[LD:%.+]] =
> +load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]], // CHECK:
> +[[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]], //
> +CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64 // CHECK:
> +[[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 // CHECK:
> +[[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]] // CHECK: [[DIF:%.+]] =
> +sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float,
> +float* null, i32 1) to i64) // CHECK: [[SIZE:%.+]] = add nuw i64
> +[[DIF]], 1 // CHECK: call i8* @llvm.stacksave() // CHECK:
> +[[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]], // CHECK:
> +[[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64 //
> +CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 //
> +CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]] //
> +CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint
> +(float* getelementptr (float, float* null, i32 1) to i64) // CHECK:
> +[[PSEUDO_VAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]],
> +[[S_FLOAT_TY]]* [[VAR2_PRIV]], i64 [[OFFSET]] // CHECK: store
> +[[S_FLOAT_TY]]** [[REF:.+]], [[S_FLOAT_TY]]*** % // CHECK: store
> +[[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]] //
> +CHECK: ret void
> +
> +// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias
> +[[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]*
> +dereferenceable(8) %{{.+}})
> +
> +// CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
> +
> +// Reduction list for runtime.
> +// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
> +
> +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}**
> +[[GTID_ADDR_ADDR:%.+]], // CHECK: [[VVAR2_ORIG:%.+]] = load [2 x
> +[[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]],
> +
> +// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2
> +x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0 // CHECK: getelementptr
> +inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]],
> +i64 0, i64 4 // CHECK: [[ORIG_START:%.+]] = bitcast [2 x
> +[[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]* // CHECK:
> +[[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64 // CHECK:
> +[[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 // CHECK:
> +[[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]] // CHECK: [[DIF:%.+]] =
> +sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float,
> +float* null, i32 1) to i64) // CHECK: [[SIZE:%.+]] = add nuw i64
> +[[DIF]], 1 // CHECK: call i8* @llvm.stacksave() // CHECK:
> +[[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]], // CHECK:
> +[[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64 //
> +CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64 //
> +CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]] //
> +CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint
> +(float* getelementptr (float, float* null, i32 1) to i64) // CHECK:
> +[[PSEUDO_VVAR2_PRIV:%.+]] = getelementptr [[S_FLOAT_TY]],
> +[[S_FLOAT_TY]]* [[VVAR2_PRIV]], i64 [[OFFSET]] // CHECK:
> +[[VVAR2_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VVAR2_PRIV]]
> to
> +[2 x [[S_FLOAT_TY]]]* // CHECK: ret void
> +
> +// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias
> +[[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]*
> +dereferenceable(8) %{{.+}})
> +
> +// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
> +
> +// Reduction list for runtime.
> +// CHECK: [[RED_LIST:%.+]] = alloca [2 x i8*],
> +
> +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}**
> +[[GTID_ADDR_ADDR:%.+]],
> +
> +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x
> +[[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], // CHECK: [[LOW:%.+]] =
> +getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]*
> +[[VAR3_ORIG]], i64 0, i64 1 // CHECK: [[VAR3_ORIG:%.+]] = load [2 x
> +[[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], //
> CHECK:
> +getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]*
> +[[VAR3_ORIG]], i64 0, i64 2 // CHECK: [[VAR3_ORIG:%.+]] = load [2 x
> +[[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], //
> CHECK:
> +[[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to
> +[[S_FLOAT_TY]]* // CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]*
> +%{{.+}} to i64 // CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]*
> +[[LOW]] to i64 // CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
> +// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float*
> +getelementptr (float, float* null, i32 1) to i64) // CHECK:
> +[[SIZE:%.+]] = add nuw i64 [[DIF]], 1 // CHECK: call i8*
> + at llvm.stacksave() // CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
> +i64 [[SIZE]], // CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]*
> +[[ORIG_START]] to i64 // CHECK: [[LOW_BOUND:%.+]] = ptrtoint
> +[[S_FLOAT_TY]]* [[LOW]] to i64 // CHECK: [[OFFSET_BYTES:%.+]] = sub i64
> +[[START]], [[LOW_BOUND]] // CHECK: [[OFFSET:%.+]] = sdiv exact i64
> +[[OFFSET_BYTES]], ptrtoint (float* getelementptr (float, float* null,
> +i32 1) to i64) // CHECK: [[PSEUDO_VAR3_PRIV:%.+]] = getelementptr
> +[[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV]], i64 [[OFFSET]] // CHECK:
> +[[VAR3_PRIV:%.+]] = bitcast [[S_FLOAT_TY]]* [[PSEUDO_VAR3_PRIV]] to [2
> +x [[S_FLOAT_TY]]]*
> +
> +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x
> +[[S_FLOAT_TY]]]** %
> +
> +// CHECK: ret void
> +
> +// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias
> +[[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]*
> +dereferenceable(8) %{{.+}})
> +
> +// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*, //
> +CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
> +
> +// Reduction list for runtime.
> +// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
> +
> +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}**
> +[[GTID_ADDR_ADDR:%.+]],
> +
> +// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x
> +[[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]], // CHECK: bitcast [2 x
> +[[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]* // CHECK:
> +getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]*
> +[[VAR3_PRIV]], i32 0, i32 0 // CHECK: getelementptr [[S_FLOAT_TY]],
> +[[S_FLOAT_TY]]* %{{.+}}, i64 2
> +
> +// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x
> +[[S_FLOAT_TY]]]** %
> +
> +// CHECK: ret void
> +
>  // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()  // CHECK: [[TEST:%.+]] 
> =
> alloca [[S_INT_TY]],  // CHECK: call {{.*}}
> [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
>
> Modified: cfe/trunk/test/OpenMP/task_codegen.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/cfe/trunk/test/OpenMP/task_codegen.cpp?rev=259776&r1=259775
> &r2=259776&view=diff
> ==========================================================
> ====================
> --- cfe/trunk/test/OpenMP/task_codegen.cpp (original)
> +++ cfe/trunk/test/OpenMP/task_codegen.cpp Thu Feb  4 05:27:03 2016
> @@ -120,15 +120,15 @@ int main() {
>  // CHECK: store i64 4, i64*
>  // CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]],
> [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2  // CHECK: store i8 3, i8*
> +// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]] // CHECK: [[IDX2:%.+]] =
> +sext i8 [[B_VAL]] to i64
>  // CHECK: [[IDX1:%.+]] = mul nsw i64 4, [[A_VAL]]  // CHECK: [[START:%.+]] 
> =
> getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
> +// CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]],
> +i64 [[IDX2]]
>  // CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]]  // CHECK: [[IDX2:%.+]] = sext 
> i8
> [[B_VAL]] to i64 -// CHECK: [[START1:%.+]] = getelementptr inbounds i32,
> i32* [[START]], i64 [[IDX2]]  // CHECK: [[IDX1:%.+]] = mul nsw i64 9, 
> [[A_VAL]]
> // CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64
> [[IDX1]] -// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]] -// CHECK: 
> [[IDX2:%.+]] =
> sext i8 [[B_VAL]] to i64  // CHECK: [[END1:%.+]] = getelementptr inbounds
> i32, i32* [[END]], i64 [[IDX2]]  // CHECK: [[END2:%.+]] = getelementptr i32,
> i32* [[END1]], i32 1  // CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START1]] 
> to
> i64 @@ -173,12 +173,12 @@ int main() {  // CHECK: [[START1:%.+]] =
> getelementptr inbounds i32, i32* [[START]], i64 3  // CHECK:
> [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}},  // CHECK:
> [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64
> +// CHECK: [[IDX2:%.+]] = sub nsw i64 [[NEW_A_VAL_I64]], 1 // CHECK:
> +[[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}}, // CHECK:
> +[[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64
>  // CHECK: [[SUB:%.+]] = add nsw i64 -1, [[NEW_A_VAL_I64]]  // CHECK:
> [[IDX1:%.+]] = mul nsw i64 [[SUB]], [[A_VAL]]  // CHECK: [[END:%.+]] =
> getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]] -// CHECK:
> [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}}, -// CHECK:
> [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64 -// CHECK:
> [[IDX2:%.+]] = sub nsw i64 [[NEW_A_VAL_I64]], 1  // CHECK: [[END1:%.+]] =
> getelementptr inbounds i32, i32* [[END]], i64 [[IDX2]]  // CHECK:
> [[END2:%.+]] = getelementptr i32, i32* [[END1]], i32 1  // CHECK:
> [[START_INT:%.+]] = ptrtoint i32* [[START1]] to i64
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5868 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160317/699e3a64/attachment-0001.bin>


More information about the cfe-commits mailing list