Skip to content

Bad codegen for widen followed by ARM vdupq_n_* #137407

Open
@CatsAreFluffy

Description

@CatsAreFluffy

Code

I tried this code:

use std::arch::aarch64::*;

#[no_mangle]
pub unsafe fn half_dup(x: u16) -> uint16x8_t {
    vaddq_u16(vreinterpretq_u16_u32(vdupq_n_u32(x as u32)), vdupq_n_u16(1))
}

I expected to see this happen: The compiled output would use the dup instruction

Instead, this happened: The compiled output uses a bunch of movs instead

Godbolt

Version it worked on

It most recently worked on: Rust 1.81.0

Version with regression

rustc --version --verbose:

rustc 1.82.0 (f6e511eec 2024-10-15)
binary: rustc
commit-hash: f6e511eec7342f59a25f7c0534f1dbea00d01b14
commit-date: 2024-10-15
host: x86_64-unknown-linux-gnu
release: 1.82.0
LLVM version: 19.1.1

and

rustc 1.87.0-nightly (f280acf4c 2025-02-19)
binary: rustc
commit-hash: f280acf4c743806abbbbcfe65050ac52ec4bdec0
commit-date: 2025-02-19
host: x86_64-unknown-linux-gnu
release: 1.87.0-nightly
LLVM version: 20.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-SIMDArea: SIMD (Single Instruction Multiple Data)C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchO-AArch64Armv8-A or later processors in AArch64 modeP-mediumMedium priorityS-has-bisectionStatus: A bisection has been found for this issueT-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

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions