[cfe-commits] r92056 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp test/CodeGen/ext-vector.c
Chris Lattner
sabre at nondot.org
Wed Dec 23 13:31:11 PST 2009
Author: lattner
Date: Wed Dec 23 15:31:11 2009
New Revision: 92056
URL: http://llvm.org/viewvc/llvm-project?rev=92056&view=rev
Log:
fix opencl extvector element extraction on rvalues. We previously
error_unsupported on test10 and crashed on test11.
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/test/CodeGen/ext-vector.c
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=92056&r1=92055&r2=92056&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Dec 23 15:31:11 2009
@@ -1179,7 +1179,7 @@
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 @@
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 @@
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));
Modified: cfe/trunk/test/CodeGen/ext-vector.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ext-vector.c?rev=92056&r1=92055&r2=92056&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ext-vector.c (original)
+++ cfe/trunk/test/CodeGen/ext-vector.c Wed Dec 23 15:31:11 2009
@@ -138,3 +138,16 @@
cmp = a == b;
cmp = a != b;
}
+
+int test9(int4 V) {
+ return V.xy.x;
+}
+
+int test10(foo_t V) {
+ return (V+V).x;
+}
+
+int4 test11a();
+int test11() {
+ return test11a().x;
+}
More information about the cfe-commits
mailing list