New __builtin_unreachable() builtin
-----------------------------------
LLVM C front-ends (llvm-gcc and clang) should support a new
__builtin_unreachable() builtin that maps to the LLVM 'unreachable'
instruction. This builtin was added to GCC mainline, and was
discovered to have several nice properties:
1. This was added to GCC mainline originally to support the Linux
kernel, which has a BUG() macro that expands to inline assembly
that aborts. Using "asm(...); __builtin_unreachable();" tells the
compiler that the asm can't return, which shrinks code a bit.
2. Having this allows us to expose arbitrary value constraints in
LLVM IR. For example, with something like this in LLVM IR:
if (cond) __builtin_unreachable();
we know that cond is never true. A contrived example, is that
we should be able to optimize something like this to "return 1":
int test(char *f) {
if (f)
__builtin_unreachable();
return f ? 1 : 0;
}
This allows us to get the benefits of __builtin_assume() (PR810)
with a much simpler framework.
3. In a C context, we could make the assert macro expand into:
if (!cond) __builtin_unrechable();
when building in NDEBUG mode. This has two advantages: first
if the condition has side effects (noone would ever do this,
right??) then building in NDEBUG mode won't break the app.
Second, the optimizer will be able to use the information from
the assertion, per #2.
The trick to implementing this is that we don't want the optimizer
to turn conditional branches with one edge to an unreachable into
an unconditional branch. It should keep the branch (and the arbitrarily
complex conditional feeding it) until CodeGenPrepare time. CGP should
then fold the branch and delete the condition feeding the branch where
possible.