3 ms·
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
by jcranmer 10mo ago
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).
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.
(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).
- afiori 10mo agoIs dereferencing an arbitrary integer cast to pointer UB on any platform? I would expect that it is system dependent but mostly not C-style UB
- jcranmer 10mo agoDereferencing an arbitrary integer cast to a pointer means you are dereferencing an arbitrary memory location, which includes memory that is outside the purview of the C abstract machine model, say the return address of the function. That means the effect of that operation can't be meaningfully constrained, and the only option for that is UB. (Integer-to-pointer conversions beg the question of pointer provenance, which is a long, complicated topic that is still not fully solved, but does go to show that UB is actually a lot more complicated than most people expect.)