Skip to content

Commit ddb16e2

Browse files
committed
Fix #[inline(always)] on closures with target feature 1.1
1 parent 9d871b0 commit ddb16e2

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
493493
});
494494

495495
// #73631: closures inherit `#[target_feature]` annotations
496-
if tcx.features().target_feature_11 && tcx.is_closure(did.to_def_id()) {
496+
//
497+
// If this closure is marked `#[inline(always)]`, simply skip adding `#[target_feature]`.
498+
//
499+
// At this point, `unsafe` has already been checked and `#[target_feature]` only affects codegen.
500+
// Emitting both `#[inline(always)]` and `#[target_feature]` can potentially result in an
501+
// ICE, because LLVM errors when the function fails to be inlined due to a target feature
502+
// mismatch.
503+
//
504+
// Using `#[inline(always)]` implies that this closure will most likely be inlined into
505+
// its parent function, which effectively inherits the features anyway. Boxing this closure
506+
// would result in this closure being compiled without the inherited target features, but this
507+
// is probably a poor usage of `#[inline(always)]` and easily avoided by not using the attribute.
508+
if tcx.features().target_feature_11
509+
&& tcx.is_closure(did.to_def_id())
510+
&& codegen_fn_attrs.inline != InlineAttr::Always
511+
{
497512
let owner_id = tcx.parent(did.to_def_id());
498513
if tcx.def_kind(owner_id).has_codegen_attrs() {
499514
codegen_fn_attrs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Tests #108655: closures in `#[target_feature]` functions can still be marked #[inline(always)]
2+
3+
// check-pass
4+
// revisions: mir thir
5+
// [thir]compile-flags: -Z thir-unsafeck
6+
// only-x86_64
7+
8+
#![feature(target_feature_11)]
9+
10+
#[target_feature(enable = "avx")]
11+
pub unsafe fn test() {
12+
({
13+
#[inline(always)]
14+
move || {}
15+
})();
16+
}
17+
18+
fn main() {}

0 commit comments

Comments
 (0)