mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
011b260cc8
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.
78 lines
1.5 KiB
Rust
78 lines
1.5 KiB
Rust
// Checks that only functions with compatible attributes are inlined.
|
|
// only-x86_64
|
|
// compile-flags: -Cpanic=abort
|
|
|
|
#![crate_type = "lib"]
|
|
#![feature(no_sanitize)]
|
|
#![feature(target_feature_11)]
|
|
#![feature(c_variadic)]
|
|
|
|
#[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 f0() {
|
|
sse2();
|
|
}
|
|
|
|
// CHECK-LABEL: fn f1()
|
|
// CHECK: bb0: {
|
|
// CHECK-NEXT: sse2()
|
|
pub unsafe fn f1() {
|
|
sse2();
|
|
}
|
|
|
|
// 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();
|
|
}
|
|
|
|
// CHECK-LABEL: fn not_inlined_no_sanitize()
|
|
// CHECK: bb0: {
|
|
// CHECK-NEXT: no_sanitize()
|
|
pub unsafe fn not_inlined_no_sanitize() {
|
|
no_sanitize();
|
|
}
|
|
|
|
// 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 _ = sum(4u32, 4u32, 30u32, 200u32, 1000u32);
|
|
}
|
|
|
|
#[inline(always)]
|
|
#[no_mangle]
|
|
unsafe extern "C" fn sum(n: u32, mut vs: ...) -> u32 {
|
|
let mut s = 0;
|
|
let mut i = 0;
|
|
while i != n {
|
|
s += vs.arg::<u32>();
|
|
i += 1;
|
|
}
|
|
s
|
|
}
|