diff options
author | John McCall <rjmccall@apple.com> | 2010-06-11 17:54:15 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-06-11 17:54:15 +0000 |
commit | a7d6c221558fa8117aa1d1fd41cf0046c5c9fade (patch) | |
tree | 48190fafaaa54de8c2d4fdf4e9bbbafd29a1ca5c | |
parent | 81e317a444dd756a1cafe94031e4b3f3c138dac6 (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.cpp | 47 | ||||
-rw-r--r-- | test/CodeGen/altivec.c | 4 |
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); |