]> granicus.if.org Git - clang/commitdiff
Fix the constant evaluator for AltiVec-style vector literals so that the
authorJohn McCall <rjmccall@apple.com>
Fri, 11 Jun 2010 17:54:15 +0000 (17:54 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 11 Jun 2010 17:54:15 +0000 (17:54 +0000)
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

lib/AST/ExprConstant.cpp
test/CodeGen/altivec.c [new file with mode: 0644]

index dc614018ec2b7b7b3f48f5819c4254af675c686e..d97d6256167daf96823021cd747f599c00f29762 100644 (file)
@@ -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 (file)
index 0000000..9e38df5
--- /dev/null
@@ -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);