summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2014-08-19 17:17:40 +0000
committerFariborz Jahanian <fjahanian@apple.com>2014-08-19 17:17:40 +0000
commit91b2fa2a9a2ae436a84216af81bc62699a2bcfa4 (patch)
treee7f3cad8a0de569fdb93ab1d23f3548a2eb182cc /clang/lib/CodeGen/CGExpr.cpp
parent6a128331a6f63c880b5edd15a802c739f7596d99 (diff)
downloadbcm5719-llvm-91b2fa2a9a2ae436a84216af81bc62699a2bcfa4.tar.gz
bcm5719-llvm-91b2fa2a9a2ae436a84216af81bc62699a2bcfa4.zip
ext_vector IRGen. Patch to allow indexing into
ext_vector_type's 'hi/lo' components when used as lvalue. rdar://18031917 pr20697 llvm-svn: 215991
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp38
1 files changed, 35 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c83cc0ad970..d632aba414c 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1361,6 +1361,28 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) {
return RValue::get(Vec);
}
+/// @brief Generates lvalue for partial ext_vector access.
+llvm::Value *CodeGenFunction::EmitExtVectorElementLValue(LValue LV) {
+ llvm::Value *VectorAddress = LV.getExtVectorAddr();
+ const VectorType *ExprVT = LV.getType()->getAs<VectorType>();
+ QualType EQT = ExprVT->getElementType();
+ llvm::Type *VectorElementTy = CGM.getTypes().ConvertType(EQT);
+ llvm::Type *VectorElementPtrToTy = VectorElementTy->getPointerTo();
+
+ llvm::Value *CastToPointerElement =
+ Builder.CreateBitCast(VectorAddress,
+ VectorElementPtrToTy, "conv.ptr.element");
+
+ const llvm::Constant *Elts = LV.getExtVectorElts();
+ unsigned ix = getAccessedFieldNo(0, Elts);
+
+ llvm::Value *VectorBasePtrPlusIx =
+ Builder.CreateInBoundsGEP(CastToPointerElement,
+ llvm::ConstantInt::get(SizeTy, ix), "add.ptr");
+
+ return VectorBasePtrPlusIx;
+}
+
/// @brief Load of global gamed gegisters are always calls to intrinsics.
RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {
assert((LV.getType()->isIntegerType() || LV.getType()->isPointerType()) &&
@@ -2323,7 +2345,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
// If the base is a vector type, then we are forming a vector element lvalue
// with this subscript.
- if (E->getBase()->getType()->isVectorType()) {
+ if (E->getBase()->getType()->isVectorType() &&
+ !isa<ExtVectorElementExpr>(E->getBase())) {
// Emit the vector as an lvalue to get its address.
LValue LHS = EmitLValue(E->getBase());
assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
@@ -2339,8 +2362,17 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
// size is a VLA or Objective-C interface.
llvm::Value *Address = nullptr;
CharUnits ArrayAlignment;
- if (const VariableArrayType *vla =
- getContext().getAsVariableArrayType(E->getType())) {
+ if (isa<ExtVectorElementExpr>(E->getBase())) {
+ LValue LV = EmitLValue(E->getBase());
+ Address = EmitExtVectorElementLValue(LV);
+ Address = Builder.CreateInBoundsGEP(Address, Idx, "arrayidx");
+ const VectorType *ExprVT = LV.getType()->getAs<VectorType>();
+ QualType EQT = ExprVT->getElementType();
+ return MakeAddrLValue(Address, EQT,
+ getContext().getTypeAlignInChars(EQT));
+ }
+ else if (const VariableArrayType *vla =
+ getContext().getAsVariableArrayType(E->getType())) {
// 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.
OpenPOWER on IntegriCloud