[PATCH] D13349: Casting boolean to an integer vector in OpenCL should set all bits if boolean is true
Neil Hickey via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 1 08:29:47 PDT 2015
neil.hickey created this revision.
neil.hickey added a reviewer: cfe-commits.
Changing behaviour of casting a true boolean to an integer vector for OpenCL. The spec (6.2.2) states that if the boolean is true, every bit in the result vector should be set. This change will treat the i1 value as signed for the purposes of performing the cast to integer, and therefore sign extend into the result.
http://reviews.llvm.org/D13349
Files:
lib/CodeGen/CGExprScalar.cpp
test/CodeGenOpenCL/bool_cast.cl
Index: test/CodeGenOpenCL/bool_cast.cl
===================================================================
--- /dev/null
+++ test/CodeGenOpenCL/bool_cast.cl
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -O0 | FileCheck %s
+
+typedef unsigned char uchar4 __attribute((ext_vector_type(4)));
+typedef unsigned int int4 __attribute((ext_vector_type(4)));
+
+void kernel ker() {
+ bool t = true;
+ int4 vec4 = (int4)t;
+// CHECK: {{%.*}} = load i8, i8* %t, align 1
+// CHECK: {{%.*}} = trunc i8 {{%.*}} to i1
+// CHECK: {{%.*}} = sext i1 {{%.*}} to i32
+// CHECK: {{%.*}} = insertelement <4 x i32> undef, i32 {{%.*}}, i32 0
+// CHECK: {{%.*}} = shufflevector <4 x i32> {{%.*}}, <4 x i32> undef, <4 x i32> zeroinitializer
+// CHECK: store <4 x i32> {{%.*}}, <4 x i32>* %vec4, align 16
+ int i = (int)t;
+// CHECK: {{%.*}} = load i8, i8* %t, align 1
+// CHECK: {{%.*}} = trunc i8 {{%.*}} to i1
+// CHECK: {{%.*}} = zext i1 {{%.*}} to i32
+// CHECK: store i32 {{%.*}}, i32* %i, align 4
+
+ uchar4 vc;
+ vc = (uchar4)true;
+// CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 -1>, <4 x i8>* %vc, align 4
+ unsigned char c;
+ c = (unsigned char)true;
+// CHECK: store i8 1, i8* %c, align 1
+}
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -151,6 +151,9 @@
Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
SourceLocation Loc);
+ Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy,
+ SourceLocation Loc, bool TreatBooleanAsSigned);
+
/// Emit a conversion from the specified complex type to the specified
/// destination type, where the destination type is an LLVM scalar type.
Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
@@ -733,6 +736,13 @@
Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
QualType DstType,
SourceLocation Loc) {
+ return EmitScalarConversion(Src, SrcType, DstType, Loc, false);
+}
+
+Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
+ QualType DstType,
+ SourceLocation Loc,
+ bool TreatBooleanAsSigned) {
SrcType = CGF.getContext().getCanonicalType(SrcType);
DstType = CGF.getContext().getCanonicalType(DstType);
if (SrcType == DstType) return Src;
@@ -807,7 +817,7 @@
if (DstType->isExtVectorType() && !SrcType->isVectorType()) {
// Cast the scalar to element type
QualType EltTy = DstType->getAs<ExtVectorType>()->getElementType();
- llvm::Value *Elt = EmitScalarConversion(Src, SrcType, EltTy, Loc);
+ llvm::Value *Elt = EmitScalarConversion(Src, SrcType, EltTy, Loc, CGF.getContext().getLangOpts().OpenCL);
// Splat the element across to all elements
unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
@@ -847,6 +857,9 @@
if (isa<llvm::IntegerType>(SrcTy)) {
bool InputSigned = SrcType->isSignedIntegerOrEnumerationType();
+ if (SrcType->isBooleanType() && TreatBooleanAsSigned) {
+ InputSigned = true;
+ }
if (isa<llvm::IntegerType>(DstTy))
Res = Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
else if (InputSigned)
@@ -1531,10 +1544,14 @@
}
case CK_VectorSplat: {
llvm::Type *DstTy = ConvertType(DestTy);
- Value *Elt = Visit(const_cast<Expr*>(E));
- Elt = EmitScalarConversion(Elt, E->getType(),
+ // Need an IgnoreImpCasts here as by default a boolean will be promoted to
+ // an int, which will not perform the sign extension, so if we know we are
+ // going to cast to a vector we have to strip the implicit cast off.
+ Value *Elt = Visit(const_cast<Expr*>(E->IgnoreImpCasts()));
+ Elt = EmitScalarConversion(Elt, E->IgnoreImpCasts()->getType(),
DestTy->getAs<VectorType>()->getElementType(),
- CE->getExprLoc());
+ CE->getExprLoc(),
+ CGF.getContext().getLangOpts().OpenCL);
// Splat the element across to all elements
unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13349.36247.patch
Type: text/x-patch
Size: 4467 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151001/1922a0bc/attachment.bin>
More information about the cfe-commits
mailing list