diff options
-rw-r--r-- | lib/AST/Expr.cpp | 22 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 32 | ||||
-rw-r--r-- | test/CodeGen/altivec.c | 9 |
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; |