[PATCH] D13349: [OpenCL] 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
Fri Oct 2 05:27:36 PDT 2015


neil.hickey updated this revision to Diff 36348.
neil.hickey added a comment.

Fixing formatting problems.


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,8 @@
   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 +858,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 +1545,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.36348.patch
Type: text/x-patch
Size: 4477 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151002/173662d6/attachment.bin>


More information about the cfe-commits mailing list