This revision was automatically updated to reflect the committed changes.
Closed by commit rC345063: [Fixed Point Arithmetic] Fixed Point to Boolean Cast 
(authored by leonardchan, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D53308?vs=169863&id=170699#toc

Repository:
  rC Clang

https://reviews.llvm.org/D53308

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/Sema.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_to_bool.c
  test/Frontend/fixed_point_unknown_conversions.c

Index: include/clang/AST/OperationKinds.def
===================================================================
--- include/clang/AST/OperationKinds.def
+++ include/clang/AST/OperationKinds.def
@@ -201,6 +201,10 @@
 ///    (_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
Index: test/Frontend/fixed_point_to_bool.c
===================================================================
--- test/Frontend/fixed_point_to_bool.c
+++ test/Frontend/fixed_point_to_bool.c
@@ -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) {
+  }
+}
Index: test/Frontend/fixed_point_unknown_conversions.c
===================================================================
--- test/Frontend/fixed_point_unknown_conversions.c
+++ test/Frontend/fixed_point_unknown_conversions.c
@@ -35,7 +35,6 @@
   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}}
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -533,8 +533,7 @@
   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");
 }
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -5894,10 +5894,7 @@
     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 @@
       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 &&
Index: lib/Edit/RewriteObjCFoundationAPI.cpp
===================================================================
--- lib/Edit/RewriteObjCFoundationAPI.cpp
+++ lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -1086,6 +1086,7 @@
       llvm_unreachable("OpenCL-specific cast in Objective-C?");
 
     case CK_FixedPointCast:
+    case CK_FixedPointToBoolean:
       llvm_unreachable("Fixed point types are disabled for Objective-C");
     }
   }
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -1015,9 +1015,26 @@
                                                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 @@
   }
 
   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;
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -4154,6 +4154,7 @@
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
+  case CK_FixedPointToBoolean:
     return EmitUnsupportedLValue(E, "unexpected cast lvalue");
 
   case CK_Dependent:
Index: lib/CodeGen/CGExprAgg.cpp
===================================================================
--- lib/CodeGen/CGExprAgg.cpp
+++ lib/CodeGen/CGExprAgg.cpp
@@ -851,6 +851,7 @@
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
+  case CK_FixedPointToBoolean:
     llvm_unreachable("cast kind invalid for aggregate types");
   }
 }
Index: lib/CodeGen/CGExprConstant.cpp
===================================================================
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -870,6 +870,7 @@
     case CK_FloatingToBoolean:
     case CK_FloatingCast:
     case CK_FixedPointCast:
+    case CK_FixedPointToBoolean:
     case CK_ZeroToOCLOpaqueType:
       return nullptr;
     }
Index: lib/CodeGen/CGExprComplex.cpp
===================================================================
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -509,6 +509,7 @@
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
+  case CK_FixedPointToBoolean:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_FloatingRealToComplex:
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -415,7 +415,8 @@
       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;
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1661,6 +1661,7 @@
   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;
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -9590,6 +9590,14 @@
     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 @@
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
+  case CK_FixedPointToBoolean:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_LValueToRValue:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to