Skip to content

Documentation on vector arguments for inline assembly is inconsistent with observed behavior #106924

Closed

Description

@pirocks

I tried this code:

#![feature(portable_simd)]

use std::simd::{i64x8, f64x8};
use std::arch::asm;


pub fn convert(a: i64x8) -> f64x8{
    let converted: f64x8;
    unsafe {
        asm!(
        "vcvtqq2pd {converted} {a}",
        a = in(zmm_reg) a,
        converted = out(zmm_reg) converted,
        );
    }
    converted
}

I expected to see this happen:
I thought this would compile and do as it says since, https://doc.rust-lang.org/reference/inline-assembly.html states that zmm_reg accepts vector types., like f64x8 and i64x8.

Instead, this happened:

error: cannot use value of type `Simd<i64, 8>` for inline assembly
  --> <source>:12:25
   |
12 |         a = in(zmm_reg) a,
   |                         ^
   |
   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: cannot use value of type `Simd<f64, 8>` for inline assembly
  --> <source>:13:34
   |
13 |         converted = out(zmm_reg) converted,
   |                                  ^^^^^^^^^
   |
   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: aborting due to 2 previous errors

Meta

rustc --version --verbose:

<redacted>@<redacted>::~$ rustc --version --verbose
rustc 1.68.0-nightly (afaf3e07a 2023-01-14)
binary: rustc
commit-hash: afaf3e07aaa7ca9873bdb439caec53faffa4230c
commit-date: 2023-01-14
host: x86_64-unknown-linux-gnu
release: 1.68.0-nightly
LLVM version: 15.0.6

No backtrace applicable.

Activity

  1. added
    A-SIMDArea: SIMD (Single Instruction Multiple Data)
    PG-portable-simdProject group: Portable SIMD (https://github.com/rust-lang/project-portable-simd)
    A-diagnosticsArea: Messages for errors, warnings, and lints
    on Jan 16, 2023
  2. workingjubilee commented on Jan 16, 2023

    @workingjubilee
    Member

    This is partly a diagnostics issue. The type you refer to in std::simd is more abstract, in that we permit it to be compiled in a way that does not actually use an AVX512 register. The type that the asm! documentation is trying to refer to is... very not. Thus it needs a conversion step to/from the "definitely a hardware register" type. The implementation that we should be recommending is:

    #![feature(avx512_target_feature)]
    #![feature(stdsimd)]
    #![feature(portable_simd)]
    
    use std::arch::{asm, x86_64::{__m512d, __m512i}};
    use std::simd::{f64x8, i64x8};
    
    #[target_feature(enable = "avx512f")]
    #[target_feature(enable = "avx512dq")]
    pub unsafe fn convert(a: i64x8) -> f64x8 {
        let a: __m512i = a.into();
        let converted: __m512d;
        unsafe {
            asm! {
                "vcvtqq2pd {converted} {a}",
                a = in(zmm_reg) a,
                converted = out(zmm_reg) converted,
            };
        }
        converted.into()
    }

    Obviously that's a fair few steps to get from here to there and we can also consider ways to smooth this path further.

  3. added
    A-inline-assemblyArea: Inline assembly (`asm!(…)`)
    A-docsArea: Documentation for any part of the project, including the compiler, standard library, and tools
    on Jan 16, 2023
  4. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Apr 5, 2023
  5. workingjubilee commented on May 10, 2023

    @workingjubilee
    Member

    It turns out this was actually more possible than I expected by simply changing how inline asm! accepts arguments, and validating that Simd still has an equivalence to a register, so this code now passes:

    #![feature(portable_simd)]
    #![feature(avx512_target_feature)]
    
    use std::simd::{i64x8, f64x8};
    use std::arch::asm;
    
    #[target_feature(enable = "avx512f")]
    pub unsafe fn convert(a: i64x8) -> f64x8{
        let converted: f64x8;
        unsafe {
            asm!(
            "vcvtqq2pd {converted}, {a}",
            a = in(zmm_reg) a,
            converted = out(zmm_reg) converted,
            );
        }
        converted
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-SIMDArea: SIMD (Single Instruction Multiple Data)A-diagnosticsArea: Messages for errors, warnings, and lintsA-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsA-inline-assemblyArea: Inline assembly (`asm!(…)`)A-target-featureArea: Enabling/disabling target features like AVX, Neon, etc.C-bugCategory: This is a bug.PG-portable-simdProject group: Portable SIMD (https://github.com/rust-lang/project-portable-simd)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions