[PATCH] D15721: [Sema] Fix ICE on casting a vector of bools to a vector of T
George Burgess IV via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 22 11:17:31 PST 2015
george.burgess.iv created this revision.
george.burgess.iv added a reviewer: Anastasia.
george.burgess.iv added a subscriber: cfe-commits.
Clang generally treats booleans as 8-bit types, but lowers them to 1-bit types. This means we currently happily accept C++ code like:
```
typedef __attribute__((__ext_vector_type__(4))) bool BoolVector;
typedef __attribute__((__ext_vector_type__(1))) int IntVector;
int main() {
BoolVector bv;
IntVector iv = (IntVector)bv;
}
```
...And lower it to a cast from a `[4 x i1]` to a `[1 x i32]`. Which gives us a nice greeting in the form of an ICE.
ISTM that `bool`s are only a valid element type in OpenCL vectors. The spec doesn't outline a definitive size for a `bool` (only that it must be able to support a 0 or 1), so I'm assuming that lowering to a vector of `i1` is fine.
http://reviews.llvm.org/D15721
Files:
lib/Sema/SemaExpr.cpp
test/CodeGenCXX/bool-vector-conversion.cpp
Index: test/CodeGenCXX/bool-vector-conversion.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/bool-vector-conversion.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 %s -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).
+
+// Nothing but OpenCL allows vectors of booleans.
+// CHECK-LABEL: @_Z4testv
+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)false;
+ // 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)false;
+}
+
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -5552,9 +5552,14 @@
// 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.
+ uint64_t srcEltSize =
+ srcEltTy->isBooleanType() ? 1 : Context.getTypeSize(srcEltTy);
+ uint64_t destEltSize =
+ destEltTy->isBooleanType() ? 1 : Context.getTypeSize(destEltTy);
+
return (srcLen * srcEltSize == destLen * destEltSize);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15721.43463.patch
Type: text/x-patch
Size: 1996 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151222/4098ae94/attachment.bin>
More information about the cfe-commits
mailing list