-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Wrong optimization: provenance affects comparison of saved bits of addresses of dead auto variables #43687
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
Comments
And the same with memcpy/memcmp: #include <string.h> int main()
}$ clang -std=c11 -Weverything -O3 test.c && ./a.out
|
The main question is, when comparing two integers for equality, This isn't illegal as of right now: define i32 @_Z4testv() { Summary: |
In general, non-aliasing doesn't mean non-equal. For example, any pointer is noalias with a pointer to a constant global. We have to construct a different proof to simplify value comparisons. The comment to justify the current transform explains the relevant considerations, mostly... but it it isn't considering stack coloring as it currently exists in LLVM. (
Note that we do have some flexibility here under the as-if rule: if you remove the "diff" line from the original testcase, we can fold the comparison to a constant. |
Is this the same issue as #132085? It sure looks similar on the surface. |
Or maybe #45725 is the more correct issue? |
Extended Description
It's known that the value of a pointer to an object becomes indeterminate after the object is dead (C11, 6.2.4p2). Whether its representation becomes indeterminate is up for debate but let's bypass the issue by saving the representation while the object is still alive. For example, we can cast it to an integer. And we'll get an ordinary integer, with a stable value etc., not affected by changes in the life of the original object. Right?
This seems to be broken for the equality operators when the operands are constructed from addresses of automatic variables and at least one of these variables is dead at the time of comparison.
#include <stdio.h>
int main()
{
unsigned long u, v;
}
$ clang -std=c11 -Weverything -O3 test.c && ./a.out
u = 0x7ffd6e1f3de0
v = 0x7ffd6e1f3de0
diff = 0
eq = 0
clang x86-64 version: clang version 10.0.0 (https://github.com/llvm/llvm-project.git 200cce3)
If "diff" is 0 then "eq" should be 1.
gcc bug -- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93010
The text was updated successfully, but these errors were encountered: