The concept of poison here is not the same as C's definition of UB. LLVM has at least 3 different concepts that all vaguely count as UB (and probably closer to a half dozen when it gets fully formalized).<p>In C, UB is instant-UB--the moment you execute an operation that is UB, your program is undefined. LLVM also has instant-UB (I mean, any language that lets you dereference an arbitrary integer cast to a pointer has to have instant-UB). But poison isn't instant-UB--your program is perfectly safe to execute an operation that produces poison. It's only if a poison value reaches certain operations--essentially any control-flow decision point, or as an input to any operation that may cause instant-UB--that it causes UB in the C sense.<p>(This also means that operations that could trap--like x / 0--aren't modeled as poison in LLVM, but as instant-UB. It's safe to speculate an operation that causes poison, like x +nsw y, but it's not safe to speculate an operation that causes instant-UB, like x / y).