godbolt
#![feature(repr_simd, powerpc_target_feature)]
#![allow(non_camel_case_types)]
#[repr(simd)] pub struct u32x4(u32, u32, u32, u32);
impl u32x4 {
#[inline]
// #[inline(always)]
fn splat(x: u32) -> Self {
u32x4(x, x, x, x)
}
}
#[target_feature(enable = "altivec")]
pub unsafe fn splat_u32x4(x: u32) -> u32x4 {
u32x4::splat(x)
}
with #[inline] that code produces a function call within splat_u32x4 (b example::u32x4::splat) to u32x4::splat, which is not eliminated, even though this method is module private. With #[inline(always)], u32x4::splat is inlined into splat_u32x4, and no code for u32x4::splat is generated.
#[inline] should not be needed here, much less #[inline(always)], yet without #[inline(always)] this produces bad codegen.
Removing the #[target_feature] attribute from splat_u32x4 fixes the issue, no #[inline] necessary: godbolt. So there must be some interaction between inlining and target features going on here.
godbolt
with
#[inline]that code produces a function call withinsplat_u32x4(b example::u32x4::splat) tou32x4::splat, which is not eliminated, even though this method is module private. With#[inline(always)],u32x4::splatis inlined intosplat_u32x4, and no code foru32x4::splatis generated.#[inline]should not be needed here, much less#[inline(always)], yet without#[inline(always)]this produces bad codegen.Removing the
#[target_feature]attribute fromsplat_u32x4fixes the issue, no#[inline]necessary: godbolt. So there must be some interaction between inlining and target features going on here.