ebevhan updated this revision to Diff 290266.
ebevhan added a comment.

Rebased.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86631/new/

https://reviews.llvm.org/D86631

Files:
  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

Index: clang/test/Frontend/fixed_point_unknown_conversions.c
===================================================================
--- clang/test/Frontend/fixed_point_unknown_conversions.c
+++ clang/test/Frontend/fixed_point_unknown_conversions.c
@@ -22,16 +22,12 @@
   _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'}}
Index: clang/test/Frontend/fixed_point_errors.c
===================================================================
--- clang/test/Frontend/fixed_point_errors.c
+++ clang/test/Frontend/fixed_point_errors.c
@@ -286,8 +286,3 @@
 
 // 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')}}
-}
Index: clang/test/Frontend/fixed_point_conversions_const.c
===================================================================
--- clang/test/Frontend/fixed_point_conversions_const.c
+++ clang/test/Frontend/fixed_point_conversions_const.c
@@ -43,6 +43,37 @@
 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
Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -418,6 +418,8 @@
       case CK_ZeroToOCLOpaqueType:
       case CK_IntToOCLSampler:
       case CK_LValueBitCast:
+      case CK_FloatingToFixedPoint:
+      case CK_FixedPointToFloating:
       case CK_FixedPointCast:
       case CK_FixedPointToBoolean:
       case CK_FixedPointToIntegral:
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -1124,11 +1124,17 @@
   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) {
@@ -7041,6 +7047,7 @@
     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(),
@@ -7113,10 +7120,7 @@
     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");
 
Index: clang/lib/Edit/RewriteObjCFoundationAPI.cpp
===================================================================
--- clang/lib/Edit/RewriteObjCFoundationAPI.cpp
+++ clang/lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -1085,6 +1085,8 @@
     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:
Index: clang/lib/CodeGen/CGExprScalar.cpp
===================================================================
--- clang/lib/CodeGen/CGExprScalar.cpp
+++ clang/lib/CodeGen/CGExprScalar.cpp
@@ -2241,6 +2241,8 @@
   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: {
Index: clang/lib/CodeGen/CGExprConstant.cpp
===================================================================
--- clang/lib/CodeGen/CGExprConstant.cpp
+++ clang/lib/CodeGen/CGExprConstant.cpp
@@ -1163,6 +1163,8 @@
     case CK_FloatingToIntegral:
     case CK_FloatingToBoolean:
     case CK_FloatingCast:
+    case CK_FloatingToFixedPoint:
+    case CK_FixedPointToFloating:
     case CK_FixedPointCast:
     case CK_FixedPointToBoolean:
     case CK_FixedPointToIntegral:
Index: clang/lib/CodeGen/CGExprComplex.cpp
===================================================================
--- clang/lib/CodeGen/CGExprComplex.cpp
+++ clang/lib/CodeGen/CGExprComplex.cpp
@@ -527,6 +527,8 @@
   case CK_ZeroToOCLOpaqueType:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
+  case CK_FloatingToFixedPoint:
+  case CK_FixedPointToFloating:
   case CK_FixedPointCast:
   case CK_FixedPointToBoolean:
   case CK_FixedPointToIntegral:
Index: clang/lib/CodeGen/CGExprAgg.cpp
===================================================================
--- clang/lib/CodeGen/CGExprAgg.cpp
+++ clang/lib/CodeGen/CGExprAgg.cpp
@@ -903,6 +903,8 @@
   case CK_ZeroToOCLOpaqueType:
 
   case CK_IntToOCLSampler:
+  case CK_FloatingToFixedPoint:
+  case CK_FixedPointToFloating:
   case CK_FixedPointCast:
   case CK_FixedPointToBoolean:
   case CK_FixedPointToIntegral:
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -4565,6 +4565,8 @@
   case CK_ARCExtendBlockObject:
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_IntToOCLSampler:
+  case CK_FloatingToFixedPoint:
+  case CK_FixedPointToFloating:
   case CK_FixedPointCast:
   case CK_FixedPointToBoolean:
   case CK_FixedPointToIntegral:
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -12818,6 +12818,8 @@
   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");
@@ -13062,6 +13064,26 @@
 
     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);
@@ -13368,6 +13390,15 @@
                                 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;
@@ -13513,6 +13544,8 @@
   case CK_NonAtomicToAtomic:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
+  case CK_FloatingToFixedPoint:
+  case CK_FixedPointToFloating:
   case CK_FixedPointCast:
   case CK_FixedPointToBoolean:
   case CK_FixedPointToIntegral:
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1764,6 +1764,8 @@
   case CK_ARCExtendBlockObject:
   case CK_ZeroToOCLOpaqueType:
   case CK_IntToOCLSampler:
+  case CK_FloatingToFixedPoint:
+  case CK_FixedPointToFloating:
   case CK_FixedPointCast:
   case CK_FixedPointToIntegral:
   case CK_IntegralToFixedPoint:
Index: clang/include/clang/AST/OperationKinds.def
===================================================================
--- clang/include/clang/AST/OperationKinds.def
+++ clang/include/clang/AST/OperationKinds.def
@@ -201,6 +201,14 @@
 ///    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)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to