Given a program

x.fr = freeze x c = icmp eq x.fr, y br c, A, B A: use(x) // here

We can replace x with y.

This can be proved by case analysis.

If y is undef or poison, c is also undef or poison, so `br c` raises UB.

If y is a well-defined value, x.fr and y are equal, so x (which is more undefined than x) can be replaced with y.

Demonstration: https://alive2.llvm.org/ce/z/UWX2fL , https://alive2.llvm.org/ce/z/vxcMLS , https://alive2.llvm.org/ce/z/_mcXgJ

If the branch condition itself was frozen (`br freeze (icmp eq x, y)`), this optimization isn't valid (https://alive2.llvm.org/ce/z/X5eetc ).

If either x or y is constant, converting it into `br (icmp eq (freeze x), y)` will make the optimization above fire again.

InstCombine might be a good candidate for doing this preprocessing.