Skip to content

Commit

Permalink
Rollup merge of #117141 - tmiasko:inline-target-features, r=oli-obk
Browse files Browse the repository at this point in the history
Require target features to match exactly during inlining

In general it is not correct to inline a callee with a target features
that are subset of the callee. Require target features to match exactly
during inlining.

The exact match could be potentially relaxed, but this would require
identifying specific feature that are allowed to differ, those that need
to match, and those that can be present in caller but not in callee.

This resolves MIR part of #116573. For other concerns with respect to
the previous implementation also see areInlineCompatible in LLVM.
  • Loading branch information
matthiaskrgr authored Oct 25, 2023
2 parents 24254d2 + 011b260 commit a1ab167
Show file tree
Hide file tree
Showing 12 changed files with 44 additions and 230 deletions.
6 changes: 2 additions & 4 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,10 +438,8 @@ impl<'tcx> Inliner<'tcx> {
return Err("incompatible instruction set");
}

for feature in &callee_attrs.target_features {
if !self.codegen_fn_attrs.target_features.contains(feature) {
return Err("incompatible target feature");
}
if callee_attrs.target_features != self.codegen_fn_attrs.target_features {
return Err("incompatible target features");
}

Ok(())
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

64 changes: 42 additions & 22 deletions tests/mir-opt/inline/inline_compatibility.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,71 @@
// skip-filecheck
// Checks that only functions with compatible attributes are inlined.
//
// only-x86_64
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
// compile-flags: -Cpanic=abort

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

// EMIT_MIR inline_compatibility.inlined_target_feature.Inline.diff
#[inline]
#[target_feature(enable = "sse2")]
unsafe fn sse2() {}

#[inline]
fn nop() {}

// CHECK-LABEL: fn f0()
// CHECK: bb0: {
// CHECK-NEXT: return;
#[target_feature(enable = "sse2")]
pub unsafe fn inlined_target_feature() {
target_feature();
pub unsafe fn f0() {
sse2();
}

// EMIT_MIR inline_compatibility.not_inlined_target_feature.Inline.diff
pub unsafe fn not_inlined_target_feature() {
target_feature();
// CHECK-LABEL: fn f1()
// CHECK: bb0: {
// CHECK-NEXT: sse2()
pub unsafe fn f1() {
sse2();
}

// EMIT_MIR inline_compatibility.inlined_no_sanitize.Inline.diff
// CHECK-LABEL: fn f2()
// CHECK: bb0: {
// CHECK-NEXT: nop()
#[target_feature(enable = "avx")]
pub unsafe fn f2() {
nop();
}

#[inline]
#[no_sanitize(address)]
pub unsafe fn no_sanitize() {}

// CHECK-LABEL: fn inlined_no_sanitize()
// CHECK: bb0: {
// CHECK-NEXT: return;
#[no_sanitize(address)]
pub unsafe fn inlined_no_sanitize() {
no_sanitize();
}

// EMIT_MIR inline_compatibility.not_inlined_no_sanitize.Inline.diff
// CHECK-LABEL: fn not_inlined_no_sanitize()
// CHECK: bb0: {
// CHECK-NEXT: no_sanitize()
pub unsafe fn not_inlined_no_sanitize() {
no_sanitize();
}

#[inline]
#[target_feature(enable = "sse2")]
pub unsafe fn target_feature() {}

#[inline]
#[no_sanitize(address)]
pub unsafe fn no_sanitize() {}

// EMIT_MIR inline_compatibility.not_inlined_c_variadic.Inline.diff
// CHECK-LABEL: fn not_inlined_c_variadic()
// CHECK: bb0: {
// CHECK-NEXT: StorageLive(_1)
// CHECK-NEXT: _1 = sum
pub unsafe fn not_inlined_c_variadic() {
let s = sum(4u32, 4u32, 30u32, 200u32, 1000u32);
let _ = sum(4u32, 4u32, 30u32, 200u32, 1000u32);
}

#[no_mangle]
#[inline(always)]
#[no_mangle]
unsafe extern "C" fn sum(n: u32, mut vs: ...) -> u32 {
let mut s = 0;
let mut i = 0;
Expand Down

0 comments on commit a1ab167

Please sign in to comment.