]> granicus.if.org Git - clang/commitdiff
[Bugfix] Fix ICE on constexpr vector splat.
authorGeorge Burgess IV <george.burgess.iv@gmail.com>
Wed, 13 Jan 2016 01:52:39 +0000 (01:52 +0000)
committerGeorge Burgess IV <george.burgess.iv@gmail.com>
Wed, 13 Jan 2016 01:52:39 +0000 (01:52 +0000)
In {CG,}ExprConstant.cpp, we weren't treating vector splats properly.
This patch makes us treat splats more properly.

Additionally, this patch adds a new cast kind which allows a bool->int
cast to result in -1 or 0, instead of 1 or 0 (for true and false,
respectively), so we can sanely model OpenCL bool->int casts in the AST.

Differential Revision: http://reviews.llvm.org/D14877

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@257559 91177308-0d34-0410-b5e6-96231b3b80d8

20 files changed:
include/clang/AST/ASTContext.h
include/clang/AST/OperationKinds.h
include/clang/Sema/Sema.h
lib/AST/Expr.cpp
lib/AST/ExprConstant.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
lib/Edit/RewriteObjCFoundationAPI.cpp
lib/Sema/SemaCast.cpp
lib/Sema/SemaChecking.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaOverload.cpp
lib/StaticAnalyzer/Core/ExprEngineC.cpp
test/CodeGenCXX/builtins-systemz-zvector.cpp [new file with mode: 0644]
test/CodeGenCXX/vector-splat-conversion.cpp
test/CodeGenOpenCL/bool_cast.cl

index 9140eabe83b6abfe6a781429b73daa0232f6454c..abf92948bb42ed7ae4731725755136dc7d4f8f17 100644 (file)
@@ -2283,9 +2283,13 @@ public:
   /// \brief Make an APSInt of the appropriate width and signedness for the
   /// given \p Value and integer \p Type.
   llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const {
-    llvm::APSInt Res(getIntWidth(Type), 
-                     !Type->isSignedIntegerOrEnumerationType());
+    // If Type is a signed integer type larger than 64 bits, we need to be sure
+    // to sign extend Res appropriately.
+    llvm::APSInt Res(64, !Type->isSignedIntegerOrEnumerationType());
     Res = Value;
+    unsigned Width = getIntWidth(Type);
+    if (Width != Res.getBitWidth())
+      return Res.extOrTrunc(Width);
     return Res;
   }
 
index 2235c1012fb77f6502e14b4c6fbe14753abcb315..102bbc21edb373f477af97fc353fda39661b99fb 100644 (file)
@@ -185,7 +185,11 @@ enum CastKind {
   /// CK_FloatingToBoolean - Floating point to boolean.
   ///    (bool) f
   CK_FloatingToBoolean,
-    
+
+  // CK_BooleanToSignedIntegral - Convert a boolean to -1 or 0 for true and
+  // false, respectively.
+  CK_BooleanToSignedIntegral,
+
   /// CK_FloatingCast - Casting between floating types of different size.
   ///    (double) f
   ///    (float) ld
index 0d49298bfc409cce1861204ac72a720fa5e79d06..ffe1ff3b950b808f77b49e1a9c69f5302ff684a6 100644 (file)
@@ -8589,6 +8589,10 @@ public:
   bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
                        CastKind &Kind);
 
+  /// \brief Prepare `SplattedExpr` for a vector splat operation, adding
+  /// implicit casts if necessary.
+  ExprResult prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr);
+
   // CheckExtVectorCast - check type constraints for extended vectors.
   // Since vectors are an extension, there are no C standard reference for this.
   // We allow casting between vectors and integer datatypes of the same size,
index f9757b2092948b5d1b37feca23326cd20be38b20..52f34df4356550d3f878f535939c5ce21071b4d0 100644 (file)
@@ -1553,6 +1553,7 @@ bool CastExpr::CastConsistency() const {
   case CK_ToVoid:
   case CK_VectorSplat:
   case CK_IntegralCast:
+  case CK_BooleanToSignedIntegral:
   case CK_IntegralToFloating:
   case CK_FloatingToIntegral:
   case CK_FloatingCast:
@@ -1646,6 +1647,8 @@ const char *CastExpr::getCastKindName() const {
     return "VectorSplat";
   case CK_IntegralCast:
     return "IntegralCast";
+  case CK_BooleanToSignedIntegral:
+    return "BooleanToSignedIntegral";
   case CK_IntegralToBoolean:
     return "IntegralToBoolean";
   case CK_IntegralToFloating:
index c4c4398c362213a841e7a1b0ccb392740ee121a8..fa652ba1b0ab259a3d1fbedfb5c4a68125189257 100644 (file)
@@ -7781,12 +7781,16 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
   case CK_PointerToBoolean:
   case CK_IntegralToBoolean:
   case CK_FloatingToBoolean:
+  case CK_BooleanToSignedIntegral:
   case CK_FloatingComplexToBoolean:
   case CK_IntegralComplexToBoolean: {
     bool BoolResult;
     if (!EvaluateAsBooleanCondition(SubExpr, BoolResult, Info))
       return false;
-    return Success(BoolResult, E);
+    uint64_t IntResult = BoolResult;
+    if (BoolResult && E->getCastKind() == CK_BooleanToSignedIntegral)
+      IntResult = (uint64_t)-1;
+    return Success(IntResult, E);
   }
 
   case CK_IntegralCast: {
@@ -8223,6 +8227,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
   case CK_ToVoid:
   case CK_VectorSplat:
   case CK_IntegralCast:
+  case CK_BooleanToSignedIntegral:
   case CK_IntegralToBoolean:
   case CK_IntegralToFloating:
   case CK_FloatingToIntegral:
index dabd2b1528bb275ccf16f63f9cb20b52d814a8e9..507ce3d7d0cea87ea7ccab337cbbaf1aed8a94eb 100644 (file)
@@ -3365,6 +3365,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
   case CK_PointerToBoolean:
   case CK_VectorSplat:
   case CK_IntegralCast:
+  case CK_BooleanToSignedIntegral:
   case CK_IntegralToBoolean:
   case CK_IntegralToFloating:
   case CK_FloatingToIntegral:
index 20838db044c96bb2cb28e193146a59fd70c5777d..a4547a9982be08b86a56b8c41a289d0475f4ddd1 100644 (file)
@@ -721,6 +721,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
   case CK_ToVoid:
   case CK_VectorSplat:
   case CK_IntegralCast:
+  case CK_BooleanToSignedIntegral:
   case CK_IntegralToBoolean:
   case CK_IntegralToFloating:
   case CK_FloatingToIntegral:
index ccdb53287e9f7b1bf1a877f57736200f70b20e18..22910d931dedfae75e30fd5a0bb22f0f5baecff7 100644 (file)
@@ -462,6 +462,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
   case CK_ToVoid:
   case CK_VectorSplat:
   case CK_IntegralCast:
+  case CK_BooleanToSignedIntegral:
   case CK_IntegralToBoolean:
   case CK_IntegralToFloating:
   case CK_FloatingToIntegral:
index 3839ab718fa3433e648109d5c4e3ffba8a722e74..ee049f1810a2fc1e6062c6e1160aabc20e3d18f0 100644 (file)
@@ -735,6 +735,7 @@ public:
     case CK_PointerToBoolean:
     case CK_NullToPointer:
     case CK_IntegralCast:
+    case CK_BooleanToSignedIntegral:
     case CK_IntegralToPointer:
     case CK_IntegralToBoolean:
     case CK_IntegralToFloating:
index 725d96f29877d762bdedb3dedfa3a2c5b45ca9c2..268e7967b808b8311f40d07a08fb85b392df40c6 100644 (file)
@@ -811,14 +811,15 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
 
   // A scalar can be splatted to an extended vector of the same element type
   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, CGF.getContext().getLangOpts().OpenCL);
+    // Sema should add casts to make sure that the source expression's type is
+    // the same as the vector's element type (sans qualifiers)
+    assert(DstType->castAs<ExtVectorType>()->getElementType().getTypePtr() ==
+               SrcType.getTypePtr() &&
+           "Splatted expr doesn't match with vector element type?");
 
     // Splat the element across to all elements
     unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
-    return Builder.CreateVectorSplat(NumElements, Elt, "splat");
+    return Builder.CreateVectorSplat(NumElements, Src, "splat");
   }
 
   // Allow bitcast from vector to integer/fp of the same size.
@@ -1541,15 +1542,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
   }
   case CK_VectorSplat: {
     llvm::Type *DstTy = ConvertType(DestTy);
-    // 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(), 
-                               CGF.getContext().getLangOpts().OpenCL);
-
+    Value *Elt = Visit(const_cast<Expr*>(E));
     // Splat the element across to all elements
     unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
     return Builder.CreateVectorSplat(NumElements, Elt, "splat");
@@ -1561,6 +1554,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
   case CK_FloatingCast:
     return EmitScalarConversion(Visit(E), E->getType(), DestTy,
                                 CE->getExprLoc());
+  case CK_BooleanToSignedIntegral:
+    return EmitScalarConversion(Visit(E), E->getType(), DestTy,
+                                CE->getExprLoc(),
+                                /*TreatBooleanAsSigned=*/true);
   case CK_IntegralToBoolean:
     return EmitIntToBoolConversion(Visit(E));
   case CK_PointerToBoolean:
index 9f71168de8fc401d4a00bdb70877361832c786e3..482c0f6f85686dff524dd32bcfc64c55dd93491f 100644 (file)
@@ -1077,6 +1077,9 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg,
     case CK_BuiltinFnToFnPtr:
     case CK_ZeroToOCLEvent:
       return false;
+
+    case CK_BooleanToSignedIntegral:
+      llvm_unreachable("OpenCL-specific cast in Objective-C?");
     }
   }
 
index 07b058911c2df09ff970562de6fab9eef15a47e5..ad1d7da4d070cd00c29ca7901eb38fff34256cc6 100644 (file)
@@ -2105,6 +2105,7 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
         && (SrcExpr.get()->getType()->isIntegerType()
             || SrcExpr.get()->getType()->isFloatingType())) {
       Kind = CK_VectorSplat;
+      SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
       return;
     }
 
@@ -2339,6 +2340,7 @@ void CastOperation::CheckCStyleCast() {
     if (DestVecTy->getVectorKind() == VectorType::AltiVecVector &&
           (SrcType->isIntegerType() || SrcType->isFloatingType())) {
       Kind = CK_VectorSplat;
+      SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
     } else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
       SrcExpr = ExprError();
     }
index 4680bcd11d078cea7e4ebc8d2e51bcca9b76098b..6c2834b750aed40eb40e3d29c22b8fa0cfcc2e47 100644 (file)
@@ -6243,7 +6243,8 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
 
     IntRange OutputTypeRange = IntRange::forValueOfType(C, GetExprType(CE));
 
-    bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast);
+    bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
+                         CE->getCastKind() == CK_BooleanToSignedIntegral;
 
     // Assume that non-integer casts can span the full range of the type.
     if (!isIntegerCast)
index 361b0a1b72d8508cf2fea67bee8a9115f4c516ca..3e89af625d1acb799f5c6b9acbcd9df974ddfad4 100644 (file)
@@ -5602,6 +5602,39 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
   return false;
 }
 
+ExprResult Sema::prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr) {
+  QualType DestElemTy = VectorTy->castAs<VectorType>()->getElementType();
+
+  if (DestElemTy == SplattedExpr->getType())
+    return SplattedExpr;
+
+  assert(DestElemTy->isFloatingType() ||
+         DestElemTy->isIntegralOrEnumerationType());
+
+  CastKind CK;
+  if (VectorTy->isExtVectorType() && SplattedExpr->getType()->isBooleanType()) {
+    // OpenCL requires that we convert `true` boolean expressions to -1, but
+    // only when splatting vectors.
+    if (DestElemTy->isFloatingType()) {
+      // To avoid having to have a CK_BooleanToSignedFloating cast kind, we cast
+      // in two steps: boolean to signed integral, then to floating.
+      ExprResult CastExprRes = ImpCastExprToType(SplattedExpr, Context.IntTy,
+                                                 CK_BooleanToSignedIntegral);
+      SplattedExpr = CastExprRes.get();
+      CK = CK_IntegralToFloating;
+    } else {
+      CK = CK_BooleanToSignedIntegral;
+    }
+  } else {
+    ExprResult CastExprRes = SplattedExpr;
+    CK = PrepareScalarCast(CastExprRes, DestElemTy);
+    if (CastExprRes.isInvalid())
+      return ExprError();
+    SplattedExpr = CastExprRes.get();
+  }
+  return ImpCastExprToType(SplattedExpr, DestElemTy, CK);
+}
+
 ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy,
                                     Expr *CastExpr, CastKind &Kind) {
   assert(DestTy->isExtVectorType() && "Not an extended vector type!");
@@ -5632,15 +5665,8 @@ ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy,
                 diag::err_invalid_conversion_between_vector_and_scalar)
       << DestTy << SrcTy << R;
 
-  QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType();
-  ExprResult CastExprRes = CastExpr;
-  CastKind CK = PrepareScalarCast(CastExprRes, DestElemTy);
-  if (CastExprRes.isInvalid())
-    return ExprError();
-  CastExpr = ImpCastExprToType(CastExprRes.get(), DestElemTy, CK).get();
-
   Kind = CK_VectorSplat;
-  return CastExpr;
+  return prepareVectorSplat(DestTy, CastExpr);
 }
 
 ExprResult
@@ -6979,13 +7005,9 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
     if (RHSType->isExtVectorType())
       return Incompatible;
     if (RHSType->isArithmeticType()) {
-      // CK_VectorSplat does T -> vector T, so first cast to the
-      // element type.
-      QualType elType = cast<ExtVectorType>(LHSType)->getElementType();
-      if (elType != RHSType && ConvertRHS) {
-        Kind = PrepareScalarCast(RHS, elType);
-        RHS = ImpCastExprToType(RHS.get(), elType, Kind);
-      }
+      // CK_VectorSplat does T -> vector T, so first cast to the element type.
+      if (ConvertRHS)
+        RHS = prepareVectorSplat(LHSType, RHS.get());
       Kind = CK_VectorSplat;
       return Compatible;
     }
@@ -8203,7 +8225,7 @@ static QualType checkOpenCLVectorShift(Sema &S,
   if (RHS.isInvalid()) return QualType();
 
   QualType LHSType = LHS.get()->getType();
-  const VectorType *LHSVecTy = LHSType->getAs<VectorType>();
+  const VectorType *LHSVecTy = LHSType->castAs<VectorType>();
   QualType LHSEleType = LHSVecTy->getElementType();
 
   // Note that RHS might not be a vector.
index 2ad595f3a81420b6cd2d6d9dca10700c482078a9..38fbea18d790d45f7fd6d4c87a38b431bda38a01 100644 (file)
@@ -3353,20 +3353,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
                              VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
-  case ICK_Vector_Splat:
+  case ICK_Vector_Splat: {
     // Vector splat from any arithmetic type to a vector.
-    // Cast to the element type.
-    {
-      QualType elType = ToType->getAs<ExtVectorType>()->getElementType();
-      if (elType != From->getType()) {
-        ExprResult E = From;
-        From = ImpCastExprToType(From, elType,
-                                 PrepareScalarCast(E, elType)).get();
-      }
-      From = ImpCastExprToType(From, ToType, CK_VectorSplat,
-                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
-    }
+    Expr *Elem = prepareVectorSplat(ToType, From).get();
+    From = ImpCastExprToType(Elem, ToType, CK_VectorSplat, VK_RValue,
+                             /*BasePath=*/nullptr, CCK).get();
     break;
+  }
 
   case ICK_Complex_Real:
     // Case 1.  x -> _Complex y
index 682f3692bac7d1d2f46db9685c2fdb69ee46112e..663da0c0e8040bf03215973696c024ac49762be6 100644 (file)
@@ -258,6 +258,7 @@ static const Expr *IgnoreNarrowingConversion(const Expr *Converted) {
     case CK_IntegralCast:
     case CK_IntegralToBoolean:
     case CK_IntegralToFloating:
+    case CK_BooleanToSignedIntegral:
     case CK_FloatingToIntegral:
     case CK_FloatingToBoolean:
     case CK_FloatingCast:
index 3a30b29781baf59abeac848b7458066e02283893..175225ba0de2fa89acb9bccb2edf77b71b60bdeb 100644 (file)
@@ -316,6 +316,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
       case CK_ArrayToPointerDecay:
       case CK_BitCast:
       case CK_AddressSpaceConversion:
+      case CK_BooleanToSignedIntegral:
       case CK_NullToPointer:
       case CK_IntegralToPointer:
       case CK_PointerToIntegral:
@@ -344,6 +345,9 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
         // Delegate to SValBuilder to process.
         SVal V = state->getSVal(Ex, LCtx);
         V = svalBuilder.evalCast(V, T, ExTy);
+        // Negate the result if we're treating the boolean as a signed i1
+        if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
+          V = evalMinus(V);
         state = state->BindExpr(CastE, LCtx, V);
         Bldr.generateNode(CastE, Pred, state);
         continue;
diff --git a/test/CodeGenCXX/builtins-systemz-zvector.cpp b/test/CodeGenCXX/builtins-systemz-zvector.cpp
new file mode 100644 (file)
index 0000000..aedb30f
--- /dev/null
@@ -0,0 +1,50 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -target-cpu z13 -triple s390x-linux-gnu \
+// RUN: -fzvector -fno-lax-vector-conversions -std=c++11 \
+// RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s
+
+bool gb;
+
+// There was an issue where we weren't properly converting constexprs to
+// vectors with elements of the appropriate width. (e.g.
+// (vector signed short)0 would be lowered as [4 x i32] in some cases)
+
+// CHECK-LABEL: @_Z8testIntsDv4_i
+void testInts(vector int VI) {
+  constexpr vector int CI1 = (vector int)0LL;
+  // CHECK: icmp
+  gb = (VI == CI1)[0];
+
+  // Likewise for float inits.
+  constexpr vector int CI2 = (vector int)char(0);
+  // CHECK: icmp
+  gb = (VI == CI2)[0];
+
+  constexpr vector int CF1 = (vector int)0.0;
+  // CHECK: icmp
+  gb = (VI == CF1)[0];
+
+  constexpr vector int CF2 = (vector int)0.0f;
+  // CHECK: icmp
+  gb = (VI == CF2)[0];
+}
+
+// CHECK-LABEL: @_Z10testFloatsDv2_d
+void testFloats(vector double VD) {
+  constexpr vector double CI1 = (vector double)0LL;
+  // CHECK: fcmp
+  gb = (VD == CI1)[0];
+
+  // Likewise for float inits.
+  constexpr vector double CI2 = (vector double)char(0);
+  // CHECK: fcmp
+  gb = (VD == CI2)[0];
+
+  constexpr vector double CF1 = (vector double)0.0;
+  // CHECK: fcmp
+  gb = (VD == CF1)[0];
+
+  constexpr vector double CF2 = (vector double)0.0f;
+  // CHECK: fcmp
+  gb = (VD == CF2)[0];
+}
index 410df3dd0cef33dcd4473b40995b3fc1f02939a5..805f9f5bab1511b995c018530775106e2eae82b9 100644 (file)
@@ -1,19 +1,51 @@
 // RUN: %clang_cc1 %s -triple arm64-apple-ios8.1.0 -std=c++11 -emit-llvm -o - | FileCheck %s
-// rdar://20000762
 
 typedef __attribute__((__ext_vector_type__(8))) float vector_float8;
 
 typedef vector_float8 float8;
 
-void MandelbrotPolyCalcSIMD8()
-{
-    constexpr float8   v4 = 4.0;  // value to compare against abs(z)^2, to see if bounded
-    float8 vABS;
-    auto vLT  = vABS < v4;
+// rdar://20000762
+// CHECK-LABEL: define void @_Z23MandelbrotPolyCalcSIMD8v
+void MandelbrotPolyCalcSIMD8() {
+  constexpr float8 v4 = 4.0;  // value to compare against abs(z)^2, to see if bounded
+  float8 vABS;
+  auto vLT  = vABS < v4;
+  // CHECK: store <8 x float>
+  // CHECK: [[ZERO:%.*]] = load <8 x float>, <8 x float>* [[VARBS:%.*]]
+  // CHECK: [[CMP:%.*]] = fcmp olt <8 x float> [[ZERO]]
+  // CHECK: [[SEXT:%.*]] = sext <8 x i1> [[CMP]] to <8 x i32>
+  // CHECK: store <8 x i32> [[SEXT]], <8 x i32>* [[VLT:%.*]]
 }
 
-// CHECK: store <8 x float> 
-// CHECK: [[ZERO:%.*]] = load <8 x float>, <8 x float>* [[VARBS:%.*]]
-// CHECK: [[CMP:%.*]] = fcmp olt <8 x float> [[ZERO]]
-// CHECK: [[SEXT:%.*]] = sext <8 x i1> [[CMP]] to <8 x i32>
-// CHECK: store <8 x i32> [[SEXT]], <8 x i32>* [[VLT:%.*]]
+typedef __attribute__((__ext_vector_type__(4))) int int4;
+typedef __attribute__((__ext_vector_type__(4))) float float4;
+typedef __attribute__((__ext_vector_type__(4))) __int128 bigint4;
+
+// CHECK-LABEL: define void @_Z14BoolConversionv
+void BoolConversion() {
+  // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+  int4 intsT = (int4)true;
+  // CHECK: store <4 x i32> zeroinitializer
+  int4 intsF = (int4)false;
+  // CHECK: store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>
+  float4 floatsT = (float4)true;
+  // CHECK: store <4 x float> zeroinitializer
+  float4 floatsF = (float4)false;
+  // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 -1, i128 -1>
+  bigint4 bigintsT = (bigint4)true;
+  // CHECK: store <4 x i128> zeroinitializer
+  bigint4 bigintsF = (bigint4)false;
+
+  // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>
+  constexpr int4 cIntsT = (int4)true;
+  // CHECK: store <4 x i32> zeroinitializer
+  constexpr int4 cIntsF = (int4)false;
+  // CHECK: store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>
+  constexpr float4 cFloatsT = (float4)true;
+  // CHECK: store <4 x float> zeroinitializer
+  constexpr float4 cFloatsF = (float4)false;
+  // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 -1, i128 -1>
+  constexpr bigint4 cBigintsT = (bigint4)true;
+  // CHECK: store <4 x i128> zeroinitializer
+  constexpr bigint4 cBigintsF = (bigint4)false;
+}
index d63431b1b7ca3cec68979bdf7e9a0d8b6b5ec150..8c86b06577d681339f73de7c1b007942d4eb2b53 100644 (file)
@@ -2,7 +2,9 @@
 
 typedef unsigned char uchar4 __attribute((ext_vector_type(4)));
 typedef unsigned int int4 __attribute((ext_vector_type(4)));
+typedef float float4 __attribute((ext_vector_type(4)));
 
+// CHECK-LABEL: define void @ker()
 void kernel ker() {
   bool t = true;
   int4 vec4 = (int4)t;
@@ -24,4 +26,8 @@ void kernel ker() {
   unsigned char c;
   c = (unsigned char)true;
 // CHECK: store i8 1, i8* %c, align 1
+
+  float4 vf;
+  vf = (float4)true;
+// CHECK: store <4 x float> <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>
 }