r259776 - [OPENMP 4.0] Fixed support of array sections/array subscripts.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 4 03:27:05 PST 2016
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
More information about the cfe-commits
mailing list