Closed
Description
I tried this code:
pub fn div2(a: i32) -> i32 {
a.div_euclid(2)
}
I expected to see this happen:
After compiling to assembly with -C opt-level=3
to generate the following x86 assembly code.
div2:
mov eax, edi
sar eax
ret
Instead, this happened:
div2:
mov eax, edi
shr eax, 31
add eax, edi
sar eax
not edi
and edi, -2147483647
cmp edi, 1
sbb eax, 0
ret
Meta
rustc --version --verbose
:
rustc 1.74.0 (79e9716c9 2023-11-13)
binary: rustc
commit-hash: 79e9716c980570bfd1f666e3b16ac583f0168962
commit-date: 2023-11-13
host: x86_64-unknown-linux-gnu
release: 1.74.0
LLVM version: 17.0.4
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generationCategory: This is a bug.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.Issue: Problems and improvements with respect to binary size of generated code.Issue: Problems and improvements with respect to performance of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.
Activity
Urgau commentedon Nov 27, 2023
Those are not equivalent!(EDIT: was wrong, see below)div_euclid
say it it will round towards negative infinity ifself < 0
; whileself / 2
always rounds towards positive infinity.A simple playground example with
-7
proves that they do not return the same value:However if you use
u32
(or any unsigned integer) you will get the expected assembly.@rustbot labels -C-bug -needs-triage +C-discussion
LunaBorowska commentedon Nov 27, 2023
@Urgau I believe
x.div_euclid(2)
andx >> 1
(not to be confused withx / 2
) are in fact equivalent, and Alive2 tells me that this optimization is valid (https://alive2.llvm.org/ce/z/YVeJvZ), albeit I tested it withi8
(testing withi32
gets a timeout).x / 2
on the other hand compiles down to the following:Note how the generated code adds sign bit, which is correct.
x / 2
is not the same thing asx >> 1
specifically because it rounds towards 0, and not negative infinity.Jules-Bertholet commentedon Nov 28, 2023
@rustbot labels +C-bug +needs-triage -C-discussion I-heavy I-slow A-LLVM A-codegen T-compiler
17 remaining items