# Packed\_simd: \`cfg(target\_feature)\` does not play well with \`#\[target\_feature\]\`

**URL:** <https://internals.rust-lang.org/t/packed-simd-cfg-target-feature-does-not-play-well-with-target-feature/8115>\
**Category:** Uncategorized\
**Created:** [August 2, 2018, 8:30am UTC](https://internals.rust-lang.org/t/packed-simd-cfg-target-feature-does-not-play-well-with-target-feature/8115 "2018-08-02T08:30:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![gnzlbg](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gnzlbg/32/3858_2.png) [@gnzlbg](https://internals.rust-lang.org/u/gnzlbg)\
**Post date:** [August 2, 2018, 8:30am UTC](https://internals.rust-lang.org/t/packed-simd-cfg-target-feature-does-not-play-well-with-target-feature/8115/1 "2018-08-02T08:30:31Z")

</div>

The `packed_simd` crate ([https://github.com/rust-lang-nursery/packed\_simd](https://github.com/rust-lang-nursery/packed_simd)) does not play well with `#[target_feature]`. Given:

```rust
extern crate packed_simd;
use packed_simd::m32x8;

#[target_feature(enable = "sse4.2")]
unsafe fn foo(m: m32x8) -> bool { m.all() }

#[target_feature(enable = "avx2")]
unsafe fn bar(m: m32x8) -> bool { m.all() }

```

the functions `foo` and `bar` are potentially compiled with different target features. Assume that the binary is compiled for one of the `x86_64`-targets, then the binary is compiled with SSE2 globally enabled, while `foo` and `bar` extend SSE2 with SSE4.2 and AVX2.

The method `all` on masks, like all methods in `packed_simd`, is `#[inline]`. The crate `packed_simd` will be compiled with SSE2 enabled, but because `foo` and `bar` extend the feature set that `packed_simd` was compiled with, the functions defined in the `packed_simd` crate can be inlined into `foo` and `bar`, and for them LLVM will generate code using SSE4.2 and AVX2 in this case.

Now comes the problem. The `packed_simd` crate has _many_ work arounds for LLVM bugs: [https://github.com/rust-lang-nursery/packed\_simd/tree/master/src/codegen](https://github.com/rust-lang-nursery/packed_simd/tree/master/src/codegen)

All these workarounds are currently implemented using `cfg(target_feature)`, like this:

```rust
impl m32x8 {
    cfg_if! {
        if #[cfg(target_feature = "sse4.2")] {
            #[inline] fn all(self) -> bool { ... }
        } else if #[cfg(target_feature = "avx2")] {
            #[inline] fn all(self) -> bool { ... }
        } else {
            #[inline] fn all(self) -> bool { ... }
        }
    }
}

```

and that shows the problem. Because the `packed_simd` crate was compiled with the global feature set, and neither SSE4.2 nor AVX2 were enabled globally, the worst possible implementation for every work around will be selected independently of the features that the calling context, `foo` and `bar`, supports.

So that is the problem in practice. This is a reduced version of this problem:

```rust
// interaction within a single function
// (macros won't solve packed_simd's problem)
#[target_feature(enable = "avx2")]
unsafe fn foo() -> bool {
    // often returns false:
    if cfg!(target_feature = "avx2") { true } else { false }
}

// interaction across functions
#[target_feature(enable = "avx2")]
unsafe fn bar() -> bool { foo() }

```

How do we improve / fix this? I have no good answer.

---

<div class="post-metadata">

**Author:** ![raphlinus](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/raphlinus/32/2668_2.png) [@raphlinus](https://internals.rust-lang.org/u/raphlinus)\
**Post date:** [October 11, 2018, 12:26am UTC](https://internals.rust-lang.org/t/packed-simd-cfg-target-feature-does-not-play-well-with-target-feature/8115/2 "2018-10-11T00:26:54Z")

</div>

I’m very curious if there’s an update to this. In experimenting, it seems that functions in packed\_simd are getting inlined as hoped for. However, when I try to write my own code ([work in progress](https://gist.github.com/raphlinus/d0666fcd1c454d13ab5a9aec1244b4b3)) I seem to get the fallback implementation.

Did you find a workaround? Is the problem basically that using an llvm intrinsic (such as `llvm.round.v8f32`) preserves the conditional compilation by target, but doing direct simd instructions, as I’m trying to do with my `SimdRounded`, doesn’t?

Presumably this question is the subject for the documentation stub on [inlining](https://rust-lang-nursery.github.io/packed_simd/perf-guide/target-feature/inlining.html). I for one would be very interested!

---

<div class="post-metadata">

**Author:** ![gnzlbg](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gnzlbg/32/3858_2.png) [@gnzlbg](https://internals.rust-lang.org/u/gnzlbg)\
**Post date:** [October 11, 2018, 8:27am UTC](https://internals.rust-lang.org/t/packed-simd-cfg-target-feature-does-not-play-well-with-target-feature/8115/3 "2018-10-11T08:27:30Z")

</div>

See [Using run-time feature detection in core](https://internals.rust-lang.org/t/using-run-time-feature-detection-in-core/8419) for the most promising path forward, since we have this problem in `libcore` and `libstd` as well.

> However, when I try to write my own code ([work in progress](https://gist.github.com/raphlinus/d0666fcd1c454d13ab5a9aec1244b4b3)) I seem to get the fallback implementation.

You are doing compile-time feature detection there, so as long as you compile with `-C target-feature=+sse4.2` you should be getting the correct intrinsics.

If you want to see `round` and the other math intrinsics in `packed_simd` open an issue or send a PR, chances are that the LLVM intrinsics is not going to be good enough for you anyways (they are going to be scalarized by LLVM, but `packed_simd` supports vectorized `libm` libraries up to a certain degree that are much faster: ~8-10x faster).

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:30am UTC](https://internals.rust-lang.org/t/packed-simd-cfg-target-feature-does-not-play-well-with-target-feature/8115/4 "2019-03-25T08:30:38Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
