LLVM backends still break freeze, inviting miscompiles
An RFC seeks proper machine-IR support for freeze so poison and undef stop producing inconsistent values after instruction selection.
LLVM backends have long ignored the freeze rule that a poison or undef value must become one fixed arbitrary value, and an RFC on the LLVM Discourse now pushes to correct the lowering before more miscompiles appear.
LangRef requires freeze to stabilize its input. The middle end mostly obeys that contract, but SelectionDAG, FastISel and GlobalISel on AArch64, AMDGPU, RISC-V and X86 simply turn freeze into a copy. When the operand is undef or poison the copy becomes an IMPLICIT_DEF; later passes then treat the result as freely rewritable, so different uses of the same frozen value can observe different registers. Open bugs dating back years document the resulting wrong code.
Mitch Briles, who filed the RFC, lists three approaches: materialize a concrete constant such as zero, reuse the existing INIT_UNDEF pseudo, or introduce a first-class FREEZE machine opcode that mirrors the IR instruction. He and others doing verification work regard anything short of a real freeze operation as incomplete, because poison can still appear after instruction selection.
Matt Arsenault agreed that machine IR needs full equivalents of undef, poison and freeze, noting that IMPLICIT_DEF already behaves as poison in practice and that a rename would reduce confusion. Nikita Popov called INIT_UNDEF a narrow hack and said a proper FREEZE opcode is the right long-term direction, while warning that the change will require substantial work to avoid performance regressions.
The discussion leaves the concrete implementation open, but the diagnosis is settled: without explicit freeze support in the backends, LLVM will continue to generate code that violates its own semantics.