https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91291
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Ah, we do not eliminate # VUSE <.MEM_8> reg.0_2 = reg; because this is a hard-register load (we know reg.0_2 is constant 1). So we end up making the constant 1 (value) available via the leader reg.0_2. Note it doesn't really work here as the comment says /* See PR43491. Do not replace a global register variable when it is a the RHS of an assignment. Do replace local register variables since gcc does not guarantee a local variable will be allocated in register. ??? The fix isn't effective here. This should instead be ensured by not value-numbering them the same but treating them like volatiles? */ && !(gimple_assign_single_p (stmt) && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)) && is_global_var (gimple_assign_rhs1 (stmt))))) uses of reg.0_2 will still be replaced with '1': Value numbering stmt = reg = 1B; RHS 1B simplified to 1B No store match Value numbering store reg to 1B Setting value number of .MEM_8 to .MEM_8 (changed) Value numbering stmt = reg.0_2 = reg; Setting value number of reg.0_2 to 1B (changed) Value numbering stmt = if (reg.0_2 == 0B) marking known outgoing edge 3 -> 5 executable Removing unexecutable edge from if (reg.0_2 == 0B) ... <bb 3> : foo: reg = 1B; reg.0_2 = reg; reg = &foo; goto <bb 3>; [INV] so the only thing this achieved is leaving a dead load around in this case. Anyways, easy to fix.