Improve optimizations for boolean values

LLVM doesn't handle i1 value in allocas/memory very well and skips a number of optimizations if it hits it. So we have to do the same thing that Clang does, using i1 for SSA values, but storing i8 in memory.

Fixes #15203.
`load_ty` returns an `undef` value for any zero-sized typed. But that value has the rust type, not the foreign type, so this would fail here.