diff options
-rw-r--r-- | lib/AST/ExprConstant.cpp | 22 | ||||
-rw-r--r-- | test/Sema/ext_vector_components.c | 2 |
2 files changed, 21 insertions, 3 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 4815ae5c3b..9d765924e0 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -486,12 +486,28 @@ static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { const Expr* SE = E->getSubExpr(); + QualType SETy = SE->getType(); + APValue Result = APValue(); - // Check for vector->vector bitcast. - if (SE->getType()->isVectorType()) + // Check for vector->vector bitcast and scalar->vector splat. + if (SETy->isVectorType()) { return this->Visit(const_cast<Expr*>(SE)); + } else if (SETy->isIntegerType()) { + APSInt IntResult; + if (EvaluateInteger(SE, IntResult, Info)) + Result = APValue(IntResult); + } else if (SETy->isRealFloatingType()) { + APFloat F(0.0); + if (EvaluateFloat(SE, F, Info)) + Result = APValue(F); + } - return APValue(); + if (Result.isInt() || Result.isFloat()) { + unsigned NumElts = E->getType()->getAsVectorType()->getNumElements(); + llvm::SmallVector<APValue, 4> Elts(NumElts, Result); + Result = APValue(&Elts[0], Elts.size()); + } + return Result; } APValue diff --git a/test/Sema/ext_vector_components.c b/test/Sema/ext_vector_components.c index a5d270074a..48903024d3 100644 --- a/test/Sema/ext_vector_components.c +++ b/test/Sema/ext_vector_components.c @@ -5,6 +5,8 @@ typedef __attribute__(( ext_vector_type(3) )) float float3; typedef __attribute__(( ext_vector_type(4) )) float float4; typedef __attribute__(( ext_vector_type(16) )) float float16; +static float4 vec4_0 = (float4)0.5f; + static void test() { float2 vec2, vec2_2; float3 vec3; |