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-boun...@lists.llvm.org] On Behalf >> Of Alexey Bataev via cfe-commits >> Sent: Thursday, February 04, 2016 12:27 PM >> To: cfe-commits@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]+}}*, ...)*, ...) >> +@__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]+}}*, ...)*, ...) >> +@__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]+}}*, ...)*, ...) >> +@__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* >> +@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@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits