Skip to content

u32 saturating_mul+compare slower than u64 mul+compare #34949

@eefriedman

Description

@eefriedman
#![feature(test)]
#![feature(core_intrinsics)]

extern crate test;

static mut XXX: u32 = 10;

use test::Bencher;

#[bench]
fn bench_sat_mul(b: &mut Bencher) {
    b.iter(|| unsafe {
        for _ in 1..1000 {
            let r = std::intrinsics::volatile_load(&XXX);
            let r2 = std::intrinsics::volatile_load(&XXX);
            let r = r.saturating_mul(r2);
            let r = if r > 1000000000 { 1000000000 } else { r };
            std::intrinsics::volatile_store(&mut XXX, r);
        }
    });
}

#[bench]
fn bench_sat_mul_2(b: &mut Bencher) {
    b.iter(|| unsafe {
        for _ in 1..1000 {
            let r = std::intrinsics::volatile_load(&XXX);
            let r2 = std::intrinsics::volatile_load(&XXX);
            let r = r as u64 * r2 as u64;
            let r = if r > 1000000000 { 1000000000 } else { r as u32 };
            std::intrinsics::volatile_store(&mut XXX, r);
        }
    });
}

Originally reported at https://users.rust-lang.org/t/unexpected-performance-from-array-bound-tests-and-more/6376/5 .

The two different code sequences:

    deac:       f7 e2                   mul    %edx
    deae:       0f 40 c7                cmovo  %edi,%eax
    deb1:       3d 00 ca 9a 3b          cmp    $0x3b9aca00,%eax
    deb6:       0f 47 c3                cmova  %ebx,%eax
    df3c:       48 0f af f3             imul   %rbx,%rsi
    df40:       48 81 fe 00 ca 9a 3b    cmp    $0x3b9aca00,%rsi
    df47:       0f 43 f2                cmovae %edx,%esi

There also seems to be some effect on loop unrolling.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.I-slowIssue: Problems and improvements with respect to performance of generated code.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions