george.burgess.iv updated this revision to Diff 45930.
george.burgess.iv marked an inline comment as done.
george.burgess.iv added a comment.
- Added diagnostics that prohibit vectors of booleans in OpenCL
- Added tests for extended vectors of bools in C (previously existed only in
C++)
- Clarified some comments
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 Section 6.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
@@ -5708,9 +5708,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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits