// Checks that only functions with the compatible instruction_set attributes are inlined. // // A function is "compatible" when the *callee* has the same attribute or no attribute. // //@ compile-flags: --target thumbv4t-none-eabi //@ needs-llvm-components: arm #![crate_type = "lib"] #![feature(rustc_attrs)] #![feature(no_core, lang_items)] #![feature(isa_attribute)] #![no_core] #[rustc_builtin_macro] #[macro_export] macro_rules! asm { ("assembly template", $(operands,)* $(options($(option),*))? ) => { /* compiler built-in */ }; } #[lang = "sized"] trait Sized {} #[lang = "copy"] trait Copy {} #[instruction_set(arm::a32)] #[inline] fn instruction_set_a32() {} #[instruction_set(arm::t32)] #[inline] fn instruction_set_t32() {} #[inline] fn instruction_set_default() {} #[inline(always)] fn inline_always_and_using_inline_asm() { unsafe { asm!("/* do nothing */") }; } // EMIT_MIR inline_instruction_set.t32.Inline.diff #[instruction_set(arm::t32)] pub fn t32() { // CHECK-LABEL: fn t32( // CHECK-NOT: (inlined instruction_set_a32) instruction_set_a32(); // CHECK: (inlined instruction_set_t32) instruction_set_t32(); // CHECK: (inlined instruction_set_default) instruction_set_default(); // CHECK-NOT: (inlined inline_always_and_using_inline_asm) inline_always_and_using_inline_asm(); } // EMIT_MIR inline_instruction_set.default.Inline.diff pub fn default() { // CHECK-LABEL: fn default( // CHECK-NOT: (inlined instruction_set_a32) instruction_set_a32(); // CHECK-NOT: (inlined instruction_set_t32) instruction_set_t32(); // CHECK: (inlined instruction_set_default) instruction_set_default(); // CHECK: (inlined inline_always_and_using_inline_asm) inline_always_and_using_inline_asm(); }