[cfe-commits] r145981 - in /cfe/trunk: lib/AST/Expr.cpp lib/AST/ExprConstant.cpp test/CodeGen/altivec.c

Richard Smith richard-llvm at metafoo.co.uk
Tue Dec 6 14:44:34 PST 2011


Author: rsmith
Date: Tue Dec  6 16:44:34 2011
New Revision: 145981

URL: http://llvm.org/viewvc/llvm-project?rev=145981&view=rev
Log:
Move vector bitcast handling in constant expressions from the expression
evaluator into constant initializer handling / IRGen. The practical consequence
of this is that the bitcast now lives in the constant's definition, rather than
in its uses.

The code in the constant expression evaluator was producing vectors of the wrong
type and size (and possibly of the wrong value for a big-endian int-to-vector
bitcast). We were getting away with this only because we don't yet support
constant-folding of any expressions which inspect vector values.

Modified:
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/test/CodeGen/altivec.c

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=145981&r1=145980&r2=145981&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Dec  6 16:44:34 2011
@@ -2541,23 +2541,27 @@
   case CXXFunctionalCastExprClass:
   case CXXStaticCastExprClass:
   case ImplicitCastExprClass:
-  case CStyleCastExprClass:
+  case CStyleCastExprClass: {
+    const CastExpr *CE = cast<CastExpr>(this);
+
+    // Handle bitcasts of vector constants.
+    if (getType()->isVectorType() && CE->getCastKind() == CK_BitCast)
+      return CE->getSubExpr()->isConstantInitializer(Ctx, false);
+
     // Handle casts with a destination that's a struct or union; this
     // deals with both the gcc no-op struct cast extension and the
     // cast-to-union extension.
     if (getType()->isRecordType())
-      return cast<CastExpr>(this)->getSubExpr()
-        ->isConstantInitializer(Ctx, false);
-      
+      return CE->getSubExpr()->isConstantInitializer(Ctx, false);
+
     // Integer->integer casts can be handled here, which is important for
     // things like (int)(&&x-&&y).  Scary but true.
     if (getType()->isIntegerType() &&
-        cast<CastExpr>(this)->getSubExpr()->getType()->isIntegerType())
-      return cast<CastExpr>(this)->getSubExpr()
-        ->isConstantInitializer(Ctx, false);
-      
+        CE->getSubExpr()->getType()->isIntegerType())
+      return CE->getSubExpr()->isConstantInitializer(Ctx, false);
+
     break;
-      
+  }
   case MaterializeTemporaryExprClass:
     return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()
                                             ->isConstantInitializer(Ctx, false);

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=145981&r1=145980&r2=145981&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Dec  6 16:44:34 2011
@@ -2502,11 +2502,9 @@
 
 bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
   const VectorType *VTy = E->getType()->castAs<VectorType>();
-  QualType EltTy = VTy->getElementType();
   unsigned NElts = VTy->getNumElements();
-  unsigned EltWidth = Info.Ctx.getTypeSize(EltTy);
 
-  const Expr* SE = E->getSubExpr();
+  const Expr *SE = E->getSubExpr();
   QualType SETy = SE->getType();
 
   switch (E->getCastKind()) {
@@ -2530,34 +2528,6 @@
     SmallVector<APValue, 4> Elts(NElts, Val);
     return Success(Elts, E);
   }
-  case CK_BitCast: {
-    // FIXME: this is wrong for any cast other than a no-op cast.
-    if (SETy->isVectorType())
-      return Visit(SE);
-
-    if (!SETy->isIntegerType())
-      return Error(E);
-
-    APSInt Init;
-    if (!EvaluateInteger(SE, Init, Info))
-      return Error(E);
-
-    assert((EltTy->isIntegerType() || EltTy->isRealFloatingType()) &&
-           "Vectors must be composed of ints or floats");
-
-    SmallVector<APValue, 4> Elts;
-    for (unsigned i = 0; i != NElts; ++i) {
-      APSInt Tmp = Init.extOrTrunc(EltWidth);
-
-      if (EltTy->isIntegerType())
-        Elts.push_back(APValue(Tmp));
-      else
-        Elts.push_back(APValue(APFloat(Tmp)));
-
-      Init >>= EltWidth;
-    }
-    return Success(Elts, E);
-  }
   default:
     return ExprEvaluatorBaseTy::VisitCastExpr(E);
   }

Modified: cfe/trunk/test/CodeGen/altivec.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/altivec.c?rev=145981&r1=145980&r2=145981&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/altivec.c (original)
+++ cfe/trunk/test/CodeGen/altivec.c Tue Dec  6 16:44:34 2011
@@ -5,6 +5,15 @@
 vector int test0 = (vector int)(1);       // CHECK: @test0 = global <4 x i32> <i32 1, i32 1, i32 1, i32 1>
 vector float test1 = (vector float)(1.0); // CHECK: @test1 = global <4 x float> <float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}>
 
+// CHECK: @v1 = global <16 x i8> bitcast (<4 x i32> <i32 1, i32 2, i32 3, i32 4> to <16 x i8>)
+vector char v1 = (vector char)((vector int)(1, 2, 3, 4));
+// CHECK: @v2 = global <16 x i8> bitcast (<4 x float> <float 1.000000e+{{0+}}, float 2.000000e+{{0+}}, float 3.000000e+{{0+}}, float 4.000000e+{{0+}}> to <16 x i8>)
+vector char v2 = (vector char)((vector float)(1.0f, 2.0f, 3.0f, 4.0f));
+// CHECK: @v3 = global <16 x i8> bitcast (<4 x i32> <i32 97, i32 98, i32 99, i32 100> to <16 x i8>)
+vector char v3 = (vector char)((vector int)('a', 'b', 'c', 'd'));
+// CHECK: @v4 = global <4 x i32> bitcast (<16 x i8> <i8 1, i8 2, i8 3, i8 4, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0> to <4 x i32>)
+vector int v4 = (vector char){1, 2, 3, 4};
+
 void test2()
 {
   vector int vi;





More information about the cfe-commits mailing list