-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LLVM-backend] Zig should set noundef
attributes on arguments
#18501
Comments
with that attribute does passing |
shouldnt passing undefined already be considered UB? it really shouldnt be used like that unless you know the argument is unused |
yeah I suppose it would. guess I'm wary of what other kind of optimizations it would cause llvm to enable and if we have enough safety checking to warn against it |
Passing syscall6(SYS_EXIT, 0, undefined, undefined, undefined, undefined, undefined) here the values will even be used and passed to inline assembly, they will just have undefined values
|
but those parameters are effectively unused right? they're passed to inline asm but only as pseudo values to fullfil the interface of the syscall function. there's no branching on the values for example? I don't mean UB in the sense that the compiler will emit broken code, more that you're willingly using values that may lead to unpredictable behavior. I'm assuming that's more in line with what nektro meant as well and I'm a little confused on that llvm definition, I'm not familiar with what it means by poison bits or if undefined in that context is the same as zigs |
Yes those values are used but ignored, but the LLVM docs don't mention usage, only the values. |
Ugh, there's something more fucky going on here, and I don't get it. |
would you look at that, it does make the optimziation happen though:
|
Ah here's why: https://llvm.org/docs/LangRef.html#i-select
|
That makes no sense. Why would select be defined for undefined values? Also, does this make it UB or just undefined result to pass undefined in? |
(By my understanding,) It's currently well-defined to call Edit: I got the truth values the wrong way around: Edit2: Here's more details on the optimization from llvm's end https://aqjune.github.io/posts/2021-10-4.the-select-story.html |
Select talks about semantics based on poison bits, not undefined bits. noundef forbids both. Does zig emit anything that can have poison bits? |
Here's As a quick explanation of that syntax, This was the best source I could find for this info: docs are sparse on undef, and most email threads are debating the semantics XD MemorySanitizer at least represents the current intentions of the llvm sources |
It seems the optimization might be valid anyway in this specific case (pointed out by @mlugg on discord). Clang doesn't need it because of their We might add it as an optimization for zig's sake if it does turn out to be correct. Here's an informal analysis for someone smarter than me to refine😆
There're 9 cases for each permutation of x and y, and the result value of the instruction is written
It would seem that there're no cases where the rewrite would introduce UB. (I am however entirely out of my element ;)) |
Exactly what I've been saying about the bitwise rewrite. They are exactly equivalent. The undefined bits shouldn't affect this optimization at all. The only thing that could are poison bits. |
Zig Version
0.12.0-dev.2076+8fd15c6ca
Steps to Reproduce and Observed Behavior
Godbolt Link
The above is not getting optimized. The obvious optimization here is to transform this into
return (a | b) < 2
, but that will not happen because, according to the fine folks at llvm/llvm-project#77432, Zig is not properly setting thenoundef
attribute on the function arguments, thereforeand
can not be turned into a bitwise AND, i.e.&
.Expected Behavior
It should be as optimized as this code is: (Godbolt link)
The text was updated successfully, but these errors were encountered: