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=259775&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&view=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=259776&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=259775&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=259775&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=259776&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&r1=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