Unboxed Booleans
Right now the only way to compare two integers is with primops that produce boxed bools:
<# :: Int# -> Int# -> Bool
==# :: Int# -> Int# -> Bool
To consume the resulting Bool we need a case-expression, which introduces branches into the core IR and object code. Case expressions are bad in the presence of heavy inlining because case-of-case performed by the GHC simplifier tends to duplicate code (like in DPH and Repa programs). Mis-predicted branches are bad in object code because they stall the pipeline.
Consider the following expression:
case x <# 0# || x >=# aWidth
|| y <# 0# || y >=# aHeight of
True -> ...
False -> ...
This is very common in array programming. Ideally, it should turn into some straight-line code to compute the flag, and then a single branch instruction once we've worked out what alternative to take. However, as the only way to consume the Bools produced by the comparisons is to introduce more case expressions, we end up with *four* cases in the core IR.
What I want is this:
data Bool#
(.<#) :: Int# -> Int# -> Bool#
(.==#) :: Int# -> Int# -> Bool#
(.||#) :: Bool# -> Bool# -> Bool#
case x .<# 0# .||# x .>=# aWidth
.||# y .<# 0# .||# y .>=# aHeight of
True# -> ...
False# -> ...
Bool# is the type of one bit integers. I can compute with them algebraically and be sure that I'll get at most one branch instruction in the resulting object code.