diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-12-23 21:31:11 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-12-23 21:31:11 +0000 |
| commit | 4e1a323b85d5b0807e715ff3c2dd3c6e434975e8 (patch) | |
| tree | bc4592f72bc94e8ef1556e7aec188da530354743 /clang/lib/CodeGen | |
| parent | 43c8be526dd5459527345c4fd1e77b8faa85a02e (diff) | |
| download | bcm5719-llvm-4e1a323b85d5b0807e715ff3c2dd3c6e434975e8.tar.gz bcm5719-llvm-4e1a323b85d5b0807e715ff3c2dd3c6e434975e8.zip | |
fix opencl extvector element extraction on rvalues. We previously
error_unsupported on test10 and crashed on test11.
llvm-svn: 92056
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 64fbfbcb56c..6b54d969f8e 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1179,7 +1179,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { static llvm::Constant *GenerateConstantVector(llvm::LLVMContext &VMContext, llvm::SmallVector<unsigned, 4> &Elts) { - llvm::SmallVector<llvm::Constant *, 4> CElts; + llvm::SmallVector<llvm::Constant*, 4> CElts; for (unsigned i = 0, e = Elts.size(); i != e; ++i) CElts.push_back(llvm::ConstantInt::get( @@ -1190,21 +1190,44 @@ llvm::Constant *GenerateConstantVector(llvm::LLVMContext &VMContext, LValue CodeGenFunction:: EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { + const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext); + // Emit the base vector as an l-value. LValue Base; // ExtVectorElementExpr's base can either be a vector or pointer to vector. - if (!E->isArrow()) { - assert(E->getBase()->getType()->isVectorType()); - Base = EmitLValue(E->getBase()); - } else { - const PointerType *PT = E->getBase()->getType()->getAs<PointerType>(); + if (E->isArrow()) { + // If it is a pointer to a vector, emit the address and form an lvalue with + // it. llvm::Value *Ptr = EmitScalarExpr(E->getBase()); + const PointerType *PT = E->getBase()->getType()->getAs<PointerType>(); Qualifiers Quals = MakeQualifiers(PT->getPointeeType()); Quals.removeObjCGCAttr(); Base = LValue::MakeAddr(Ptr, Quals); + } else if (E->getBase()->isLvalue(getContext()) == Expr::LV_Valid) { + // Otherwise, if the base is an lvalue ( as in the case of foo.x.x), + // emit the base as an lvalue. + assert(E->getBase()->getType()->isVectorType()); + Base = EmitLValue(E->getBase()); + } else { + // Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such. + const VectorType *VT = E->getBase()->getType()->getAs<VectorType>(); + assert(VT && "Result must be a vector"); + llvm::Value *Vec = EmitScalarExpr(E->getBase()); + + // Store the vector to memory (because LValue wants an address) and use an + // index list of 0,1,2,3 which is the full vector. + llvm::Value *VecMem =CreateTempAlloca(ConvertType(E->getBase()->getType())); + Builder.CreateStore(Vec, VecMem); + + llvm::SmallVector<llvm::Constant *, 4> CElts; + for (unsigned i = 0, e = VT->getNumElements(); i != e; ++i) + CElts.push_back(llvm::ConstantInt::get(Int32Ty, i)); + + llvm::Constant *Elts = llvm::ConstantVector::get(&CElts[0], CElts.size()); + Base = LValue::MakeExtVectorElt(VecMem, Elts, 0); } - + // Encode the element access list into a vector of unsigned indices. llvm::SmallVector<unsigned, 4> Indices; E->getEncodedElementAccess(Indices); @@ -1219,7 +1242,6 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { llvm::Constant *BaseElts = Base.getExtVectorElts(); llvm::SmallVector<llvm::Constant *, 4> CElts; - const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext); for (unsigned i = 0, e = Indices.size(); i != e; ++i) { if (isa<llvm::ConstantAggregateZero>(BaseElts)) CElts.push_back(llvm::ConstantInt::get(Int32Ty, 0)); |

