Skip to content

Rust 1.45+ generates suboptimal control flow for ARMv7 atomic compare exchange #123113

@ds84182

Description

@ds84182

Code

I tried this code:

https://rust.godbolt.org/z/vP88v5GGc

I expected to see this happen:

A tight loop.

Instead, this happened:

In Rust 1.45 and later, LLVM generates a switch + unconditional branch to a conditional branch. This happens in opt-level=z, s, 1, 2, 3.

In some versions generates a dead branch, e.g.

mov r2, #0
cmp r2, #0
bne ... # If this branch is taken, hell has frozen over.

Version it worked on

It most recently worked on: 1.44

Version with regression

rustc --version --verbose:

rustc 1.79.0-nightly (0824b300e 2024-03-24)
binary: rustc
commit-hash: 0824b300eb0dae5d9ed59719d3f2732016683d66
commit-date: 2024-03-24
host: x86_64-unknown-linux-gnu
release: 1.79.0-nightly
LLVM version: 18.1.2

@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size of generated code.I-slowIssue: Problems and improvements with respect to performance of generated code.O-ArmTarget: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 stateP-lowLow priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    Status

    Blocked By LLVM

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions