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