How to prevent bad code genration while using intrinsics in rust

Hello,

I have these 2 code snippets in rust and c++ .

#![feature(portable_simd)]
#![feature(stdsimd)]
use std::arch::x86_64::__m128i;
use std::arch::x86_64::_mm_min_epu64;

pub unsafe fn simd_min128(x: __m128i , y: __m128i ) -> __m128i  
{
    _mm_min_epu64(x, y)
}

#include <immintrin.h>

__m128i simd_min128(__m128i x, __m128i y)
{
    return _mm_min_epu64(x, y);
}

I see that in godbolt c++ generates 2 instructions while in rust generates 5 instructions which includes mov instructions and thereby slowing down the code. Can anyone help me on understand why this is happening and if there is any tricks I can use to make it generate an optimal code like c++.

Hello.

Have you tried inline?

It's ABI related, because if I switch to an extern "C" function, it generates the same code as the C++ compiler:

#![feature(portable_simd)]
#![feature(stdsimd)]
use std::arch::x86_64::__m128i;
use std::arch::x86_64::_mm_min_epu64;

pub unsafe extern "C" fn simd_min128(x: __m128i , y: __m128i ) -> __m128i  
{
    _mm_min_epu64(x, y)
}

In practice, I suspect you'll find that you don't need to care about this - Rust's inlining will fix it for you most of the time.

However, it might be worthwhile raising a bug report, since the compiler should be using a better ABI for Rust-internal stuff, and thus generating the same code.

2 Likes

Thanks for the help, inlining helped me fix it.

1 Like

Thanks for the help, inlining helped me fix it.

1 Like

This is intentional as the C calling convention used for passing vectors depends on the enabled target features, so it would be easy to get an ABI incompatibility. For SSE vectors on most x86_64 targets it doesn't really matter as SSE2 is required by x86_64 and as such most x86_64 targets have it unconditionally enabled, but for example for AVX vectors it is required to be able to call a function for which AVX is enabled from one for which it isn't enabled and vice versa.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.