r283891 - [OpenCL] Allow partial initializer for array and struct

Yaxun Liu via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 11 08:53:29 PDT 2016


Author: yaxunl
Date: Tue Oct 11 10:53:28 2016
New Revision: 283891

URL: http://llvm.org/viewvc/llvm-project?rev=283891&view=rev
Log:
[OpenCL] Allow partial initializer for array and struct

Currently Clang allows partial initializer for C99 but not for OpenCL, e.g.

float a[16][16] = {1.0f, 2.0f};

is allowed in C99 but not allowed in OpenCL.

This patch fixes that.

Differential Revision: https://reviews.llvm.org/D25335

Added:
    cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl
Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=283891&r1=283890&r2=283891&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Oct 11 10:53:28 2016
@@ -1238,8 +1238,9 @@ void InitListChecker::CheckSubElementTyp
   //   subaggregate, brace elision is assumed and the initializer is
   //   considered for the initialization of the first member of
   //   the subaggregate.
-  if (!SemaRef.getLangOpts().OpenCL && 
-      (ElemType->isAggregateType() || ElemType->isVectorType())) {
+  // OpenCL vector initializer is handled elsewhere.
+  if ((!SemaRef.getLangOpts().OpenCL && ElemType->isVectorType()) ||
+      ElemType->isAggregateType()) {
     CheckImplicitInitList(Entity, IList, ElemType, Index, StructuredList,
                           StructuredIndex);
     ++StructuredIndex;

Added: cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl?rev=283891&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl (added)
+++ cfe/trunk/test/CodeGenOpenCL/partial_initializer.cl Tue Oct 11 10:53:28 2016
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm %s -O0 -o - | FileCheck %s
+
+typedef __attribute__(( ext_vector_type(2) ))  int int2;
+typedef __attribute__(( ext_vector_type(4) ))  int int4;
+
+// CHECK: %struct.StrucTy = type { i32, i32, i32 }
+
+// CHECK: @GA = addrspace(1) global [6 x [6 x float]] {{[[][[]}}6 x float] [float 1.000000e+00, float 2.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00],
+// CHECK:        [6 x float] zeroinitializer, [6 x float] zeroinitializer, [6 x float] zeroinitializer, [6 x float] zeroinitializer, [6 x float] zeroinitializer], align 4 
+float GA[6][6]  = {1.0f, 2.0f};
+
+typedef struct {
+  int x;
+  int y;
+  int z;
+} StrucTy;
+
+// CHECK: @GS = addrspace(1) global %struct.StrucTy { i32 1, i32 2, i32 0 }, align 4
+StrucTy GS = {1, 2};
+
+// CHECK: @GV1 = addrspace(1) global <4 x i32> <i32 1, i32 2, i32 3, i32 4>, align 16
+int4 GV1 = (int4)((int2)(1,2),3,4);
+
+// CHECK: @GV2 = addrspace(1) global <4 x i32> <i32 1, i32 1, i32 1, i32 1>, align 16
+int4 GV2 = (int4)(1);
+
+// CHECK: @f.S = private unnamed_addr constant %struct.StrucTy { i32 1, i32 2, i32 0 }, align 4
+
+// CHECK-LABEL: define spir_func void @f()
+void f(void) {
+  // CHECK: %[[A:.*]] = alloca [6 x [6 x float]], align 4
+  // CHECK: %[[S:.*]] = alloca %struct.StrucTy, align 4
+  // CHECK: %[[V1:.*]] = alloca <4 x i32>, align 16
+  // CHECK: %[[compoundliteral:.*]] = alloca <4 x i32>, align 16
+  // CHECK: %[[compoundliteral1:.*]] = alloca <2 x i32>, align 8
+  // CHECK: %[[V2:.*]] = alloca <4 x i32>, align 16
+
+  // CHECK: %[[v0:.*]] = bitcast [6 x [6 x float]]* %A to i8*
+  // CHECK: call void @llvm.memset.p0i8.i32(i8* %[[v0]], i8 0, i32 144, i32 4, i1 false)
+  // CHECK: %[[v1:.*]] = bitcast i8* %[[v0]] to [6 x [6 x float]]*
+  // CHECK: %[[v2:.*]] = getelementptr [6 x [6 x float]], [6 x [6 x float]]* %[[v1]], i32 0, i32 0
+  // CHECK: %[[v3:.*]] = getelementptr [6 x float], [6 x float]* %[[v2]], i32 0, i32 0
+  // CHECK: store float 1.000000e+00, float* %[[v3]]
+  // CHECK: %[[v4:.*]] = getelementptr [6 x float], [6 x float]* %[[v2]], i32 0, i32 1
+  // CHECK: store float 2.000000e+00, float* %[[v4]]
+  float A[6][6]  = {1.0f, 2.0f};
+
+  // CHECK: %[[v5:.*]] = bitcast %struct.StrucTy* %S to i8*
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[v5]], i8* bitcast (%struct.StrucTy* @f.S to i8*), i32 12, i32 4, i1 false)
+  StrucTy S = {1, 2};
+
+  // CHECK: store <2 x i32> <i32 1, i32 2>, <2 x i32>* %[[compoundliteral1]], align 8
+  // CHECK: %[[v6:.*]] = load <2 x i32>, <2 x i32>* %[[compoundliteral1]], align 8
+  // CHECK: %[[vext:.*]] = shufflevector <2 x i32> %[[v6]], <2 x i32> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
+  // CHECK: %[[vecinit:.*]] = shufflevector <4 x i32> %[[vext]], <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
+  // CHECK: %[[vecinit2:.*]] = insertelement <4 x i32> %[[vecinit]], i32 3, i32 2
+  // CHECK: %[[vecinit3:.*]] = insertelement <4 x i32> %[[vecinit2]], i32 4, i32 3
+  // CHECK: store <4 x i32> %[[vecinit3]], <4 x i32>* %[[compoundliteral]], align 16
+  // CHECK: %[[v7:.*]] = load <4 x i32>, <4 x i32>* %[[compoundliteral]], align 16
+  // CHECK: store <4 x i32> %[[v7]], <4 x i32>* %[[V1]], align 16
+  int4 V1 = (int4)((int2)(1,2),3,4);
+
+  // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32>* %[[V2]], align 16
+  int4 V2 = (int4)(1);
+}
+




More information about the cfe-commits mailing list