george.burgess.iv updated this revision to Diff 46053.
george.burgess.iv marked an inline comment as done.
george.burgess.iv added a comment.

Updated comment, as requested.


http://reviews.llvm.org/D15721

Files:
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaType.cpp
  test/CodeGen/bool-vector-conversion.c
  test/SemaOpenCL/bool-vectors.cl

Index: test/SemaOpenCL/bool-vectors.cl
===================================================================
--- /dev/null
+++ test/SemaOpenCL/bool-vectors.cl
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+
+typedef __attribute__((ext_vector_type(16))) _Bool bool8; // expected-error{{invalid vector element type 'bool'}}
Index: test/CodeGen/bool-vector-conversion.c
===================================================================
--- /dev/null
+++ test/CodeGen/bool-vector-conversion.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -x c -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -x c++ -emit-llvm -o - | FileCheck %s
+//
+// In many parts of clang, we treat a bool as an i8, but we lower it to an i1.
+// This is usually fine, but it broke things with vectors (e.g. we deemed a cast
+// from a [4 x i1] to a [1 x i32] to be legal, and proceeded to crash shortly
+// afterward).
+
+#ifdef __cplusplus
+typedef bool BOOL;
+#else
+typedef _Bool BOOL;
+#endif
+
+// Only extended vectors allow bool elements.
+// __asm__ label keeps C++ mangling from happening
+void test() __asm__("test");
+
+// CHECK-LABEL: @test
+void test() {
+  typedef __attribute__((__ext_vector_type__(8))) BOOL CLVectorBool8;
+  typedef __attribute__((__ext_vector_type__(1))) unsigned char CLVectorInt1;
+
+  // CHECK: store <8 x i1> zeroinitializer
+  CLVectorBool8 bools = (CLVectorBool8)0;
+  // CHECK: store <1 x i8>
+  CLVectorInt1 ints = (CLVectorInt1)bools;
+  // CHECK: store <8 x i1>
+  bools = (CLVectorBool8)ints;
+
+  // Run through the code in CGExprConstant.
+  // CHECK: store <8 x i1> zeroinitializer
+  bools = (CLVectorBool8)(CLVectorInt1)(CLVectorBool8)0;
+}
+
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -2184,10 +2184,15 @@
 /// Run the required checks for the extended vector type.
 QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize,
                                   SourceLocation AttrLoc) {
-  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
+  // Unlike gcc's vector_size attribute, we do not allow vectors to be defined
   // in conjunction with complex types (pointers, arrays, functions, etc.).
-  if (!T->isDependentType() &&
-      !T->isIntegerType() && !T->isRealFloatingType()) {
+  //
+  // Additionally, OpenCL prohibits vectors of booleans (they're considered a
+  // reserved data type under OpenCL v2.0 s6.1.4), but we do allow their use
+  // outside of OpenCL.
+  if ((!T->isDependentType() && !T->isIntegerType() &&
+       !T->isRealFloatingType()) ||
+      (getLangOpts().OpenCL && T->isBooleanType())) {
     Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << T;
     return QualType();
   }
@@ -2201,7 +2206,7 @@
       return QualType();
     }
 
-    // unlike gcc's vector_size attribute, the size is specified as the
+    // Unlike gcc's vector_size attribute, the size is specified as the
     // number of elements, not the number of bytes.
     unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
 
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -5718,9 +5718,15 @@
   // ASTContext::getTypeSize will return the size rounded up to a
   // power of 2, so instead of using that, we need to use the raw
   // element size multiplied by the element count.
-  uint64_t srcEltSize = Context.getTypeSize(srcEltTy);
-  uint64_t destEltSize = Context.getTypeSize(destEltTy);
-  
+  //
+  // We need to be careful about booleans though; they're lowered to i1s, but
+  // getTypeSize views them as i8s. (They're allowed in extended vectors
+  // when compiling code as e.g. C++)
+  uint64_t srcEltSize =
+      srcEltTy->isBooleanType() ? 1 : Context.getTypeSize(srcEltTy);
+  uint64_t destEltSize =
+      destEltTy->isBooleanType() ? 1 : Context.getTypeSize(destEltTy);
+
   return (srcLen * srcEltSize == destLen * destEltSize);
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to