aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-06-11 17:54:15 +0000
committerJohn McCall <rjmccall@apple.com>2010-06-11 17:54:15 +0000
commita7d6c221558fa8117aa1d1fd41cf0046c5c9fade (patch)
tree48190fafaaa54de8c2d4fdf4e9bbbafd29a1ca5c
parent81e317a444dd756a1cafe94031e4b3f3c138dac6 (diff)
Fix the constant evaluator for AltiVec-style vector literals so that the
vector is filled with the given constant; we were just initializing the first element. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105824 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ExprConstant.cpp47
-rw-r--r--test/CodeGen/altivec.c4
2 files changed, 38 insertions, 13 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index dc614018ec..d97d625616 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -746,25 +746,46 @@ VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
QualType EltTy = VT->getElementType();
llvm::SmallVector<APValue, 4> Elements;
- for (unsigned i = 0; i < NumElements; i++) {
+ // If a vector is initialized with a single element, that value
+ // becomes every element of the vector, not just the first.
+ // This is the behavior described in the IBM AltiVec documentation.
+ if (NumInits == 1) {
+ APValue InitValue;
if (EltTy->isIntegerType()) {
llvm::APSInt sInt(32);
- if (i < NumInits) {
- if (!EvaluateInteger(E->getInit(i), sInt, Info))
- return APValue();
- } else {
- sInt = Info.Ctx.MakeIntValue(0, EltTy);
- }
- Elements.push_back(APValue(sInt));
+ if (!EvaluateInteger(E->getInit(0), sInt, Info))
+ return APValue();
+ InitValue = APValue(sInt);
} else {
llvm::APFloat f(0.0);
- if (i < NumInits) {
- if (!EvaluateFloat(E->getInit(i), f, Info))
- return APValue();
+ if (!EvaluateFloat(E->getInit(0), f, Info))
+ return APValue();
+ InitValue = APValue(f);
+ }
+ for (unsigned i = 0; i < NumElements; i++) {
+ Elements.push_back(InitValue);
+ }
+ } else {
+ for (unsigned i = 0; i < NumElements; i++) {
+ if (EltTy->isIntegerType()) {
+ llvm::APSInt sInt(32);
+ if (i < NumInits) {
+ if (!EvaluateInteger(E->getInit(i), sInt, Info))
+ return APValue();
+ } else {
+ sInt = Info.Ctx.MakeIntValue(0, EltTy);
+ }
+ Elements.push_back(APValue(sInt));
} else {
- f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
+ llvm::APFloat f(0.0);
+ if (i < NumInits) {
+ if (!EvaluateFloat(E->getInit(i), f, Info))
+ return APValue();
+ } else {
+ f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
+ }
+ Elements.push_back(APValue(f));
}
- Elements.push_back(APValue(f));
}
}
return APValue(&Elements[0], Elements.size());
diff --git a/test/CodeGen/altivec.c b/test/CodeGen/altivec.c
new file mode 100644
index 0000000000..9e38df5093
--- /dev/null
+++ b/test/CodeGen/altivec.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @test0 = global <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+vector int test0 = (vector int)(1);