Skip to content

Iterator inlining/optimization regression in 1.72 release #115601

Open
@alexpyattaev

Description

@alexpyattaev

Code

I tried this code to showcase zero-cost abstractions, and was quite surprised to see a whole bunch of asm as compared to hand-rolled version:

pub fn some_iterators_nonsense(z:&[i64])->i64{
    z.iter().map(| e| {
          e * e +3 
    }).filter(|e| {
        e % 2 ==0
    }).sum()  
}

In the hand-rolled version, the amount of generated asm is way less

pub fn some_nonsense(z:&[i64])->i64{
    let mut acc = 0;
    for e in z{
        let t = e * e+3 ;
        if t %2 ==0{
            acc += t;
        }
    }
    acc
}

According to godbolt, the amount of asm generated for the iterator version is ~3x more than hand-rolled version. Removing the map() operation or filter() operation (and updating the hand-rolled version) makes the issue go away.

Version it worked on

It most recently worked on: Rust 1.71
It also appears to have worked for many releases before that as well.

Version with regression

Regression observed on

  • Rust 1.71
  • Rust 1.72
  • Rust nightly

Godbolt

The exact code to reproduce is on Matt Godbolt's site:
https://godbolt.org/z/6jb8K3adK

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size of generated code.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-untriagedUntriaged performance or correctness regression.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions