Skip to content

std::arch does not implement some Neon SIMD intrinsics #75373

Closed
@Nufflee

Description

@Nufflee

I tried this code:

#![feature(stdsimd)]
#![feature(arm_target_feature)]

extern crate core;

use std::arch::arm::*;

#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
unsafe fn vmovmaskq_u8(input: uint8x16_t) -> i32 {
    // Example input (half scale):
    // 0x89 FF 1D C0 00 10 99 33

    // Shift out everything but the sign bits
    // 0x01 01 00 01 00 00 01 00
    let high_bits = vreinterpretq_u16_u8(vshrq_n_u8(input, 7));

    // Merge the even lanes together with vsra. The '??' bytes are garbage.
    // vsri could also be used, but it is slightly slower on aarch64.
    // 0x??03 ??02 ??00 ??01
    let paired16 = vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7));
    // Repeat with wider lanes.
    // 0x??????0B ??????04
    let paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14));
    // 0x??????????????4B
    let paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28));
    // Extract the low 8 bits from each lane and join.
    // 0x4B
    return vgetq_lane_u8(paired64, 0) | (vgetq_lane_u8(paired64, 8) << 8);
}

Godbolt: https://godbolt.org/z/1no41v

I expected to see this happen: Intrinsics found without compile errors

Instead, this happened: Compile errors about Neon functions and types not found. I was able to reproduce this same issue on a Raspberry Pi 3 with a ARM v8 CPU running 32-bit Raspbian. Keep in mind that these intrinsics are supported on ARM v7 and some of them, like vreinterpretq_u32_u16 are basically just reinterpret casts.

Edit: upon closer inspection, I realized that most of the intrinsics I am using are not even supported by Rust. I should still be able to use vreinterpretq_u32_u16 because it is a part of the Rust STD.

Meta

rustc --version --verbose:

rustc 1.47.0-nightly (6c8927b0c 2020-07-26)
binary: rustc
commit-hash: 6c8927b0cf80ceee19386026cf9d7fd4fd9d486f
commit-date: 2020-07-26
host: armv7-unknown-linux-gnueabihf
release: 1.47.0-nightly
LLVM version: 10.0
Backtrace

error[E0412]: cannot find type `uint8x16_t` in this scope

  --> <source>:10:31

   |

10 |   unsafe fn vmovmaskq_u8(input: uint8x16_t) -> i32 {

   |                                 ^^^^^^^^^^ help: a struct with a similar name exists: `uint8x4_t`



error[E0425]: cannot find function `vreinterpretq_u16_u8` in this scope

  --> <source>:16:21

   |

16 |     let high_bits = vreinterpretq_u16_u8(vshrq_n_u8(input, 7));

   |                     ^^^^^^^^^^^^^^^^^^^^ not found in this scope



error[E0425]: cannot find function `vshrq_n_u8` in this scope

  --> <source>:16:42

   |

16 |     let high_bits = vreinterpretq_u16_u8(vshrq_n_u8(input, 7));

   |                                          ^^^^^^^^^^ not found in this scope



error[E0425]: cannot find function `vreinterpretq_u32_u16` in this scope

  --> <source>:21:20

   |

21 |     let paired16 = vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7));

   |                    ^^^^^^^^^^^^^^^^^^^^^ not found in this scope



error[E0425]: cannot find function `vsraq_n_u16` in this scope

  --> <source>:21:42

   |

21 |     let paired16 = vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7));

   |                                          ^^^^^^^^^^^ not found in this scope



error[E0425]: cannot find function `vreinterpretq_u64_u32` in this scope

  --> <source>:24:20

   |

24 |     let paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14));

   |                    ^^^^^^^^^^^^^^^^^^^^^ not found in this scope



error[E0425]: cannot find function `vsraq_n_u32` in this scope

  --> <source>:24:42

   |

24 |     let paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14));

   |                                          ^^^^^^^^^^^ not found in this scope



error[E0425]: cannot find function `vreinterpretq_u8_u64` in this scope

  --> <source>:26:20

   |

26 |     let paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28));

   |                    ^^^^^^^^^^^^^^^^^^^^ not found in this scope



error[E0425]: cannot find function `vsraq_n_u64` in this scope

  --> <source>:26:41

   |

26 |     let paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28));

   |                                         ^^^^^^^^^^^ not found in this scope



error[E0425]: cannot find function `vgetq_lane_u8` in this scope

  --> <source>:29:12

   |

29 |     return vgetq_lane_u8(paired64, 0) | (vgetq_lane_u8(paired64, 8) << 8);

   |            ^^^^^^^^^^^^^ not found in this scope



error[E0425]: cannot find function `vgetq_lane_u8` in this scope

  --> <source>:29:42

   |

29 |     return vgetq_lane_u8(paired64, 0) | (vgetq_lane_u8(paired64, 8) << 8);

   |                                          ^^^^^^^^^^^^^ not found in this scope



warning: unused import: `std::arch::arm::*`

 --> <source>:6:5

  |

6 | use std::arch::arm::*;

  |     ^^^^^^^^^^^^^^^^^

  |

  = note: `#[warn(unused_imports)]` on by default



error: aborting due to 11 previous errors; 1 warning emitted



Some errors have detailed explanations: E0412, E0425.

For more information about an error, try `rustc --explain E0412`.

Compiler returned: 1

cc @gnzlbg

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-SIMDArea: SIMD (Single Instruction Multiple Data)C-feature-requestCategory: A feature request, i.e: not implemented / a PR.O-AArch64Armv8-A or later processors in AArch64 modeO-ArmTarget: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions