mirror of https://github.com/microsoft/clang.git
[Bugfix] Fix ICE on constexpr vector splat.
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
This commit is contained in:
parent
05d274ca67
commit
2824a0744c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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?");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue