Leo Gaspard via llvm-dev
2021-Nov-30 14:57 UTC
[llvm-dev] Inline assembly and poison values
Hello world, I'm currently reviewing some code making heavy use of fast math, and thus probably generating poison values. This code uses an inline assembly code block in order to freeze the poison values, as it's written in Rust and Rust doesn't currently expose the freeze operation. My question is, does inline assembly freeze its inputs or does it propagate poison? I can't find in the documentation any explicit answer with regards to freezing inline assembly inputs. My reading of the current documentation for poison would make me think inline assembly would propagate poison because there's no exception for it, but I'd be surprised if that were the wanted semantics, as it'd mean inline assembly would probably need to be UB as soon as any poison is even transitively (through pointers) passed. Would it be possible to add an explicit clause to the documentation indicating whether inline assembly freezes its inputs or if it propagates poison, or even if it generates UB when being passed a poisoned value? To be precise, the code uses an `in(reg) value.as_ptr()` (equivalent to `"r" (&value)` with clang) with nostack and preserves_flags. I'd also be interested in knowing whether `inlateout(reg) value` (approx. equivalent to `"=r" (value)` with clang) with pure would still freeze, as it should lead to better performance by not requiring llvm to put the variable in memory. Either way, thank you for LLVM, it's an awesome piece of software! Best, Léo
Johannes Doerfert via llvm-dev
2021-Nov-30 15:28 UTC
[llvm-dev] Inline assembly and poison values
On 11/30/21 08:57, Leo Gaspard via llvm-dev wrote:> Hello world, > > I'm currently reviewing some code making heavy use of fast math, and > thus probably generating poison values. > > This code uses an inline assembly code block in order to freeze the > poison values, as it's written in Rust and Rust doesn't currently expose > the freeze operation. > My question is, does inline assembly freeze its inputs or does it > propagate poison? I can't find in the documentation any explicit answer > with regards to freezing inline assembly inputs. My reading of the > current documentation for poison would make me think inline assembly > would propagate poison because there's no exception for it, but I'd be > surprised if that were the wanted semantics, as it'd mean inline > assembly would probably need to be UB as soon as any poison is even > transitively (through pointers) passed. > > Would it be possible to add an explicit clause to the documentation > indicating whether inline assembly freezes its inputs or if it > propagates poison, or even if it generates UB when being passed a > poisoned value?I very much hope inline asm can (in general) act like a freeze but does not have to. That is, if we ever look into the box we can determine if it does freeze or not, and consequently use the information for follow argumentation. However, unless we look into the box we cannot assume anything. Hence, asm does not propagate poison but also does not freeze the inputs. That means we shall not propagate poison trough (uninterpreted) asm but also not remove a subsequent freeze under the assumption the asm would have implicitly frozen the poison already. That all said, whatever we come up with needs documentation for sure. ~ Johannes> To be precise, the code uses an `in(reg) value.as_ptr()` (equivalent to > `"r" (&value)` with clang) with nostack and preserves_flags. I'd also be > interested in knowing whether `inlateout(reg) value` (approx. equivalent > to `"=r" (value)` with clang) with pure would still freeze, as it should > lead to better performance by not requiring llvm to put the variable in > memory. > > Either way, thank you for LLVM, it's an awesome piece of software! > > Best, > Léo > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Leo Gaspard via llvm-dev
2021-Dec-07 20:34 UTC
[llvm-dev] Inline assembly and poison values
Johannes Doerfert <johannesdoerfert at gmail.com> writes:> I very much hope inline asm can (in general) act like a freeze > but does not have to. That is, if we ever look into the box we > can determine if it does freeze or not, and consequently use the > information for follow argumentation. However, unless we look > into the box we cannot assume anything. Hence, asm does not > propagate poison but also does not freeze the inputs. That means > we shall not propagate poison trough (uninterpreted) asm but also > not remove a subsequent freeze under the assumption the asm would > have implicitly frozen the poison already.Do I understand correctly if I say that this means that for defining proper semantics of the assembly+IR group, this would require defining, for each assembly backend, what “poison” translates to and from for it? Or maybe documentation could just say “what exactly ‘poison’ means is backend-specific, and the outputs of an assembly block handling poisoned data can be, or not, poisoned depending on each backend” or something similar, thus postponing the specification work for later? Though it'd probably be better if it were possible to have a full spec of what exactly poison means for each backend, I guess it can take a while to check exactly how each poison can arise and what they should translate to for each backend in order to enable as many optimizations as possible