rust-lang / rust-lang/rust

RISC-V intrinsics with one or more target features are not inlined

Open
#137,293 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-LLVM C-bug C-optimization O-riscv T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

The Problem

The compiler does not inline RISC-V intrinsics that can be enabled with one or more target features (i.e. #[target_feature(enable = "zkne", enable = "zknd")]) unless all of them are present.

Expected Behavior

At least one enabled feature should be enough for the compiler to generate inlined code.

Explanation

RISC-V intrinsics such as sha512sig0 require only one target feature:

#[target_feature(enable = "zknh")]
pub unsafe fn sha512sig0(rs1: u64) -> u64;

When zknh is enabled, the compiler inlines the intrinsic with the appropriate instruction on nightly (https://godbolt.org/z/Kozx3KE11):

example::main::hb1a6ee9bd645943a:
        addi    sp, sp, -16
        sha512sig0      a0, zero
        sd      a0, 8(sp)
        addi    a0, sp, 8
        addi    sp, sp, 16
        ret

Unfortunately, this is not the case for intrinsics that can be enabled by one or more target features. Let's take a look at aes64ks2:

#[target_feature(enable = "zkne", enable = "zknd")]
pub unsafe fn aes64ks2(rs1: u64, rs2: u64) -> u64;

The documentation states that the intrinsic is "safe to use if the zkne OR zknd target feature is present." which means that enabling at least one of them should be enough to inline the intrinsic.

However, the compiler exhibits this behavior only if two of them are enabled at the same time.

The compiler generates a stub if only one of zkne (https://godbolt.org/z/5TxeKo1sG), or zknd (https://godbolt.org/z/KKqz8MWYY) is enabled:

core::core_arch::riscv64::zk::aes64ks2::ha6614eafefa6ee36:
        aes64ks2        a0, zero, zero
        ret

example::main::hb1a6ee9bd645943a:
        addi    sp, sp, -16
        sd      ra, 8(sp)
        call    core::core_arch::riscv64::zk::aes64ks2::ha6614eafefa6ee36
        sd      a0, 0(sp)
        mv      a0, sp
        ld      ra, 8(sp)
        addi    sp, sp, 16
        ret

If they are both enabled, the compiler inlines the intrinsic as expected (https://godbolt.org/z/3fEjfr1v8):

example::main::hb1a6ee9bd645943a:
        addi    sp, sp, -16
        aes64ks2        a0, zero, zero
        sd      a0, 8(sp)
        addi    a0, sp, 8
        addi    sp, sp, 16
        ret

Meta

Here is the output of the compiler:

rustc 1.87.0-nightly (5bc623145 2025-02-16)
binary: rustc
commit-hash: 5bc62314547c7639484481f62f218156697cfef0
commit-date: 2025-02-16
host: x86_64-unknown-linux-gnu
release: 1.87.0-nightly
LLVM version: 19.1.7

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the RISC-V intrinsic definitions in crates/core_arch/src/riscv64/zk.rs, especially aes64ks2 and sha512sig0, then compare the linked Godbolt assembly examples. Trace how rustc handles multiple target_feature requirements during inlining; done means an intrinsic requiring zkne or zknd is inlined when either feature is enabled.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.