implement lvalue to rvalue conversion for ocuvector components. We can now compile stuff
like this:
typedef __attribute__(( ocu_vector_type(4) )) float float4;
float4 test1(float4 V) {
return V.wzyx+V;
}
to:
_test1:
pshufd $27, %xmm0, %xmm1
addps %xmm0, %xmm1
movaps %xmm1, %xmm0
ret
and:
_test1:
mfspr r2, 256
oris r3, r2, 4096
mtspr 256, r3
li r3, lo16(LCPI1_0)
lis r4, ha16(LCPI1_0)
lvx v3, r4, r3
vperm v3, v2, v2, v3
vaddfp v2, v3, v2
mtspr 256, r2
blr
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40771 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp
index 1a841f9..7d8dc8c 100644
--- a/CodeGen/CGExpr.cpp
+++ b/CodeGen/CGExpr.cpp
@@ -282,6 +282,30 @@
return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(),
"vecext"));
}
+
+ // If this is a reference to a subset of the elements of a vector, either
+ // shuffle the input or extract/insert them as appropriate.
+ if (LV.isOCUVectorComp()) {
+ llvm::Value *Vec = Builder.CreateLoad(LV.getOCUVectorAddr(), "tmp");
+ unsigned NumElts = cast<VectorType>(ExprType)->getNumElements();
+
+ // Start out with an undef of the result type.
+ llvm::Value *Result = llvm::UndefValue::get(ConvertType(ExprType));
+
+ unsigned EncFields = LV.getOCUVectorComp();
+
+ // Extract/Insert each element of the result.
+ for (unsigned i = 0; i != NumElts; ++i) {
+ unsigned InIdx = OCUVectorComponent::getAccessedFieldNo(i, EncFields);
+ llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
+ Elt = Builder.CreateExtractElement(Vec, Elt, "tmp");
+
+ llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
+ Result = Builder.CreateInsertElement(Result, Elt, OutIdx, "tmp");
+ }
+
+ return RValue::get(Result);
+ }
assert(0 && "Bitfield ref not impl!");
}
@@ -505,6 +529,8 @@
return EmitLoadOfLValue(E);
case Expr::ArraySubscriptExprClass:
return EmitArraySubscriptExprRV(cast<ArraySubscriptExpr>(E));
+ case Expr::OCUVectorComponentClass:
+ return EmitLoadOfLValue(E);
case Expr::PreDefinedExprClass:
case Expr::StringLiteralClass:
return RValue::get(EmitLValue(E).getAddress());