Given a program
x.fr = freeze x
c = icmp eq x.fr, y
br c, A, B
use(x) // here
We can replace x with y, and this is useful for reducing # of uses of freeze.
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.