[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