[cfe-commits] r147496 - in /cfe/trunk: lib/AST/ExprConstant.cpp test/CodeGenOpenCL/vector_literals_nested.cl test/SemaOpenCL/vector_literals_const.cl

Eli Friedman eli.friedman at gmail.com
Tue Jan 3 15:24:20 PST 2012


Author: efriedma
Date: Tue Jan  3 17:24:20 2012
New Revision: 147496

URL: http://llvm.org/viewvc/llvm-project?rev=147496&view=rev
Log:
Support constant evaluation for OpenCL nested vector literals.  Patch by Anton Lokhmotov.


Added:
    cfe/trunk/test/CodeGenOpenCL/vector_literals_nested.cl
    cfe/trunk/test/SemaOpenCL/vector_literals_const.cl
Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=147496&r1=147495&r2=147496&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Jan  3 17:24:20 2012
@@ -3181,53 +3181,42 @@
   QualType EltTy = VT->getElementType();
   SmallVector<APValue, 4> Elements;
 
-  // 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) {
-
-    // Handle the case where the vector is initialized by another
-    // vector (OpenCL 6.1.6).
-    if (E->getInit(0)->getType()->isVectorType())
-      return Visit(E->getInit(0));
-
-    APValue InitValue;
-    if (EltTy->isIntegerType()) {
+  // The number of initializers can be less than the number of
+  // vector elements. For OpenCL, this can be due to nested vector
+  // initialization. For GCC compatibility, missing trailing elements 
+  // should be initialized with zeroes.
+  unsigned CountInits = 0, CountElts = 0;
+  while (CountElts < NumElements) {
+    // Handle nested vector initialization.
+    if (CountInits < NumInits 
+        && E->getInit(CountInits)->getType()->isExtVectorType()) {
+      APValue v;
+      if (!EvaluateVector(E->getInit(CountInits), v, Info))
+        return Error(E);
+      unsigned vlen = v.getVectorLength();
+      for (unsigned j = 0; j < vlen; j++) 
+        Elements.push_back(v.getVectorElt(j));
+      CountElts += vlen;
+    } else if (EltTy->isIntegerType()) {
       llvm::APSInt sInt(32);
-      if (!EvaluateInteger(E->getInit(0), sInt, Info))
-        return false;
-      InitValue = APValue(sInt);
+      if (CountInits < NumInits) {
+        if (!EvaluateInteger(E->getInit(CountInits), sInt, Info))
+          return Error(E);
+      } else // trailing integer zero.
+        sInt = Info.Ctx.MakeIntValue(0, EltTy);
+      Elements.push_back(APValue(sInt));
+      CountElts++;
     } else {
       llvm::APFloat f(0.0);
-      if (!EvaluateFloat(E->getInit(0), f, Info))
-        return false;
-      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 false;
-        } else {
-          sInt = Info.Ctx.MakeIntValue(0, EltTy);
-        }
-        Elements.push_back(APValue(sInt));
-      } else {
-        llvm::APFloat f(0.0);
-        if (i < NumInits) {
-          if (!EvaluateFloat(E->getInit(i), f, Info))
-            return false;
-        } else {
-          f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
-        }
-        Elements.push_back(APValue(f));
-      }
+      if (CountInits < NumInits) {
+        if (!EvaluateFloat(E->getInit(CountInits), f, Info))
+          return Error(E);
+      } else // trailing float zero.
+        f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
+      Elements.push_back(APValue(f));
+      CountElts++;
     }
+    CountInits++;
   }
   return Success(Elements, E);
 }

Added: cfe/trunk/test/CodeGenOpenCL/vector_literals_nested.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/vector_literals_nested.cl?rev=147496&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenOpenCL/vector_literals_nested.cl (added)
+++ cfe/trunk/test/CodeGenOpenCL/vector_literals_nested.cl Tue Jan  3 17:24:20 2012
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 %s -emit-llvm -O3 -o - | FileCheck %s
+
+typedef int int2 __attribute((ext_vector_type(2)));
+typedef int int4 __attribute((ext_vector_type(4)));
+
+__constant const int4 itest1 = (int4)(1, 2, ((int2)(3, 4)));
+// CHECK: constant <4 x i32> <i32 1, i32 2, i32 3, i32 4>
+__constant const int4 itest2 = (int4)(1, 2, ((int2)(3)));
+// CHECK: constant <4 x i32> <i32 1, i32 2, i32 3, i32 3>
+
+typedef float float2 __attribute((ext_vector_type(2)));
+typedef float float4 __attribute((ext_vector_type(4)));
+
+float4 ftest1() {
+  return (float4)(1.1f, 1.2f, ((float2)(1.3f, 1.4f)));
+// CHECK: ret <4 x float> <float 0x3FF19999A0000000, float 0x3FF3333340000000, float 0x3FF4CCCCC0000000, float 0x3FF6666660000000>
+}
+
+float4 ftest2() {
+   return (float4)(1.1f, 1.2f, ((float2)(1.3f)));
+// CHECK: ret <4 x float> <float 0x3FF19999A0000000, float 0x3FF3333340000000, float 0x3FF4CCCCC0000000, float 0x3FF4CCCCC0000000>
+}
+

Added: cfe/trunk/test/SemaOpenCL/vector_literals_const.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/vector_literals_const.cl?rev=147496&view=auto
==============================================================================
--- cfe/trunk/test/SemaOpenCL/vector_literals_const.cl (added)
+++ cfe/trunk/test/SemaOpenCL/vector_literals_const.cl Tue Jan  3 17:24:20 2012
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+
+typedef int int2 __attribute((ext_vector_type(2)));
+typedef int int3 __attribute((ext_vector_type(3)));
+typedef int int4 __attribute((ext_vector_type(4)));
+
+__constant int4 i_1_1_1_1 = (int4)(1,2,3,4);
+__constant int4 i_2_1_1 = (int4)((int2)(1,2),3,4);
+__constant int4 i_1_2_1 = (int4)(1,(int2)(2,3),4);
+__constant int4 i_1_1_2 = (int4)(1,2,(int2)(3,4));
+__constant int4 i_2_2 = (int4)((int2)(1,2),(int2)(3,4));
+__constant int4 i_3_1 = (int4)((int3)(1,2,3),4);
+__constant int4 i_1_3 = (int4)(1,(int3)(2,3,4));
+
+typedef float float2 __attribute((ext_vector_type(2)));
+typedef float float3 __attribute((ext_vector_type(3)));
+typedef float float4 __attribute((ext_vector_type(4)));
+
+__constant float4 f_1_1_1_1 = (float4)(1,2,3,4);
+__constant float4 f_2_1_1 = (float4)((float2)(1,2),3,4);
+__constant float4 f_1_2_1 = (float4)(1,(float2)(2,3),4);
+__constant float4 f_1_1_2 = (float4)(1,2,(float2)(3,4));
+__constant float4 f_2_2 = (float4)((float2)(1,2),(float2)(3,4));
+__constant float4 f_3_1 = (float4)((float3)(1,2,3),4);
+__constant float4 f_1_3 = (float4)(1,(float3)(2,3,4));
+





More information about the cfe-commits mailing list