Skip to content

Commit

Permalink
Auto merge of #111836 - calebzulawski:target-feature-closure, r=worki…
Browse files Browse the repository at this point in the history
…ngjubilee

Fix #[inline(always)] on closures with target feature 1.1

Fixes #108655.  I think this is the most obvious solution that isn't overly complicated.  The comment includes more justification, but I think this is likely better than demoting the `#[inline(always)]` to `#[inline]`, since existing code is unaffected.
  • Loading branch information
bors committed Jul 23, 2023
2 parents 98179ad + cdb9de7 commit 1c44af9
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
17 changes: 16 additions & 1 deletion compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
});

// #73631: closures inherit `#[target_feature]` annotations
if tcx.features().target_feature_11 && tcx.is_closure(did.to_def_id()) {
//
// If this closure is marked `#[inline(always)]`, simply skip adding `#[target_feature]`.
//
// At this point, `unsafe` has already been checked and `#[target_feature]` only affects codegen.
// Emitting both `#[inline(always)]` and `#[target_feature]` can potentially result in an
// ICE, because LLVM errors when the function fails to be inlined due to a target feature
// mismatch.
//
// Using `#[inline(always)]` implies that this closure will most likely be inlined into
// its parent function, which effectively inherits the features anyway. Boxing this closure
// would result in this closure being compiled without the inherited target features, but this
// is probably a poor usage of `#[inline(always)]` and easily avoided by not using the attribute.
if tcx.features().target_feature_11
&& tcx.is_closure(did.to_def_id())
&& codegen_fn_attrs.inline != InlineAttr::Always
{
let owner_id = tcx.parent(did.to_def_id());
if tcx.def_kind(owner_id).has_codegen_attrs() {
codegen_fn_attrs
Expand Down
33 changes: 33 additions & 0 deletions tests/codegen/target-feature-inline-closure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// only-x86_64
// compile-flags: -Copt-level=3

#![crate_type = "lib"]
#![feature(target_feature_11)]

#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;

// CHECK-LABEL: @with_avx
#[no_mangle]
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "avx")]
fn with_avx(x: __m256) -> __m256 {
// CHECK: fadd
let add = {
#[inline(always)]
|x, y| unsafe { _mm256_add_ps(x, y) }
};
add(x, x)
}

// CHECK-LABEL: @without_avx
#[no_mangle]
#[cfg(target_arch = "x86_64")]
unsafe fn without_avx(x: __m256) -> __m256 {
// CHECK-NOT: fadd
let add = {
#[inline(always)]
|x, y| unsafe { _mm256_add_ps(x, y) }
};
add(x, x)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Tests #108655: closures in `#[target_feature]` functions can still be marked #[inline(always)]

// check-pass
// revisions: mir thir
// [thir]compile-flags: -Z thir-unsafeck
// only-x86_64

#![feature(target_feature_11)]

#[target_feature(enable = "avx")]
pub unsafe fn test() {
({
#[inline(always)]
move || {}
})();
}

fn main() {}

0 comments on commit 1c44af9

Please sign in to comment.