Author: Bevin Hansson Date: 2020-10-13T13:26:56+02:00 New Revision: 9fa7f48459761fa13205f4c931484b0977c35746
URL: https://github.com/llvm/llvm-project/commit/9fa7f48459761fa13205f4c931484b0977c35746 DIFF: https://github.com/llvm/llvm-project/commit/9fa7f48459761fa13205f4c931484b0977c35746.diff LOG: [Fixed Point] Add fixed-point to floating point cast types and consteval. Reviewed By: leonardchan Differential Revision: https://reviews.llvm.org/D86631 Added: Modified: clang/include/clang/AST/OperationKinds.def clang/lib/AST/Expr.cpp clang/lib/AST/ExprConstant.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprAgg.cpp clang/lib/CodeGen/CGExprComplex.cpp clang/lib/CodeGen/CGExprConstant.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/Edit/RewriteObjCFoundationAPI.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp clang/test/Frontend/fixed_point_conversions_const.c clang/test/Frontend/fixed_point_errors.c clang/test/Frontend/fixed_point_unknown_conversions.c Removed: ################################################################################ diff --git a/clang/include/clang/AST/OperationKinds.def b/clang/include/clang/AST/OperationKinds.def index f29664e8eb33..6daab1ffcb0a 100644 --- a/clang/include/clang/AST/OperationKinds.def +++ b/clang/include/clang/AST/OperationKinds.def @@ -201,6 +201,14 @@ CAST_OPERATION(IntegralToBoolean) /// float f = i; CAST_OPERATION(IntegralToFloating) +/// CK_FloatingToFixedPoint - Floating to fixed point. +/// _Accum a = f; +CAST_OPERATION(FloatingToFixedPoint) + +/// CK_FixedPointToFloating - Fixed point to floating. +/// (float) 2.5k +CAST_OPERATION(FixedPointToFloating) + /// CK_FixedPointCast - Fixed point to fixed point. /// (_Accum) 0.5r CAST_OPERATION(FixedPointCast) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 8e8dd75e975a..919d3220875c 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1691,6 +1691,8 @@ bool CastExpr::CastConsistency() const { case CK_ARCExtendBlockObject: case CK_ZeroToOCLOpaqueType: case CK_IntToOCLSampler: + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: case CK_FixedPointCast: case CK_FixedPointToIntegral: case CK_IntegralToFixedPoint: diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 639a5733b34b..1327aa6876e4 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -12896,6 +12896,8 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { case CK_NonAtomicToAtomic: case CK_AddressSpaceConversion: case CK_IntToOCLSampler: + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: case CK_FixedPointCast: case CK_IntegralToFixedPoint: llvm_unreachable("invalid cast kind for integral value"); @@ -13140,6 +13142,26 @@ bool FixedPointExprEvaluator::VisitCastExpr(const CastExpr *E) { return Success(IntResult, E); } + case CK_FloatingToFixedPoint: { + APFloat Src(0.0); + if (!EvaluateFloat(SubExpr, Src, Info)) + return false; + + bool Overflowed; + APFixedPoint Result = APFixedPoint::getFromFloatValue( + Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed); + + if (Overflowed) { + if (Info.checkingForUndefinedBehavior()) + Info.Ctx.getDiagnostics().Report(E->getExprLoc(), + diag::warn_fixedpoint_constant_overflow) + << Result.toString() << E->getType(); + else if (!HandleOverflow(Info, E, Result, E->getType())) + return false; + } + + return Success(Result, E); + } case CK_NoOp: case CK_LValueToRValue: return ExprEvaluatorBaseTy::VisitCastExpr(E); @@ -13446,6 +13468,15 @@ bool FloatExprEvaluator::VisitCastExpr(const CastExpr *E) { E->getType(), Result); } + case CK_FixedPointToFloating: { + APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->getType())); + if (!EvaluateFixedPoint(SubExpr, FixResult, Info)) + return false; + Result = + FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->getType())); + return true; + } + case CK_FloatingCast: { if (!Visit(SubExpr)) return false; @@ -13591,6 +13622,8 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) { case CK_NonAtomicToAtomic: case CK_AddressSpaceConversion: case CK_IntToOCLSampler: + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: case CK_FixedPointCast: case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 869bace18ffc..2f54097d9209 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4593,6 +4593,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { case CK_ARCExtendBlockObject: case CK_CopyAndAutoreleaseBlockObject: case CK_IntToOCLSampler: + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: case CK_FixedPointCast: case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index fb96d70732e8..208157699981 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -903,6 +903,8 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { case CK_ZeroToOCLOpaqueType: case CK_IntToOCLSampler: + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: case CK_FixedPointCast: case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index a49817898ae3..5b2a0bb4700c 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -527,6 +527,8 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, case CK_ZeroToOCLOpaqueType: case CK_AddressSpaceConversion: case CK_IntToOCLSampler: + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: case CK_FixedPointCast: case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index bff4a0c38af9..57f1ad59a72a 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1163,6 +1163,8 @@ class ConstExprEmitter : case CK_FloatingToIntegral: case CK_FloatingToBoolean: case CK_FloatingCast: + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: case CK_FixedPointCast: case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index cee2210e74c1..f14f862a5f67 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2241,6 +2241,8 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { case CK_IntegralToFloating: case CK_FloatingToIntegral: case CK_FloatingCast: + case CK_FixedPointToFloating: + case CK_FloatingToFixedPoint: return EmitScalarConversion(Visit(E), E->getType(), DestTy, CE->getExprLoc()); case CK_BooleanToSignedIntegral: { diff --git a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp index 6f4a880b649a..7565626cba99 100644 --- a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp +++ b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp @@ -1085,6 +1085,8 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg, case CK_BooleanToSignedIntegral: llvm_unreachable("OpenCL-specific cast in Objective-C?"); + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: case CK_FixedPointCast: case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f0cb227ff58e..a02db2293bcc 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1126,11 +1126,17 @@ static QualType handleFloatConversion(Sema &S, ExprResult &LHS, bool LHSFloat = LHSType->isRealFloatingType(); bool RHSFloat = RHSType->isRealFloatingType(); - // FIXME: Implement floating to fixed point conversion.(Bug 46268) - // Reference N1169 4.1.4 (Type conversion, usual arithmetic conversions). - if ((LHSType->isFixedPointType() && RHSFloat) || - (LHSFloat && RHSType->isFixedPointType())) - return QualType(); + // N1169 4.1.4: If one of the operands has a floating type and the other + // operand has a fixed-point type, the fixed-point operand + // is converted to the floating type [...] + if (LHSType->isFixedPointType() || RHSType->isFixedPointType()) { + if (LHSFloat) + RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FixedPointToFloating); + else if (!IsCompAssign) + LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FixedPointToFloating); + return LHSFloat ? LHSType : RHSType; + } + // If we have two real floating types, convert the smaller operand // to the bigger result. if (LHSFloat && RHSFloat) { @@ -7000,6 +7006,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_Integral: return CK_FixedPointToIntegral; case Type::STK_Floating: + return CK_FixedPointToFloating; case Type::STK_IntegralComplex: case Type::STK_FloatingComplex: Diag(Src.get()->getExprLoc(), @@ -7072,10 +7079,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); case Type::STK_FixedPoint: - Diag(Src.get()->getExprLoc(), - diag::err_unimplemented_conversion_with_fixed_point_type) - << SrcTy; - return CK_IntegralCast; + return CK_FloatingToFixedPoint; } llvm_unreachable("Should have returned before this"); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 507400c705b9..18d1b2169eed 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -418,6 +418,8 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, case CK_ZeroToOCLOpaqueType: case CK_IntToOCLSampler: case CK_LValueBitCast: + case CK_FloatingToFixedPoint: + case CK_FixedPointToFloating: case CK_FixedPointCast: case CK_FixedPointToBoolean: case CK_FixedPointToIntegral: diff --git a/clang/test/Frontend/fixed_point_conversions_const.c b/clang/test/Frontend/fixed_point_conversions_const.c index 7d63d4d63879..30aefbd564f3 100644 --- a/clang/test/Frontend/fixed_point_conversions_const.c +++ b/clang/test/Frontend/fixed_point_conversions_const.c @@ -43,6 +43,37 @@ short _Accum sa_const6 = -2; short _Accum sa_const7 = -256; // CHECK-DAG: @sa_const7 = {{.*}}global i16 -32768, align 2 +// Fixed point to floating point +float fl_const = 1.0hk; +// CHECK-DAG: @fl_const = {{.*}}global float 1.000000e+00, align 4 +float fl_const2 = -128.0k; +// CHECK-DAG: @fl_const2 = {{.*}}global float -1.280000e+02, align 4 +float fl_const3 = 0.0872802734375k; +// CHECK-DAG: @fl_const3 = {{.*}}global float 0x3FB6580000000000, align 4 +float fl_const4 = 192.5k; +// CHECK-DAG: @fl_const4 = {{.*}}global float 1.925000e+02, align 4 +float fl_const5 = -192.5k; +// CHECK-DAG: @fl_const5 = {{.*}}global float -1.925000e+02, align 4 + +// Floating point to fixed point +_Accum a_fl_const = 1.0f; +// CHECK-DAG: @a_fl_const = {{.*}}global i32 32768, align 4 +_Accum a_fl_const2 = -128.0f; +// CHECK-DAG: @a_fl_const2 = {{.*}}global i32 -4194304, align 4 +_Accum a_fl_const3 = 0.0872802734375f; +// CHECK-DAG: @a_fl_const3 = {{.*}}global i32 2860, align 4 +_Accum a_fl_const4 = 0.0872802734375; +// CHECK-DAG: @a_fl_const4 = {{.*}}global i32 2860, align 4 +_Accum a_fl_const5 = -0.0872802734375f; +// CHECK-DAG: @a_fl_const5 = {{.*}}global i32 -2860, align 4 +_Fract f_fl_const = 0.5f; +// CHECK-DAG: @f_fl_const = {{.*}}global i16 16384, align 2 +_Fract f_fl_const2 = -0.75; +// CHECK-DAG: @f_fl_const2 = {{.*}}global i16 -24576, align 2 +unsigned short _Accum usa_fl_const = 48.75f; +// SIGNED-DAG: @usa_fl_const = {{.*}}global i16 12480, align 2 +// UNSIGNED-DAG: @usa_fl_const = {{.*}}global i16 6240, align 2 + // Signedness unsigned short _Accum usa_const2 = 2.5hk; // SIGNED-DAG: @usa_const2 = {{.*}}global i16 640, align 2 diff --git a/clang/test/Frontend/fixed_point_errors.c b/clang/test/Frontend/fixed_point_errors.c index 5aaf59876dcb..6c41bf6df163 100644 --- a/clang/test/Frontend/fixed_point_errors.c +++ b/clang/test/Frontend/fixed_point_errors.c @@ -286,8 +286,3 @@ short _Accum shl_sat = (_Sat short _Accum)200.0hk << 5; // Division by zero short _Accum div_zero = 4.5k / 0.0lr; // expected-error {{initializer element is not a compile-time constant}} - -void foo(void) { - _Accum x = 0.5k; - if (x == 0.5) {} // expected-error{{invalid operands to binary expression ('_Accum' and 'double')}} -} diff --git a/clang/test/Frontend/fixed_point_unknown_conversions.c b/clang/test/Frontend/fixed_point_unknown_conversions.c index c6a02e903890..8595901f9e9c 100644 --- a/clang/test/Frontend/fixed_point_unknown_conversions.c +++ b/clang/test/Frontend/fixed_point_unknown_conversions.c @@ -22,16 +22,12 @@ void func() { _Fract fract = accum; // ok _Accum *accum_ptr; - accum = f; // expected-error{{conversion between fixed point and 'float' is not yet supported}} - accum = d; // expected-error{{conversion between fixed point and 'double' is not yet supported}} accum = dc; // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}} accum = ic; // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}} accum = s; // expected-error{{assigning to '_Accum' from incompatible type 'struct S'}} accum = ptr; // expected-error{{assigning to '_Accum' from incompatible type 'int *'}} accum_ptr = ptr; // expected-warning{{incompatible pointer types assigning to '_Accum *' from 'int *'}} - f = accum; // expected-error{{conversion between fixed point and 'float' is not yet supported}} - d = accum; // expected-error{{conversion between fixed point and 'double' is not yet supported}} dc = accum; // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}} ic = accum; // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}} s = accum; // expected-error{{assigning to 'struct S' from incompatible type '_Accum'}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits