[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-15 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: ebevhan, rjmccall, bjope.
leonardchan added a project: clang.

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.


Repository:
  rC Clang

https://reviews.llvm.org/D53308

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/Sema.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
  clang/test/Frontend/fixed_point_to_bool.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
@@ -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: clang/test/Frontend/fixed_point_to_bool.c
===
--- /dev/null
+++ clang/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: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -416,7 +416,8 @@
   case CK_ZeroToOCLQueue:
   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: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/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_In

[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-16 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/CodeGen/CGExprScalar.cpp:1032
+  // them.
+  return Builder.CreateIsNotNull(Src);
+}

Is this comment true? I don't think EmitFixedPointConversion does this.

Maybe I'm misinterpreting what it means.



Comment at: clang/lib/CodeGen/CGExprScalar.cpp:2023
+// We do not check the padding bit on unsigned types since they are zero'd
+// out on operations that can cause overflow into the bit.
+assert(E->getType()->isFixedPointType() &&

This comment is a duplicate of the one in EmitScalarConversion.



Comment at: clang/lib/Sema/Sema.cpp:537
   case Type::STK_FixedPoint:
-llvm_unreachable("Unknown cast from FixedPoint to boolean");
+return CK_FixedPointToBoolean;
   }

Put this on the line above directly after the case like the others.


Repository:
  rC Clang

https://reviews.llvm.org/D53308



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-16 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 169863.
leonardchan marked 3 inline comments as done.

Repository:
  rC Clang

https://reviews.llvm.org/D53308

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/Sema.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
  clang/test/Frontend/fixed_point_to_bool.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
@@ -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: clang/test/Frontend/fixed_point_to_bool.c
===
--- /dev/null
+++ clang/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: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -416,7 +416,8 @@
   case CK_ZeroToOCLQueue:
   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: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/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->getScal

[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-16 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: clang/lib/CodeGen/CGExprScalar.cpp:1032
+  // them.
+  return Builder.CreateIsNotNull(Src);
+}

ebevhan wrote:
> Is this comment true? I don't think EmitFixedPointConversion does this.
> 
> Maybe I'm misinterpreting what it means.
Ah sorry, this was my bad. I briefly forgot that we intended for overflow into 
the bit to be undefined behavior. In that case, this comment doesn't make sense 
and should be removed, but we still shouldn't have to clear/check the padding 
bit in this case because we should assume it's zero'd.

So this refers to handling when the padding bit needs to be cleared since if we 
ever have an operation that reads the whole int of an underlying unsigned type. 
I accidentally wrote this comment thinking that it would be cleared/zero'd at 
some point when we decided before that overflow into this padding was just 
undefined behavior. Updated the comment to reflect this.


Repository:
  rC Clang

https://reviews.llvm.org/D53308



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-18 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:9599
+  return false;
+return Success(Val.getInt().getBoolValue(), E);
+  }

I know you haven't really done constant-evaluation yet, but I think you should 
at least be setting up operations like this correctly:

1. There should be an `EvaluateFixedPoint` function that evaluates an 
expression as a fixed-point value, just like `EvaluateFloat` and the others, 
which can be structured to use `FixedPointExprEvaluator`.
2. There should be a `getBoolValue` method on `APFixedPoint`.



Comment at: clang/lib/CodeGen/CGExprScalar.cpp:2026
+return EmitScalarConversion(Visit(E), E->getType(), DestTy,
+CE->getExprLoc());
 

Why are you pushing these casts through `EmitScalarConversion` when the cast 
kind already tells you which operation you're doing?


Repository:
  rC Clang

https://reviews.llvm.org/D53308



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-22 Thread Bevin Hansson via Phabricator via cfe-commits
ebevhan added inline comments.



Comment at: clang/lib/CodeGen/CGExprScalar.cpp:2026
+return EmitScalarConversion(Visit(E), E->getType(), DestTy,
+CE->getExprLoc());
 

rjmccall wrote:
> Why are you pushing these casts through `EmitScalarConversion` when the cast 
> kind already tells you which operation you're doing?
It could be useful to enable EmitScalarConversion to handle any of the 
conversions so it can be used in other contexts than expanding a cast.


Repository:
  rC Clang

https://reviews.llvm.org/D53308



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-22 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: clang/lib/CodeGen/CGExprScalar.cpp:2026
+return EmitScalarConversion(Visit(E), E->getType(), DestTy,
+CE->getExprLoc());
 

ebevhan wrote:
> rjmccall wrote:
> > Why are you pushing these casts through `EmitScalarConversion` when the 
> > cast kind already tells you which operation you're doing?
> It could be useful to enable EmitScalarConversion to handle any of the 
> conversions so it can be used in other contexts than expanding a cast.
> It could be useful to enable EmitScalarConversion to handle any of the 
> conversions so it can be used in other contexts than expanding a cast.

This was also the reason I did this since `EmitScalarConversion` seems to get 
called in many places as a generic dispatch for different conversions.


Repository:
  rC Clang

https://reviews.llvm.org/D53308



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-23 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.
This revision is now accepted and ready to land.

LGTM.




Comment at: clang/lib/CodeGen/CGExprScalar.cpp:2026
+return EmitScalarConversion(Visit(E), E->getType(), DestTy,
+CE->getExprLoc());
 

leonardchan wrote:
> ebevhan wrote:
> > rjmccall wrote:
> > > Why are you pushing these casts through `EmitScalarConversion` when the 
> > > cast kind already tells you which operation you're doing?
> > It could be useful to enable EmitScalarConversion to handle any of the 
> > conversions so it can be used in other contexts than expanding a cast.
> > It could be useful to enable EmitScalarConversion to handle any of the 
> > conversions so it can be used in other contexts than expanding a cast.
> 
> This was also the reason I did this since `EmitScalarConversion` seems to get 
> called in many places as a generic dispatch for different conversions.
I think we do that in a very restricted set of places, like compound assignment 
operators, and honestly they should be changed so that they store the final 
cast kind.  But I suppose I can't ask you to fight the current system.


Repository:
  rC Clang

https://reviews.llvm.org/D53308



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-23 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:9599
+  return false;
+return Success(Val.getInt().getBoolValue(), E);
+  }

rjmccall wrote:
> I know you haven't really done constant-evaluation yet, but I think you 
> should at least be setting up operations like this correctly:
> 
> 1. There should be an `EvaluateFixedPoint` function that evaluates an 
> expression as a fixed-point value, just like `EvaluateFloat` and the others, 
> which can be structured to use `FixedPointExprEvaluator`.
> 2. There should be a `getBoolValue` method on `APFixedPoint`.
I will add these in another patch since this has LGTM.


Repository:
  rC Clang

https://reviews.llvm.org/D53308



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53308: [Fixed Point Arithmetic] Fixed Point to Boolean Cast

2018-10-23 Thread Leonard Chan via Phabricator via cfe-commits
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