Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upConfusion with double negation and booleans #36856
Comments
This comment has been minimized.
This comment has been minimized.
|
This is... interesting I tested on OS X with various rust versions with various flags:
|
TimNN
added
I-wrong
T-compiler
I-nominated
labels
Sep 30, 2016
This comment has been minimized.
This comment has been minimized.
|
The first column seems to have been "fixed" by the switch to mir. |
TimNN
added
the
regression-from-stable-to-stable
label
Sep 30, 2016
This comment has been minimized.
This comment has been minimized.
|
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
|
This comment has been minimized.
This comment has been minimized.
|
(I updated the table above): Also, I checked with |
This comment has been minimized.
This comment has been minimized.
|
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 correctWith mov al, 255
mov cl, 1
cmp cl, al
je correctSo LLVM turns |
eddyb
added
the
A-LLVM
label
Sep 30, 2016
This comment has been minimized.
This comment has been minimized.
|
So we could just make compares use |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
we may want to consider doing this. It seems like llvm bugs for comparing |
This comment has been minimized.
This comment has been minimized.
|
In that case, these two arguments need to be wrapped in |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Something to note: MIPS, ARM and PowerPC should not be affected on quick visual inspection of the assembly. |
This comment has been minimized.
This comment has been minimized.
|
I am in favor of working around this by using |
This comment has been minimized.
This comment has been minimized.
|
(Preparing a patch.) |
nikomatsakis
self-assigned this
Oct 4, 2016
nikomatsakis
added a commit
to nikomatsakis/rust
that referenced
this issue
Oct 4, 2016
nikomatsakis
referenced this issue
Oct 4, 2016
Merged
force `i1` booleans to `i8` when comparing #36958
This comment has been minimized.
This comment has been minimized.
|
See PR #36958 |
This comment has been minimized.
This comment has been minimized.
|
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. |
bors
added a commit
that referenced
this issue
Oct 5, 2016
This comment has been minimized.
This comment has been minimized.
|
Just waiting for backport |
PieterPenninckx commentedSep 30, 2016
•
edited by eddyb
In certain circumstances,
true != !falseis consideredtrue.Steps to reproduce
cargo new negation --binsrc/main.rsso that the contents is the following:3.Run with
cargo runExpected and observed behavior
When run with
cargo run, the compiled program printswrong.I expect
correctto be printed because after the assignment,ashould still equal the value it was assigned to (note thatg()alwaysreturns the same value).
Note that
cargo run --releaseresults 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.rsand witchcargo run --releasethe resultingprogram behaves as I expect.
The unexpected behaviour only occurs when using
cargo run(or runningtarget/debug/negation).rustc --version --verbose:cargo --version --verboseEdit: added short description.