[cfe-commits] r62458 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/Sema.cpp test/CodeGen/ext-vector-shuffle.c
Nate Begeman
natebegeman at mac.com
Sat Jan 17 22:42:52 PST 2009
Author: sampo
Date: Sun Jan 18 00:42:49 2009
New Revision: 62458
URL: http://llvm.org/viewvc/llvm-project?rev=62458&view=rev
Log:
Vector codegen improvements
Added:
cfe/trunk/test/CodeGen/ext-vector-shuffle.c
Modified:
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/Sema/Sema.cpp
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=62458&r1=62457&r2=62458&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sun Jan 18 00:42:49 2009
@@ -20,6 +20,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Bitcode/Serialize.h"
#include "llvm/Bitcode/Deserialize.h"
+#include "llvm/Support/MathExtras.h"
using namespace clang;
@@ -284,8 +285,11 @@
std::pair<uint64_t, unsigned> EltInfo =
getTypeInfo(cast<VectorType>(T)->getElementType());
Width = EltInfo.first*cast<VectorType>(T)->getNumElements();
- // FIXME: This isn't right for unusual vectors
Align = Width;
+ // If the alignment is not a power of 2, round up to the next power of 2.
+ // This happens for non-power-of-2 length vectors.
+ // FIXME: this should probably be a target property.
+ Align = 1 << llvm::Log2_32_Ceil(Align);
break;
}
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=62458&r1=62457&r2=62458&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Sun Jan 18 00:42:49 2009
@@ -631,6 +631,8 @@
case X86::BI__builtin_ia32_vec_ext_v2di:
case X86::BI__builtin_ia32_vec_ext_v4sf:
case X86::BI__builtin_ia32_vec_ext_v4si:
+ case X86::BI__builtin_ia32_vec_ext_v8hi:
+ case X86::BI__builtin_ia32_vec_ext_v4hi:
case X86::BI__builtin_ia32_vec_ext_v2df:
return Builder.CreateExtractElement(Ops[0], Ops[1], "result");
case X86::BI__builtin_ia32_cmpordss:
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=62458&r1=62457&r2=62458&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Jan 18 00:42:49 2009
@@ -309,8 +309,8 @@
return EmitObjCPropertyGet(LV.getKVCRefExpr());
}
-// 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 this is a reference to a subset of the elements of a vector, create an
+// appropriate shufflevector.
RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
QualType ExprType) {
llvm::Value *Vec = Builder.CreateLoad(LV.getExtVectorAddr(),
@@ -326,41 +326,21 @@
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
}
-
- // If the source and destination have the same number of elements, use a
- // vector shuffle instead of insert/extracts.
+
+ // Always use shuffle vector to try to retain the original program structure
unsigned NumResultElts = ExprVT->getNumElements();
- unsigned NumSourceElts =
- cast<llvm::VectorType>(Vec->getType())->getNumElements();
-
- if (NumResultElts == NumSourceElts) {
- llvm::SmallVector<llvm::Constant*, 4> Mask;
- for (unsigned i = 0; i != NumResultElts; ++i) {
- unsigned InIdx = getAccessedFieldNo(i, Elts);
- Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
- }
-
- llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
- Vec = Builder.CreateShuffleVector(Vec,
- llvm::UndefValue::get(Vec->getType()),
- MaskV, "tmp");
- return RValue::get(Vec);
- }
-
- // Start out with an undef of the result type.
- llvm::Value *Result = llvm::UndefValue::get(ConvertType(ExprType));
- // Extract/Insert each element of the result.
+ llvm::SmallVector<llvm::Constant*, 4> Mask;
for (unsigned i = 0; i != NumResultElts; ++i) {
unsigned InIdx = getAccessedFieldNo(i, Elts);
- 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");
+ Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
}
- return RValue::get(Result);
+ llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
+ Vec = Builder.CreateShuffleVector(Vec,
+ llvm::UndefValue::get(Vec->getType()),
+ MaskV, "tmp");
+ return RValue::get(Vec);
}
@@ -548,15 +528,54 @@
if (const VectorType *VTy = Ty->getAsVectorType()) {
unsigned NumSrcElts = VTy->getNumElements();
-
- // Extract/Insert each element.
- for (unsigned i = 0; i != NumSrcElts; ++i) {
- llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- Elt = Builder.CreateExtractElement(SrcVal, Elt, "tmp");
-
- unsigned Idx = getAccessedFieldNo(i, Elts);
- llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Idx);
- Vec = Builder.CreateInsertElement(Vec, Elt, OutIdx, "tmp");
+ unsigned NumDstElts =
+ cast<llvm::VectorType>(Vec->getType())->getNumElements();
+ if (NumDstElts == NumSrcElts) {
+ // Use shuffle vector is the src and destination are the same number
+ // of elements
+ llvm::SmallVector<llvm::Constant*, 4> Mask;
+ for (unsigned i = 0; i != NumSrcElts; ++i) {
+ unsigned InIdx = getAccessedFieldNo(i, Elts);
+ Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
+ }
+
+ llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
+ Vec = Builder.CreateShuffleVector(SrcVal,
+ llvm::UndefValue::get(Vec->getType()),
+ MaskV, "tmp");
+ }
+ else if (NumDstElts > NumSrcElts) {
+ // Extended the source vector to the same length and then shuffle it
+ // into the destination.
+ // FIXME: since we're shuffling with undef, can we just use the indices
+ // into that? This could be simpler.
+ llvm::SmallVector<llvm::Constant*, 4> ExtMask;
+ unsigned i;
+ for (i = 0; i != NumSrcElts; ++i)
+ ExtMask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, i));
+ for (; i != NumDstElts; ++i)
+ ExtMask.push_back(llvm::UndefValue::get(llvm::Type::Int32Ty));
+ llvm::Value *ExtMaskV = llvm::ConstantVector::get(&ExtMask[0],
+ ExtMask.size());
+ llvm::Value *ExtSrcVal = Builder.CreateShuffleVector(SrcVal,
+ llvm::UndefValue::get(SrcVal->getType()),
+ ExtMaskV, "tmp");
+ // build identity
+ llvm::SmallVector<llvm::Constant*, 4> Mask;
+ for (unsigned i = 0; i != NumDstElts; ++i) {
+ Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, i));
+ }
+ // modify when what gets shuffled in
+ for (unsigned i = 0; i != NumSrcElts; ++i) {
+ unsigned Idx = getAccessedFieldNo(i, Elts);
+ Mask[Idx] =llvm::ConstantInt::get(llvm::Type::Int32Ty, i+NumDstElts);
+ }
+ llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
+ Vec = Builder.CreateShuffleVector(Vec, ExtSrcVal, MaskV, "tmp");
+ }
+ else {
+ // We should never shorten the vector
+ assert(0 && "unexpected shorten vector length");
}
} else {
// If the Src is a scalar (not a vector) it must be updating one element.
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=62458&r1=62457&r2=62458&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sun Jan 18 00:42:49 2009
@@ -409,10 +409,26 @@
}
// A scalar can be splatted to an extended vector of the same element type
- if (DstType->isExtVectorType() && !isa<VectorType>(SrcType) &&
- cast<llvm::VectorType>(DstTy)->getElementType() == Src->getType())
- return CGF.EmitVector(&Src, DstType->getAsVectorType()->getNumElements(),
- true);
+ if (DstType->isExtVectorType() && !isa<VectorType>(SrcType)) {
+ // Cast the scalar to element type
+ QualType EltTy = DstType->getAsExtVectorType()->getElementType();
+ llvm::Value *Elt = EmitScalarConversion(Src, SrcType, EltTy);
+
+ // Insert the element in element zero of an undef vector
+ llvm::Value *UnV = llvm::UndefValue::get(DstTy);
+ llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
+ UnV = Builder.CreateInsertElement(UnV, Elt, Idx, "tmp");
+
+ // Splat the element across to all elements
+ llvm::SmallVector<llvm::Constant*, 16> Args;
+ unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
+ for (unsigned i = 0; i < NumElements; i++)
+ Args.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0));
+
+ llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], NumElements);
+ llvm::Value *Yay = Builder.CreateShuffleVector(UnV, UnV, Mask, "splat");
+ return Yay;
+ }
// Allow bitcast from vector to integer/fp of the same size.
if (isa<llvm::VectorType>(Src->getType()) ||
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=62458&r1=62457&r2=62458&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Sun Jan 18 00:42:49 2009
@@ -151,7 +151,7 @@
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// If there is already an implicit cast, merge into the existing one.
- /// If isLvalue, the result of the cast is an lvalue.
+/// If isLvalue, the result of the cast is an lvalue.
void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty, bool isLvalue) {
QualType ExprTy = Context.getCanonicalType(Expr->getType());
QualType TypeTy = Context.getCanonicalType(Ty);
Added: cfe/trunk/test/CodeGen/ext-vector-shuffle.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ext-vector-shuffle.c?rev=62458&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/ext-vector-shuffle.c (added)
+++ cfe/trunk/test/CodeGen/ext-vector-shuffle.c Sun Jan 18 00:42:49 2009
@@ -0,0 +1,15 @@
+// RUN: clang %s -emit-llvm -o - | not grep 'extractelement'
+// RUN: clang %s -emit-llvm -o - | not grep 'insertelement'
+// RUN: clang %s -emit-llvm -o - | grep 'shufflevector'
+
+typedef __attribute__(( ext_vector_type(2) )) float float2;
+typedef __attribute__(( ext_vector_type(4) )) float float4;
+
+float2 test1(float4 V) {
+ return V.xy + V.wz;
+}
+
+float4 test2(float4 V) {
+ float2 W = V.ww;
+ return W.xyxy + W.yxyx;
+}
More information about the cfe-commits
mailing list