- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
Closed
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.
Description
When calling .rem_euclid(n) on a signed integer type, it fails to apply the optimization for powers of 2, where it should do a bitwise AND operation instead.
Missed optimization
pub fn rem(n: i32) -> i32 {
    n.rem_euclid(2)
}example::rem:
        mov     eax, edi
        shr     eax, 31
        add     eax, edi
        and     eax, -2
        sub     edi, eax
        mov     eax, 1
        cmovns  eax, edi
        ret
How it should be optimized
pub fn rem(n: i32) -> i32 {
    n & 1
}example::rem:
        mov     eax, edi
        and     eax, 1
        ret
Testing the optimization:
n = 2
?play
let mut passed = true;
for i in (std::i16::MIN..=std::i16::MAX) {
    if (i&1) != (i.rem_euclid(2)) {
        passed = false;
        break
    }
}
println!("{passed}");truen = 1
?play
let mut passed = true;
for i in (std::i16::MIN..=std::i16::MAX) {
    if (i&0) != (i.rem_euclid(1)) {
        passed = false;
        break
    }
}
println!("{passed}");truen = 4
?play
let mut passed = true;
for i in (std::i16::MIN..=std::i16::MAX) {
    if (i&3) != (i.rem_euclid(4)) {
        passed = false;
        break
    }
}
println!("{passed}");trueCuriously, the optimization is applied to unsigned integers just fine
pub fn rem(n: u32) -> u32 {
    n.rem_euclid(2) 
}example::rem:
        mov     eax, edi
        and     eax, 1
        ret
Metadata
Metadata
Assignees
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.I-slowIssue: Problems and improvements with respect to performance of generated code.Issue: Problems and improvements with respect to performance of generated code.