aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/Expr.cpp22
-rw-r--r--lib/AST/ExprConstant.cpp32
-rw-r--r--test/CodeGen/altivec.c9
3 files changed, 23 insertions, 40 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index c2880a0ad1..08611c32c6 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2541,23 +2541,27 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
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);
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 438bef5de8..6a290a6c83 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -2502,11 +2502,9 @@ static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
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 @@ bool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
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);
}
diff --git a/test/CodeGen/altivec.c b/test/CodeGen/altivec.c
index c3b1f42e06..bd694a6a56 100644
--- a/test/CodeGen/altivec.c
+++ b/test/CodeGen/altivec.c
@@ -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;