r345063 - [Fixed Point Arithmetic] Fixed Point to Boolean Cast

Leonard Chan via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 23 10:55:35 PDT 2018


Author: leonardchan
Date: Tue Oct 23 10:55:35 2018
New Revision: 345063

URL: http://llvm.org/viewvc/llvm-project?rev=345063&view=rev
Log:
[Fixed Point Arithmetic] Fixed Point to Boolean Cast

This patch is a part of https://reviews.llvm.org/D48456 in an attempt to split
the casting logic up into smaller patches. This contains the code for casting
from fixed point types to boolean types.

Differential Revision: https://reviews.llvm.org/D53308

Added:
    cfe/trunk/test/Frontend/fixed_point_to_bool.c
Modified:
    cfe/trunk/include/clang/AST/OperationKinds.def
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprComplex.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
    cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c

Modified: cfe/trunk/include/clang/AST/OperationKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OperationKinds.def?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OperationKinds.def (original)
+++ cfe/trunk/include/clang/AST/OperationKinds.def Tue Oct 23 10:55:35 2018
@@ -201,6 +201,10 @@ CAST_OPERATION(IntegralToFloating)
 ///    (_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

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Oct 23 10:55:35 2018
@@ -1661,6 +1661,7 @@ bool CastExpr::CastConsistency() const {
   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;

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Oct 23 10:55:35 2018
@@ -9590,6 +9590,14 @@ bool IntExprEvaluator::VisitCastExpr(con
     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 @@ bool ComplexExprEvaluator::VisitCastExpr
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
+  case CK_FixedPointToBoolean:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_LValueToRValue:

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Oct 23 10:55:35 2018
@@ -4154,6 +4154,7 @@ LValue CodeGenFunction::EmitCastLValue(c
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
+  case CK_FixedPointToBoolean:
     return EmitUnsupportedLValue(E, "unexpected cast lvalue");
 
   case CK_Dependent:

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Tue Oct 23 10:55:35 2018
@@ -851,6 +851,7 @@ void AggExprEmitter::VisitCastExpr(CastE
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
+  case CK_FixedPointToBoolean:
     llvm_unreachable("cast kind invalid for aggregate types");
   }
 }

Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Tue Oct 23 10:55:35 2018
@@ -509,6 +509,7 @@ ComplexPairTy ComplexExprEmitter::EmitCa
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
   case CK_FixedPointCast:
+  case CK_FixedPointToBoolean:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_FloatingRealToComplex:

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Oct 23 10:55:35 2018
@@ -870,6 +870,7 @@ public:
     case CK_FloatingToBoolean:
     case CK_FloatingCast:
     case CK_FixedPointCast:
+    case CK_FixedPointToBoolean:
     case CK_ZeroToOCLOpaqueType:
       return nullptr;
     }

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Oct 23 10:55:35 2018
@@ -1015,9 +1015,26 @@ Value *ScalarExprEmitter::EmitScalarConv
                                                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 @@ Value *ScalarExprEmitter::VisitCastExpr(
   }
 
   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;

Modified: cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp (original)
+++ cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp Tue Oct 23 10:55:35 2018
@@ -1086,6 +1086,7 @@ static bool rewriteToNumericBoxedExpress
       llvm_unreachable("OpenCL-specific cast in Objective-C?");
 
     case CK_FixedPointCast:
+    case CK_FixedPointToBoolean:
       llvm_unreachable("Fixed point types are disabled for Objective-C");
     }
   }

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Tue Oct 23 10:55:35 2018
@@ -533,8 +533,7 @@ CastKind Sema::ScalarTypeToBooleanCastKi
   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");
 }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Oct 23 10:55:35 2018
@@ -5894,10 +5894,7 @@ CastKind Sema::PrepareScalarCast(ExprRes
     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 @@ ExprResult Sema::CreateBuiltinUnaryOp(So
       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 &&

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Tue Oct 23 10:55:35 2018
@@ -415,7 +415,8 @@ void ExprEngine::VisitCast(const CastExp
       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;

Added: cfe/trunk/test/Frontend/fixed_point_to_bool.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/fixed_point_to_bool.c?rev=345063&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/fixed_point_to_bool.c (added)
+++ cfe/trunk/test/Frontend/fixed_point_to_bool.c Tue Oct 23 10:55:35 2018
@@ -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) {
+  }
+}

Modified: cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c?rev=345063&r1=345062&r2=345063&view=diff
==============================================================================
--- cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c (original)
+++ cfe/trunk/test/Frontend/fixed_point_unknown_conversions.c Tue Oct 23 10:55:35 2018
@@ -35,7 +35,6 @@ void func() {
   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}}




More information about the cfe-commits mailing list