r259776 - [OPENMP 4.0] Fixed support of array sections/array subscripts.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 17 04:22:21 PDT 2016
Yes, of course
Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team
17.03.2016 14:18, Hahnfeld, Jonas пишет:
> 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
More information about the cfe-commits
mailing list