[clang] 9fa7f48 - [Fixed Point] Add fixed-point to floating point cast types and consteval.
Bevin Hansson via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 13 04:43:53 PDT 2020
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'}}
More information about the cfe-commits
mailing list