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.
I'd rather keep `Builder` a thin wrapper, without any special knowledge. What I could agree to would be passing a `Builder` instead of a `Block` to `load_ty()` and `store_ty()`. That would make them usable here. But that would make those two functions different from all the others that all take a `Block`. The remaining option is to change all the functions to take a builder instead of a block, which is something that appeals to me, but not within the scope of this PR.