r187694 - Add support for passing -1 to __builtin_shufflevector to signify an undefined element value to match IR capabilities.

Craig Topper craig.topper at gmail.com
Sat Aug 3 10:40:39 PDT 2013


Author: ctopper
Date: Sat Aug  3 12:40:38 2013
New Revision: 187694

URL: http://llvm.org/viewvc/llvm-project?rev=187694&view=rev
Log:
Add support for passing -1 to __builtin_shufflevector to signify an undefined element value to match IR capabilities.

Modified:
    cfe/trunk/docs/LanguageExtensions.rst
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/CodeGen/builtinshufflevector2.c

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=187694&r1=187693&r2=187694&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Sat Aug  3 12:40:38 2013
@@ -1455,8 +1455,8 @@ for the implementation of various target
 
 .. code-block:: c++
 
-  // Identity operation - return 4-element vector V1.
-  __builtin_shufflevector(V1, V1, 0, 1, 2, 3)
+  // identity operation - return 4-element vector v1.
+  __builtin_shufflevector(v1, v1, 0, 1, 2, 3)
 
   // "Splat" element 0 of V1 into a 4-element result.
   __builtin_shufflevector(V1, V1, 0, 0, 0, 0)
@@ -1470,6 +1470,9 @@ for the implementation of various target
   // Concatenate every other element of 8-element vectors V1 and V2.
   __builtin_shufflevector(V1, V2, 0, 2, 4, 6, 8, 10, 12, 14)
 
+  // Shuffle v1 with some elements being undefined
+  __builtin_shufflevector(v1, v1, 3, -1, 1, -1)
+
 **Description**:
 
 The first two arguments to ``__builtin_shufflevector`` are vectors that have
@@ -1478,7 +1481,8 @@ specify the elements indices of the firs
 and returned in a new vector.  These element indices are numbered sequentially
 starting with the first vector, continuing into the second vector.  Thus, if
 ``vec1`` is a 4-element vector, index 5 would refer to the second element of
-``vec2``.
+``vec2``. An index of -1 can be used to indicate that the corresponding element
+in the returned vector is a don't care and can be optimized by the backend.
 
 The result of ``__builtin_shufflevector`` is a vector with the same element
 type as ``vec1``/``vec2`` but that has an element count equal to the number of

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=187694&r1=187693&r2=187694&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Aug  3 12:40:38 2013
@@ -3451,9 +3451,9 @@ public:
 
   void setExprs(ASTContext &C, ArrayRef<Expr *> Exprs);
 
-  unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) const {
+  llvm::APSInt getShuffleMaskIdx(ASTContext &Ctx, unsigned N) const {
     assert((N < NumExprs - 2) && "Shuffle idx out of range!");
-    return getExpr(N+2)->EvaluateKnownConstInt(Ctx).getZExtValue();
+    return getExpr(N+2)->EvaluateKnownConstInt(Ctx);
   }
 
   // Iterators

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=187694&r1=187693&r2=187694&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sat Aug  3 12:40:38 2013
@@ -955,8 +955,12 @@ Value *ScalarExprEmitter::VisitShuffleVe
 
   SmallVector<llvm::Constant*, 32> indices;
   for (unsigned i = 2; i < E->getNumSubExprs(); ++i) {
-    unsigned Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2);
-    indices.push_back(Builder.getInt32(Idx));
+    llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2);
+    // Check for -1 and output it as undef in the IR.
+    if (Idx.isSigned() && Idx.isAllOnesValue())
+      indices.push_back(llvm::UndefValue::get(CGF.Int32Ty));
+    else
+      indices.push_back(Builder.getInt32(Idx.getZExtValue()));
   }
 
   Value *SV = llvm::ConstantVector::get(indices);

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=187694&r1=187693&r2=187694&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Sat Aug  3 12:40:38 2013
@@ -1786,6 +1786,10 @@ ExprResult Sema::SemaBuiltinShuffleVecto
                             diag::err_shufflevector_nonconstant_argument)
                        << TheCall->getArg(i)->getSourceRange());
 
+    // Allow -1 which will be translated to undef in the IR.
+    if (Result.isSigned() && Result.isAllOnesValue())
+      continue;
+
     if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2)
       return ExprError(Diag(TheCall->getLocStart(),
                             diag::err_shufflevector_argument_too_large)

Modified: cfe/trunk/test/CodeGen/builtinshufflevector2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtinshufflevector2.c?rev=187694&r1=187693&r2=187694&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/builtinshufflevector2.c (original)
+++ cfe/trunk/test/CodeGen/builtinshufflevector2.c Sat Aug  3 12:40:38 2013
@@ -28,8 +28,15 @@ void clang_shufflevector_v_v( float4* A,
 }
 
 // CHECK: define void @clang_shufflevector_v_v_c(
-void clang_shufflevector_v_v_c( float4* A, float4 x, float4 y, uint4 mask ) {
+void clang_shufflevector_v_v_c( float4* A, float4 x, float4 y) {
 // CHECK: [[V:%.*]] = shufflevector <4 x float> {{%.*}}, <4 x float> {{%.*}}, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
 // CHECK: store <4 x float> [[V]], <4 x float>* {{%.*}}
   *A = __builtin_shufflevector( x, y, 0, 4, 1, 5 );
 }
+
+// CHECK: define void @clang_shufflevector_v_v_undef(
+void clang_shufflevector_v_v_undef( float4* A, float4 x, float4 y) {
+// CHECK: [[V:%.*]] = shufflevector <4 x float> {{%.*}}, <4 x float> {{%.*}}, <4 x i32> <i32 0, i32 4, i32 undef, i32 5>
+// CHECK: store <4 x float> [[V]], <4 x float>* {{%.*}}
+  *A = __builtin_shufflevector( x, y, 0, 4, -1, 5 );
+}





More information about the cfe-commits mailing list