leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch contains changes and a test for checking that fixed point types can 
be converted between all other valid types. Fixed point types can be converted 
between floating point types, integral types, and other fixed point types.

This is a child of https://reviews.llvm.org/D46963


Repository:
  rC Clang

https://reviews.llvm.org/D46979

Files:
  include/clang/AST/OperationKinds.def
  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/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_all_conversions.c

Index: test/Frontend/fixed_point_all_conversions.c
===================================================================
--- /dev/null
+++ test/Frontend/fixed_point_all_conversions.c
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -Werror %s
+
+// Test for conversions between fixed point types and all other valid types.
+
+// Conversion from one type to another type
+#define CONVERT(FROM_TYPE, FROM_ID, TO_TYPE, TO_ID) \
+  TO_TYPE FROM_ID ## _to_ ## TO_ID (FROM_TYPE x) { return x; }
+
+// Conversion between 2 types
+#define CONVERT_COMBINATION(TYPE1, ID1, TYPE2, ID2) \
+  CONVERT(TYPE1, ID1, TYPE2, ID2) \
+  CONVERT(TYPE2, ID2, TYPE1, ID1)
+
+// Conversion between one type and floating point types
+#define CONVERT_BETWEEN_FLOATS(TYPE, ID) \
+  CONVERT_COMBINATION(TYPE, ID, float, Float) \
+  CONVERT_COMBINATION(TYPE, ID, double, Double)
+
+// Conversion between one type and an integral type with differant signage
+#define CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, INT_TYPE, INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, INT_TYPE, INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, signed INT_TYPE, Signed ## INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, unsigned INT_TYPE, Unsigned ## INT_ID)
+
+// Conversion between one type and all integral types
+#define CONVERT_BETWEEN_INTEGRALS(TYPE, ID) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, char, Char) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, short, Short) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, int, Int) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long, Long) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long long, LongLong)
+
+// Conversion between one type and a fixed point type with different saturation
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_COMBINATION(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_COMBINATION(TYPE, ID, _Sat FIXED_TYPE, Sat ## FIXED_ID)
+
+// Conversion between one type and a fixed point type with different signage
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, signed FIXED_TYPE, Signed ## FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, unsigned FIXED_TYPE, Unsigned ## FIXED_ID)
+
+// Convert between one type and all fixed point types.
+// Add "Type" to the end of the ID to avoid multiple definitions of a function
+// if the Type is a fixed point type.
+#define CONVERT_BETWEEN_FIXED_POINT(TYPE, ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Fract, FractType) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Accum, AccumType)
+
+// Convert between one type and all other types
+#define CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+  CONVERT_BETWEEN_FLOATS(TYPE, ID) \
+  CONVERT_BETWEEN_INTEGRALS(TYPE, ID) \
+  CONVERT_BETWEEN_FIXED_POINT(TYPE, ID)
+
+#define CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+  CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+  CONVERT_BETWEEN_ALL_TYPES(_Sat TYPE, Sat ## ID)
+
+#define CONVERT_FIXED_POINT_TYPE(TYPE, ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(signed TYPE, Signed ## ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(unsigned TYPE, Unsigned ## ID)
+
+CONVERT_FIXED_POINT_TYPE(short _Fract, ShortFract);
+CONVERT_FIXED_POINT_TYPE(_Fract, Fract);
+CONVERT_FIXED_POINT_TYPE(long _Fract, LongFract);
+
+CONVERT_FIXED_POINT_TYPE(short _Accum, ShortAccum);
+CONVERT_FIXED_POINT_TYPE(_Accum, Accum);
+CONVERT_FIXED_POINT_TYPE(long _Accum, LongAccum);
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -321,6 +321,7 @@
     const LocationContext *LCtx = Pred->getLocationContext();
 
     switch (CastE->getCastKind()) {
+      case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
       case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
       case CK_IntegralToFixedPoint: llvm_unreachable("ExprEngine::VisitCast CK_IntegralToFixedPoint"); // TODO
       case CK_FixedPointCast: llvm_unreachable("CK_FixedPointCast"); // TODO
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -6055,16 +6055,17 @@
   case Type::STK_FixedPoint: {
     switch (DestTy->getScalarTypeKind()) {
       default: llvm_unreachable("Unable to convert from fixed point type");
-      case Type::STK_Integral: llvm_unreachable("Unimplemented scalar cast from fixed point to int");  // TODO
+      case Type::STK_Integral: return CK_IntegralToFixedPoint;
       case Type::STK_Floating: return CK_FixedPointToFloating;
       case Type::STK_FixedPoint: return CK_FixedPointCast;
     }
   }
 
   case Type::STK_Bool: // casting from bool is like casting from an integer
   case Type::STK_Integral:
     switch (DestTy->getScalarTypeKind()) {
-    case Type::STK_FixedPoint: llvm_unreachable("Sema::PrepareScalarCast from STK_Integral to STK_FixedPoint");  // TODO
+    case Type::STK_FixedPoint:
+      return CK_IntegralToFixedPoint;
     case Type::STK_CPointer:
     case Type::STK_ObjCObjectPointer:
     case Type::STK_BlockPointer:
@@ -6095,7 +6096,8 @@
 
   case Type::STK_Floating:
     switch (DestTy->getScalarTypeKind()) {
-    case Type::STK_FixedPoint: llvm_unreachable("Sema::PrepareScalarCast from STK_Floating to STK_FixedPoint");  // TODO
+    case Type::STK_FixedPoint:
+      return CK_FloatingToFixedPoint;
     case Type::STK_Floating:
       return CK_FloatingCast;
     case Type::STK_Bool:
Index: lib/Edit/RewriteObjCFoundationAPI.cpp
===================================================================
--- lib/Edit/RewriteObjCFoundationAPI.cpp
+++ lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -1005,6 +1005,7 @@
     case CK_IntegralToFixedPoint: llvm_unreachable("rewriteToNumericBoxedExpression CK_IntegralToFixedPoint"); // TODO
     case CK_FixedPointCast: llvm_unreachable("rewriteToNumericBoxedExpression CK_FixedPointCast"); // TODO
     case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
+    case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
     case CK_LValueToRValue:
     case CK_NoOp:
     case CK_UserDefinedConversion:
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -1691,6 +1691,7 @@
   // a default case, so the compiler will warn on a missing case.  The cases
   // are in the same order as in the CastKind enum.
   switch (Kind) {
+  case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
   case CK_BuiltinFnToFnPtr:
     llvm_unreachable("builtin functions are handled elsewhere");
Index: lib/CodeGen/CGExprConstant.cpp
===================================================================
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -687,6 +687,7 @@
 
     switch (E->getCastKind()) {
     case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
+    case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
     case CK_FixedPointCast: llvm_unreachable("CK_FixedPointCast"); // TODO
     case CK_IntegralToFixedPoint: llvm_unreachable("VisitCastExpr CK_IntegralToFixedPoint"); // TODO
     case CK_ToUnion: {
Index: lib/CodeGen/CGExprComplex.cpp
===================================================================
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -449,6 +449,7 @@
   case CK_IntegralToFixedPoint: llvm_unreachable("ComplexExprEmitter::EmitCast CK_IntegralToFixedPoint"); // TODO
   case CK_FixedPointCast: llvm_unreachable("CK_FixedPointCast"); // TODO
   case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
+  case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
 
   // Atomic to non-atomic casts may be more than a no-op for some platforms and
Index: lib/CodeGen/CGExprAgg.cpp
===================================================================
--- lib/CodeGen/CGExprAgg.cpp
+++ lib/CodeGen/CGExprAgg.cpp
@@ -671,6 +671,7 @@
   if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
     CGF.CGM.EmitExplicitCastExprType(ECE, &CGF);
   switch (E->getCastKind()) {
+  case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
   case CK_FixedPointCast: llvm_unreachable("CK_FixedPointCast"); // TODO
   case CK_IntegralToFixedPoint: llvm_unreachable("AggExprEmitter::VisitCastExpr CK_IntegralToFixedPoint"); // TODO
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -4045,6 +4045,7 @@
 LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
   switch (E->getCastKind()) {
   case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
+  case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_IntegralToFixedPoint: llvm_unreachable("CodeGenFunction::EmitCastLValue CK_IntegralToFixedPoint"); // TODO
   case CK_FixedPointCast: llvm_unreachable("CK_FixedPointCast"); // TODO
   case CK_ToVoid:
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -9163,6 +9163,7 @@
   QualType SrcType = SubExpr->getType();
 
   switch (E->getCastKind()) {
+  case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
   case CK_FixedPointCast: llvm_unreachable("CK_FixedPointCast"); // TODO
   case CK_IntegralToFixedPoint: llvm_unreachable("IntExprEvaluator::VisitCastExpr CK_IntegralToFixedPoint"); // TODO
@@ -9760,6 +9761,7 @@
 
   switch (E->getCastKind()) {
   case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
+  case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_IntegralToFixedPoint: llvm_unreachable("ComplexExprEvaluator::VisitCastExpr CK_IntegralToFixedPoint"); // TODO
   case CK_FixedPointCast: llvm_unreachable("CK_FixedPointCast"); // TODO
   case CK_BitCast:
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1654,6 +1654,7 @@
   case CK_IntegralToFixedPoint:
   case CK_FixedPointCast:
   case CK_FixedPointToFloating:
+  case CK_FloatingToFixedPoint:
     assert(!getType()->isBooleanType() && "unheralded conversion to bool");
     goto CheckNoBasePath;
 
Index: include/clang/AST/OperationKinds.def
===================================================================
--- include/clang/AST/OperationKinds.def
+++ include/clang/AST/OperationKinds.def
@@ -210,6 +210,11 @@
 ///    (float) 2.5hk
 CAST_OPERATION(FixedPointToFloating)
 
+/// CK_FloatingToFixedPoint - Floating point to fixed point.  Rounds
+/// towards zero, discarding any fractional component.
+///    (short _Accum) f
+CAST_OPERATION(FloatingToFixedPoint)
+
 /// CK_FloatingToIntegral - Floating point to integral.  Rounds
 /// towards zero, discarding any fractional component.
 ///    (int) f
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D46979: [Fixed Point ... Leonard Chan via Phabricator via cfe-commits

Reply via email to