-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Confusion with double negation and booleans #36856
Comments
This is... interesting I tested on OS X with various rust versions with various flags:
|
The first column seems to have been "fixed" by the switch to mir. |
The 1.12 change might mean MIR fixed an old trans bug. Unoptimized Before MIR trans, we didn't have the infrastructure to handle turning What hasn't changed, though, is the behavior with
|
(I updated the table above): Also, I checked with |
Minimal version for inspecting LLVM IR or assembly. Cleaned up assembly: call g
xor al, -1
and al, 1
mov byte ptr [rbp - 10], al
call g
xor al, -1
mov cl, byte ptr [rbp - 10]
cmp cl, al
je correct With mov al, 255
mov cl, 1
cmp cl, al
je correct So LLVM turns |
So we could just make compares use |
To further explain what MIR "fixed": both following forms also result in "correct" with fn main() {
if !g() != !g() {
println!("wrong");
} else {
println!("correct");
}
} fn main() {
let a = !g();
let b = !g();
if a != b {
println!("wrong");
} else {
println!("correct");
}
} Variables end up holding |
we may want to consider doing this. It seems like llvm bugs for comparing |
In that case, these two arguments need to be wrapped in |
Something to note: MIPS, ARM and PowerPC should not be affected on quick visual inspection of the assembly. |
I am in favor of working around this by using |
(Preparing a patch.) |
Work around LLVM bug. cc rust-lang#36856
See PR #36958 |
For all its worth, it seems like LLVM Trunk does not reproduce, though I didn’t check myself, yet. Backporting the LLVM patch would still make rustc compiled against 3.9/3.8 fail so working around the issue in rustc seems good to me. |
Just waiting for backport |
Work around LLVM bug. cc rust-lang#36856
Work around LLVM bug. cc rust-lang#36856
In certain circumstances,
true != !false
is consideredtrue
.Steps to reproduce
cargo new negation --bin
src/main.rs
so that the contents is the following:3.Run with
cargo run
Expected and observed behavior
When run with
cargo run
, the compiled program printswrong
.I expect
correct
to be printed because after the assignment,a
should still equal the value it was assigned to (note thatg()
alwaysreturns the same value).
Note that
cargo run --release
results in printingcorrect
, so even if it's me who is being confused, the output should still be the same in debug mode and in release mode.Meta
When I do a normal
rustc main.rs
and witchcargo run --release
the resultingprogram behaves as I expect.
The unexpected behaviour only occurs when using
cargo run
(or runningtarget/debug/negation
).rustc --version --verbose
:cargo --version --verbose
Edit: added short description.
The text was updated successfully, but these errors were encountered: