Auto merge of #111836 - calebzulawski:target-feature-closure, r=worki… · rust-lang/rust@1c44af9 (original) (raw)
File tree
3 files changed
lines changed
- compiler/rustc_codegen_ssa/src
- ui/rfcs/rfc-2396-target_feature-11
3 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -501,7 +501,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { | ||
501 | 501 | }); |
502 | 502 | |
503 | 503 | // #73631: closures inherit `#[target_feature]` annotations |
504 | -if tcx.features().target_feature_11 && tcx.is_closure(did.to_def_id()) { | |
504 | +// | |
505 | +// If this closure is marked `#[inline(always)]`, simply skip adding `#[target_feature]`. | |
506 | +// | |
507 | +// At this point, `unsafe` has already been checked and `#[target_feature]` only affects codegen. | |
508 | +// Emitting both `#[inline(always)]` and `#[target_feature]` can potentially result in an | |
509 | +// ICE, because LLVM errors when the function fails to be inlined due to a target feature | |
510 | +// mismatch. | |
511 | +// | |
512 | +// Using `#[inline(always)]` implies that this closure will most likely be inlined into | |
513 | +// its parent function, which effectively inherits the features anyway. Boxing this closure | |
514 | +// would result in this closure being compiled without the inherited target features, but this | |
515 | +// is probably a poor usage of `#[inline(always)]` and easily avoided by not using the attribute. | |
516 | +if tcx.features().target_feature_11 | |
517 | + && tcx.is_closure(did.to_def_id()) | |
518 | + && codegen_fn_attrs.inline != InlineAttr::Always | |
519 | +{ | |
505 | 520 | let owner_id = tcx.parent(did.to_def_id()); |
506 | 521 | if tcx.def_kind(owner_id).has_codegen_attrs() { |
507 | 522 | codegen_fn_attrs |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
1 | +// only-x86_64 | |
2 | +// compile-flags: -Copt-level=3 | |
3 | + | |
4 | +#![crate_type = "lib"] | |
5 | +#![feature(target_feature_11)] | |
6 | + | |
7 | +#[cfg(target_arch = "x86_64")] | |
8 | +use std::arch::x86_64::*; | |
9 | + | |
10 | +// CHECK-LABEL: @with_avx | |
11 | +#[no_mangle] | |
12 | +#[cfg(target_arch = "x86_64")] | |
13 | +#[target_feature(enable = "avx")] | |
14 | +fn with_avx(x: __m256) -> __m256 { | |
15 | +// CHECK: fadd | |
16 | +let add = { | |
17 | +#[inline(always)] | |
18 | + |x, y | |
19 | +}; | |
20 | +add(x, x) | |
21 | +} | |
22 | + | |
23 | +// CHECK-LABEL: @without_avx | |
24 | +#[no_mangle] | |
25 | +#[cfg(target_arch = "x86_64")] | |
26 | +unsafe fn without_avx(x: __m256) -> __m256 { | |
27 | +// CHECK-NOT: fadd | |
28 | +let add = { | |
29 | +#[inline(always)] | |
30 | + |x, y | |
31 | +}; | |
32 | +add(x, x) | |
33 | +} |
Original file line number | Diff line number | Diff 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() {} |