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
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits