Skip to content

Inconsistent optimization #63274

@npmccallum

Description

@npmccallum
use std::ops::*;

pub struct Number([u64; 4]);

impl Add for Number {
    type Output = Self;

    #[inline]
    fn add(self, other: Self) -> Self::Output {
        let mut accum: Self::Output = unsafe { core::mem::uninitialized() };
        let mut carry = false;

        for i in 0..self.0.len() {
            let x = self.0[i] as u128 + other.0[i] as u128 + carry as u128;
            carry = x > core::u64::MAX as u128;
            accum.0[i] = x as u64;
        }

        accum
    }
}

pub fn add_a(l: Number, r: Number) -> Number {
    l + r
}


pub fn add_b(l: [u64; 4], r: [u64; 4]) -> [u64; 4] {
    let mut accum: [u64; 4] = unsafe { core::mem::uninitialized() };
    let mut carry = false;

    for i in 0..4 {
        let x = l[i] as u128 + r[i] as u128 + carry as u128;
        carry = x > core::u64::MAX as u128;
        accum[i] = x as u64;
    }

    accum
}

impl Sub for Number {
    type Output = Self;

    #[inline]
    fn sub(self, other: Self) -> Self::Output {
        let mut accum: Self::Output = unsafe { core::mem::uninitialized() };
        let mut carry = false;

        for i in 0..self.0.len() {
            let x = self.0[i] as u128 - other.0[i] as u128 - carry as u128;
            carry = x > core::u64::MAX as u128;
            accum.0[i] = x as u64;
        }

        accum
    }
}

pub fn sub_a(l: Number, r: Number) -> Number {
    l - r
}


pub fn sub_b(l: [u64; 4], r: [u64; 4]) -> [u64; 4] {
    let mut accum: [u64; 4] = unsafe { core::mem::uninitialized() };
    let mut carry = false;

    for i in 0..4 {
        let x = l[i] as u128 - r[i] as u128 - carry as u128;
        carry = x > core::u64::MAX as u128;
        accum[i] = x as u64;
    }

    accum
}

https://godbolt.org/z/aqhD1B

The above link demonstrates four functions of the same algorithm. The generated assembly is widely divergent based on context. It would be great if rust could output the same code for all of them. Alternatively, someone could recommend an algorithm that produces consistent output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-enhancementCategory: An issue proposing an enhancement or a PR with one.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    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