Skip to content

Commit 728c955

Browse files
authored
Rollup merge of #81753 - tmiasko:inline-instruction-set, r=oli-obk
Never MIR inline functions with a different instruction set
2 parents e8aaa14 + eb5e2d0 commit 728c955

File tree

5 files changed

+152
-1
lines changed

5 files changed

+152
-1
lines changed

compiler/rustc_attr/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub enum InlineAttr {
7474
Never,
7575
}
7676

77-
#[derive(Clone, Encodable, Decodable, Debug)]
77+
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
7878
pub enum InstructionSetAttr {
7979
ArmA32,
8080
ArmT32,

compiler/rustc_mir/src/transform/inline.rs

+5
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,11 @@ impl Inliner<'tcx> {
281281
return false;
282282
}
283283

284+
if self.codegen_fn_attrs.instruction_set != codegen_fn_attrs.instruction_set {
285+
debug!("`callee has incompatible instruction set - not inlining");
286+
return false;
287+
}
288+
284289
let hinted = match codegen_fn_attrs.inline {
285290
// Just treat inline(always) as a hint for now,
286291
// there are cases that prevent inlining that we
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Checks that only functions with the compatible instruction_set attributes are inlined.
2+
//
3+
// compile-flags: --target thumbv4t-none-eabi
4+
// needs-llvm-components: arm
5+
6+
#![crate_type = "lib"]
7+
#![feature(rustc_attrs)]
8+
#![feature(no_core, lang_items)]
9+
#![feature(isa_attribute)]
10+
#![no_core]
11+
12+
#[rustc_builtin_macro]
13+
#[macro_export]
14+
macro_rules! asm {
15+
("assembly template",
16+
$(operands,)*
17+
$(options($(option),*))?
18+
) => {
19+
/* compiler built-in */
20+
};
21+
}
22+
23+
#[lang = "sized"]
24+
trait Sized {}
25+
#[lang = "copy"]
26+
trait Copy {}
27+
28+
#[instruction_set(arm::a32)]
29+
#[inline]
30+
fn instruction_set_a32() {}
31+
32+
#[instruction_set(arm::t32)]
33+
#[inline]
34+
fn instruction_set_t32() {}
35+
36+
#[inline]
37+
fn instruction_set_default() {}
38+
39+
// EMIT_MIR inline_instruction_set.t32.Inline.diff
40+
#[instruction_set(arm::t32)]
41+
pub fn t32() {
42+
instruction_set_a32();
43+
instruction_set_t32();
44+
// The default instruction set is currently
45+
// conservatively assumed to be incompatible.
46+
instruction_set_default();
47+
}
48+
49+
// EMIT_MIR inline_instruction_set.default.Inline.diff
50+
pub fn default() {
51+
instruction_set_a32();
52+
instruction_set_t32();
53+
instruction_set_default();
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
- // MIR for `default` before Inline
2+
+ // MIR for `default` after Inline
3+
4+
fn default() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:50:18: 50:18
6+
let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:51:5: 51:26
7+
let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:52:5: 52:26
8+
let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:53:5: 53:30
9+
+ scope 1 (inlined instruction_set_default) { // at $DIR/inline-instruction-set.rs:53:5: 53:30
10+
+ }
11+
12+
bb0: {
13+
StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:51:5: 51:26
14+
_1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:51:5: 51:26
15+
// mir::Constant
16+
// + span: $DIR/inline-instruction-set.rs:51:5: 51:24
17+
// + literal: Const { ty: fn() {instruction_set_a32}, val: Value(Scalar(<ZST>)) }
18+
}
19+
20+
bb1: {
21+
StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:51:26: 51:27
22+
StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:52:5: 52:26
23+
_2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:52:5: 52:26
24+
// mir::Constant
25+
// + span: $DIR/inline-instruction-set.rs:52:5: 52:24
26+
// + literal: Const { ty: fn() {instruction_set_t32}, val: Value(Scalar(<ZST>)) }
27+
}
28+
29+
bb2: {
30+
StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:52:26: 52:27
31+
StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:53:5: 53:30
32+
- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:53:5: 53:30
33+
- // mir::Constant
34+
- // + span: $DIR/inline-instruction-set.rs:53:5: 53:28
35+
- // + literal: Const { ty: fn() {instruction_set_default}, val: Value(Scalar(<ZST>)) }
36+
- }
37+
-
38+
- bb3: {
39+
+ _3 = const (); // scope 1 at $DIR/inline-instruction-set.rs:53:5: 53:30
40+
StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:53:30: 53:31
41+
_0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:50:18: 54:2
42+
return; // scope 0 at $DIR/inline-instruction-set.rs:54:2: 54:2
43+
}
44+
}
45+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
- // MIR for `t32` before Inline
2+
+ // MIR for `t32` after Inline
3+
4+
fn t32() -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/inline-instruction-set.rs:41:14: 41:14
6+
let _1: (); // in scope 0 at $DIR/inline-instruction-set.rs:42:5: 42:26
7+
let _2: (); // in scope 0 at $DIR/inline-instruction-set.rs:43:5: 43:26
8+
let _3: (); // in scope 0 at $DIR/inline-instruction-set.rs:46:5: 46:30
9+
+ scope 1 (inlined instruction_set_t32) { // at $DIR/inline-instruction-set.rs:43:5: 43:26
10+
+ }
11+
12+
bb0: {
13+
StorageLive(_1); // scope 0 at $DIR/inline-instruction-set.rs:42:5: 42:26
14+
_1 = instruction_set_a32() -> bb1; // scope 0 at $DIR/inline-instruction-set.rs:42:5: 42:26
15+
// mir::Constant
16+
// + span: $DIR/inline-instruction-set.rs:42:5: 42:24
17+
// + literal: Const { ty: fn() {instruction_set_a32}, val: Value(Scalar(<ZST>)) }
18+
}
19+
20+
bb1: {
21+
StorageDead(_1); // scope 0 at $DIR/inline-instruction-set.rs:42:26: 42:27
22+
StorageLive(_2); // scope 0 at $DIR/inline-instruction-set.rs:43:5: 43:26
23+
- _2 = instruction_set_t32() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:43:5: 43:26
24+
- // mir::Constant
25+
- // + span: $DIR/inline-instruction-set.rs:43:5: 43:24
26+
- // + literal: Const { ty: fn() {instruction_set_t32}, val: Value(Scalar(<ZST>)) }
27+
- }
28+
-
29+
- bb2: {
30+
+ _2 = const (); // scope 1 at $DIR/inline-instruction-set.rs:43:5: 43:26
31+
StorageDead(_2); // scope 0 at $DIR/inline-instruction-set.rs:43:26: 43:27
32+
StorageLive(_3); // scope 0 at $DIR/inline-instruction-set.rs:46:5: 46:30
33+
- _3 = instruction_set_default() -> bb3; // scope 0 at $DIR/inline-instruction-set.rs:46:5: 46:30
34+
+ _3 = instruction_set_default() -> bb2; // scope 0 at $DIR/inline-instruction-set.rs:46:5: 46:30
35+
// mir::Constant
36+
// + span: $DIR/inline-instruction-set.rs:46:5: 46:28
37+
// + literal: Const { ty: fn() {instruction_set_default}, val: Value(Scalar(<ZST>)) }
38+
}
39+
40+
- bb3: {
41+
+ bb2: {
42+
StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:46:30: 46:31
43+
_0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:41:14: 47:2
44+
return; // scope 0 at $DIR/inline-instruction-set.rs:47:2: 47:2
45+
}
46+
}
47+

0 commit comments

Comments
 (0)