Author: leonardchan Date: Tue Oct 23 10:55:35 2018 New Revision: 345063 URL: http://llvm.org/viewvc/llvm-project?rev=345063&view=rev Log: [Fixed Point Arithmetic] Fixed Point to Boolean Cast
This patch is a part of https://reviews.llvm.org/D48456 in an attempt to split the casting logic up into smaller patches. This contains the code for casting from fixed point types to boolean types. Differential Revision: https://reviews.llvm.org/D53308 Added: cfe/trunk/test/Frontend/fixed_point_to_bool.c Modified: cfe/trunk/include/clang/AST/OperationKinds.def cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprAgg.cpp cfe/trunk/lib/CodeGen/CGExprComplex.cpp cfe/trunk/lib/CodeGen/CGExprConstant.cpp cfe/trunk/lib/CodeGen/CGExprScalar.cpp cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp cfe/trunk/lib/Sema/Sema.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c Modified: cfe/trunk/include/clang/AST/OperationKinds.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OperationKinds.def?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/OperationKinds.def (original) +++ cfe/trunk/include/clang/AST/OperationKinds.def Tue Oct 23 10:55:35 2018 @@ -201,6 +201,10 @@ CAST_OPERATION(IntegralToFloating) /// (_Accum) 0.5r CAST_OPERATION(FixedPointCast) +/// CK_FixedPointToBoolean - Fixed point to boolean. +/// (bool) 0.5r +CAST_OPERATION(FixedPointToBoolean) + /// CK_FloatingToIntegral - Floating point to integral. Rounds /// towards zero, discarding any fractional component. /// (int) f Modified: cfe/trunk/lib/AST/Expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/AST/Expr.cpp (original) +++ cfe/trunk/lib/AST/Expr.cpp Tue Oct 23 10:55:35 2018 @@ -1661,6 +1661,7 @@ bool CastExpr::CastConsistency() const { case CK_LValueBitCast: // -> bool& case CK_UserDefinedConversion: // operator bool() case CK_BuiltinFnToFnPtr: + case CK_FixedPointToBoolean: CheckNoBasePath: assert(path_empty() && "Cast kind should not have a base path!"); break; Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Oct 23 10:55:35 2018 @@ -9590,6 +9590,14 @@ bool IntExprEvaluator::VisitCastExpr(con return Success(IntResult, E); } + case CK_FixedPointToBoolean: { + // Unsigned padding does not affect this. + APValue Val; + if (!Evaluate(Val, Info, SubExpr)) + return false; + return Success(Val.getInt().getBoolValue(), E); + } + case CK_IntegralCast: { if (!Visit(SubExpr)) return false; @@ -10090,6 +10098,7 @@ bool ComplexExprEvaluator::VisitCastExpr case CK_AddressSpaceConversion: case CK_IntToOCLSampler: case CK_FixedPointCast: + case CK_FixedPointToBoolean: llvm_unreachable("invalid cast kind for complex value"); case CK_LValueToRValue: Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Oct 23 10:55:35 2018 @@ -4154,6 +4154,7 @@ LValue CodeGenFunction::EmitCastLValue(c case CK_AddressSpaceConversion: case CK_IntToOCLSampler: case CK_FixedPointCast: + case CK_FixedPointToBoolean: return EmitUnsupportedLValue(E, "unexpected cast lvalue"); case CK_Dependent: Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Tue Oct 23 10:55:35 2018 @@ -851,6 +851,7 @@ void AggExprEmitter::VisitCastExpr(CastE case CK_AddressSpaceConversion: case CK_IntToOCLSampler: case CK_FixedPointCast: + case CK_FixedPointToBoolean: llvm_unreachable("cast kind invalid for aggregate types"); } } Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Tue Oct 23 10:55:35 2018 @@ -509,6 +509,7 @@ ComplexPairTy ComplexExprEmitter::EmitCa case CK_AddressSpaceConversion: case CK_IntToOCLSampler: case CK_FixedPointCast: + case CK_FixedPointToBoolean: llvm_unreachable("invalid cast kind for complex value"); case CK_FloatingRealToComplex: Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Oct 23 10:55:35 2018 @@ -870,6 +870,7 @@ public: case CK_FloatingToBoolean: case CK_FloatingCast: case CK_FixedPointCast: + case CK_FixedPointToBoolean: case CK_ZeroToOCLOpaqueType: return nullptr; } Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Oct 23 10:55:35 2018 @@ -1015,9 +1015,26 @@ Value *ScalarExprEmitter::EmitScalarConv QualType DstType, SourceLocation Loc, ScalarConversionOpts Opts) { - assert(!SrcType->isFixedPointType() && !DstType->isFixedPointType() && - "Use the ScalarExprEmitter::EmitFixedPoint family functions for " - "handling conversions involving fixed point types."); + // All conversions involving fixed point types should be handled by the + // EmitFixedPoint family functions. This is done to prevent bloating up this + // function more, and although fixed point numbers are represented by + // integers, we do not want to follow any logic that assumes they should be + // treated as integers. + // TODO(leonardchan): When necessary, add another if statement checking for + // conversions to fixed point types from other types. + if (SrcType->isFixedPointType()) { + if (DstType->isFixedPointType()) { + return EmitFixedPointConversion(Src, SrcType, DstType, Loc); + } else if (DstType->isBooleanType()) { + // We do not need to check the padding bit on unsigned types if unsigned + // padding is enabled because overflow into this bit is undefined + // behavior. + return Builder.CreateIsNotNull(Src); + } + + llvm_unreachable( + "Unhandled scalar conversion involving a fixed point type."); + } QualType NoncanonicalSrcType = SrcType; QualType NoncanonicalDstType = DstType; @@ -1998,8 +2015,15 @@ Value *ScalarExprEmitter::VisitCastExpr( } case CK_FixedPointCast: - return EmitFixedPointConversion(Visit(E), E->getType(), DestTy, - CE->getExprLoc()); + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc()); + + case CK_FixedPointToBoolean: + assert(E->getType()->isFixedPointType() && + "Expected src type to be fixed point type"); + assert(DestTy->isBooleanType() && "Expected dest type to be boolean type"); + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc()); case CK_IntegralCast: { ScalarConversionOpts Opts; Modified: cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp (original) +++ cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp Tue Oct 23 10:55:35 2018 @@ -1086,6 +1086,7 @@ static bool rewriteToNumericBoxedExpress llvm_unreachable("OpenCL-specific cast in Objective-C?"); case CK_FixedPointCast: + case CK_FixedPointToBoolean: llvm_unreachable("Fixed point types are disabled for Objective-C"); } } Modified: cfe/trunk/lib/Sema/Sema.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.cpp (original) +++ cfe/trunk/lib/Sema/Sema.cpp Tue Oct 23 10:55:35 2018 @@ -533,8 +533,7 @@ CastKind Sema::ScalarTypeToBooleanCastKi case Type::STK_Floating: return CK_FloatingToBoolean; case Type::STK_IntegralComplex: return CK_IntegralComplexToBoolean; case Type::STK_FloatingComplex: return CK_FloatingComplexToBoolean; - case Type::STK_FixedPoint: - llvm_unreachable("Unknown cast from FixedPoint to boolean"); + case Type::STK_FixedPoint: return CK_FixedPointToBoolean; } llvm_unreachable("unknown scalar type kind"); } Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Oct 23 10:55:35 2018 @@ -5894,10 +5894,7 @@ CastKind Sema::PrepareScalarCast(ExprRes case Type::STK_FixedPoint: return CK_FixedPointCast; case Type::STK_Bool: - Diag(Src.get()->getExprLoc(), - diag::err_unimplemented_conversion_with_fixed_point_type) - << DestTy; - return CK_IntegralToBoolean; + return CK_FixedPointToBoolean; case Type::STK_Integral: case Type::STK_Floating: case Type::STK_IntegralComplex: @@ -12793,12 +12790,6 @@ ExprResult Sema::CreateBuiltinUnaryOp(So if (Context.getLangOpts().CPlusPlus) { // C++03 [expr.unary.op]p8, C++0x [expr.unary.op]p9: // operand contextually converted to bool. - if (resultType->getScalarTypeKind() == Type::STK_FixedPoint) { - return ExprError( - Diag(Input.get()->getExprLoc(), - diag::err_unimplemented_conversion_with_fixed_point_type) - << resultType); - } Input = ImpCastExprToType(Input.get(), Context.BoolTy, ScalarTypeToBooleanCastKind(resultType)); } else if (Context.getLangOpts().OpenCL && Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Tue Oct 23 10:55:35 2018 @@ -415,7 +415,8 @@ void ExprEngine::VisitCast(const CastExp case CK_ZeroToOCLOpaqueType: case CK_IntToOCLSampler: case CK_LValueBitCast: - case CK_FixedPointCast: { + case CK_FixedPointCast: + case CK_FixedPointToBoolean: { state = handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred); continue; Added: cfe/trunk/test/Frontend/fixed_point_to_bool.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/fixed_point_to_bool.c?rev=345063&view=auto ============================================================================== --- cfe/trunk/test/Frontend/fixed_point_to_bool.c (added) +++ cfe/trunk/test/Frontend/fixed_point_to_bool.c Tue Oct 23 10:55:35 2018 @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s + +_Bool global_b = 1.0k; // @global_b = {{*.}}global i8 1, align 1 +_Bool global_b2 = 0.0k; // @global_b2 = {{*.}}global i8 0, align 1 + +void func() { + _Accum a = 0.5k; + unsigned _Accum ua = 0.5uk; + _Bool b; + + // CHECK: store i8 1, i8* %b, align 1 + // CHECK-NEXT: store i8 0, i8* %b, align 1 + // CHECK: store i8 1, i8* %b, align 1 + // CHECK-NEXT: store i8 0, i8* %b, align 1 + b = 0.5k; + b = 0.0k; + b = 0.5uk; + b = 0.0uk; + + // CHECK-NEXT: store i8 1, i8* %b, align 1 + // CHECK-NEXT: store i8 0, i8* %b, align 1 + // CHECK-NEXT: store i8 1, i8* %b, align 1 + // CHECK-NEXT: store i8 0, i8* %b, align 1 + b = (_Bool)0.5r; + b = (_Bool)0.0r; + b = (_Bool)0.5ur; + b = (_Bool)0.0ur; + + // CHECK-NEXT: [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4 + // CHECK-NEXT: [[NOTZERO:%[0-9]+]] = icmp ne i32 [[ACCUM]], 0 + // CHECK-NEXT: %frombool = zext i1 [[NOTZERO]] to i8 + // CHECK-NEXT: store i8 %frombool, i8* %b, align 1 + b = a; + + // CHECK-NEXT: [[ACCUM:%[0-9]+]] = load i32, i32* %ua, align 4 + // CHECK-NEXT: [[NOTZERO:%[0-9]+]] = icmp ne i32 [[ACCUM]], 0 + // CHECK-NEXT: %frombool1 = zext i1 [[NOTZERO]] to i8 + // CHECK-NEXT: store i8 %frombool1, i8* %b, align 1 + b = ua; + + // CHECK-NEXT: [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4 + // CHECK-NEXT: [[NOTZERO:%[0-9]+]] = icmp ne i32 [[ACCUM]], 0 + // CHECK-NEXT: br i1 [[NOTZERO]], label %if.then, label %if.end + if (a) { + } + + // CHECK: [[ACCUM:%[0-9]+]] = load i32, i32* %ua, align 4 + // CHECK-NEXT: [[NOTZERO:%[0-9]+]] = icmp ne i32 [[ACCUM]], 0 + // CHECK-NEXT: br i1 [[NOTZERO]], label %if.then{{[0-9]+}}, label %if.end{{[0-9]+}} + if (ua) { + } +} Modified: cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c?rev=345063&r1=345062&r2=345063&view=diff ============================================================================== --- cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c (original) +++ cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c Tue Oct 23 10:55:35 2018 @@ -35,7 +35,6 @@ void func() { accum_ptr = ptr; // expected-warning{{incompatible pointer types assigning to '_Accum *' from 'int *'}} accum = i2; // expected-error{{conversion between fixed point and 'int_t' (aka 'int') is not yet supported}} - b = accum; // expected-error{{conversion between fixed point and '_Bool' is not yet supported}} c = accum; // expected-error{{conversion between fixed point and 'char' is not yet supported}} i = accum; // expected-error{{conversion between fixed point and 'int' is not yet supported}} f = accum; // expected-error{{conversion between fixed point and 'float' is not yet supported}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits