зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
349aaec106
Коммит
46ea8eb7cc
|
@ -282,6 +282,30 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
|
|||
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 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) {
|
|||
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());
|
||||
|
|
|
@ -141,6 +141,7 @@ public:
|
|||
llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
|
||||
llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
|
||||
// ocu vector components.
|
||||
llvm::Value *getOCUVectorAddr() const { assert(isOCUVectorComp()); return V; }
|
||||
unsigned getOCUVectorComp() const {
|
||||
assert(isOCUVectorComp());
|
||||
return VectorComp;
|
||||
|
@ -164,7 +165,7 @@ public:
|
|||
|
||||
static LValue MakeOCUVectorComp(llvm::Value *Vec, unsigned Components) {
|
||||
LValue R;
|
||||
R.LVType = VectorElt;
|
||||
R.LVType = OCUVectorComp;
|
||||
R.V = Vec;
|
||||
R.VectorComp = Components;
|
||||
return R;
|
||||
|
|
Загрузка…
Ссылка в новой задаче