[llvm-commits] [dragonegg] r131122 - in /dragonegg/trunk: include/dragonegg/Internals.h src/Convert.cpp
Duncan Sands
baldrick at free.fr
Tue May 10 04:27:06 PDT 2011
Author: baldrick
Date: Tue May 10 06:27:05 2011
New Revision: 131122
URL: http://llvm.org/viewvc/llvm-project?rev=131122&view=rev
Log:
Add support for VEC_PACK_TRUNC_EXPR, which may be produced by GCC's tree
vectorizer when GCC optimizations are enabled. The resulting code is gross
though due to the type legalizer scalarizing the floating conversion from
<2 x double> to <2 x float>. This fixes PR9726.
Modified:
dragonegg/trunk/include/dragonegg/Internals.h
dragonegg/trunk/src/Convert.cpp
Modified: dragonegg/trunk/include/dragonegg/Internals.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Internals.h?rev=131122&r1=131121&r2=131122&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Internals.h (original)
+++ dragonegg/trunk/include/dragonegg/Internals.h Tue May 10 06:27:05 2011
@@ -721,6 +721,8 @@
Value *EmitReg_VEC_EXTRACT_ODD_EXPR(tree_node *op0, tree_node *op1);
Value *EmitReg_VEC_INTERLEAVE_HIGH_EXPR(tree_node *op0, tree_node *op1);
Value *EmitReg_VEC_INTERLEAVE_LOW_EXPR(tree_node *op0, tree_node *op1);
+ Value *EmitReg_VEC_PACK_TRUNC_EXPR(tree_node *type, tree_node *op0,
+ tree_node *op1);
Value *EmitLoadOfLValue(tree_node *exp);
Value *EmitOBJ_TYPE_REF(tree_node *exp);
Modified: dragonegg/trunk/src/Convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=131122&r1=131121&r2=131122&view=diff
==============================================================================
--- dragonegg/trunk/src/Convert.cpp (original)
+++ dragonegg/trunk/src/Convert.cpp Tue May 10 06:27:05 2011
@@ -6994,6 +6994,32 @@
return Builder.CreateShuffleVector(LHS, RHS, ConstantVector::get(Mask));
}
+Value *TreeToLLVM::EmitReg_VEC_PACK_TRUNC_EXPR(tree type, tree op0, tree op1) {
+ // Eg: <4 x float> = VEC_PACK_TRUNC_EXPR(<2 x double>, <2 x double>).
+ Value *LHS = EmitRegister(op0);
+ Value *RHS = EmitRegister(op1);
+
+ // Truncate the input elements to the output element type, eg: <2 x double>
+ // -> <2 x float>.
+ unsigned Length = TYPE_VECTOR_SUBPARTS(TREE_TYPE(op0));
+ const Type *TruncTy = VectorType::get(getRegType(TREE_TYPE(type)), Length);
+ if (FLOAT_TYPE_P(TREE_TYPE(type))) {
+ LHS = Builder.CreateFPTrunc(LHS, TruncTy);
+ RHS = Builder.CreateFPTrunc(RHS, TruncTy);
+ } else {
+ LHS = Builder.CreateTrunc(LHS, TruncTy);
+ RHS = Builder.CreateTrunc(RHS, TruncTy);
+ }
+
+ // Concatenate the truncated inputs into one vector of twice the length,
+ // eg: <2 x float>, <2 x float> -> <4 x float>.
+ SmallVector<Constant*, 16> Mask;
+ Mask.reserve(2*Length);
+ for (unsigned i = 0, e = 2*Length; i != e; ++i)
+ Mask.push_back(ConstantInt::get(Type::getInt32Ty(Context), i));
+ return Builder.CreateShuffleVector(LHS, RHS, ConstantVector::get(Mask));
+}
+
//===----------------------------------------------------------------------===//
// ... Exception Handling ...
@@ -7959,6 +7985,8 @@
RHS = EmitReg_VEC_INTERLEAVE_HIGH_EXPR(rhs1, rhs2); break;
case VEC_INTERLEAVE_LOW_EXPR:
RHS = EmitReg_VEC_INTERLEAVE_LOW_EXPR(rhs1, rhs2); break;
+ case VEC_PACK_TRUNC_EXPR:
+ RHS = EmitReg_VEC_PACK_TRUNC_EXPR(type, rhs1, rhs2); break;
}
assert(RHS->getType() == getRegType(type) && "RHS has wrong type!");
More information about the llvm-commits
mailing list