Implementation of __builtin_shufflevector, a portable builtin capable of
expressing the full flexibility of the LLVM shufflevector instruction.
The expected immediate usage is in *mmintrin.h, so that they don't
depend on the mess of gcc-inherited (and not completely implemented)
shuffle builtins.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51113 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 4fb69d0..bdd7975 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -127,6 +127,7 @@
Value *VisitObjCMessageExpr(ObjCMessageExpr *E);
Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { return EmitLoadOfLValue(E);}
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
+ Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
Value *VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); }
Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { return EmitLoadOfLValue(E); }
@@ -449,6 +450,17 @@
return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
}
+Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
+ llvm::SmallVector<llvm::Constant*, 32> indices;
+ for (unsigned i = 2; i < E->getNumSubExprs(); i++) {
+ indices.push_back(cast<llvm::Constant>(CGF.EmitScalarExpr(E->getExpr(i))));
+ }
+ Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
+ Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
+ Value* SV = llvm::ConstantVector::get(indices.begin(), indices.size());
+ return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
+}
+
Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
// Only the lookup mechanism and first two arguments of the method
// implementation vary between runtimes. We can get the receiver and