about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs6
-rw-r--r--tests/codegen/issues/issue-136329-optnone-noinline.rs21
2 files changed, 26 insertions, 1 deletions
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 95aeccfdda6..f8b0688dfdc 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -4,7 +4,7 @@ use std::iter;
 use std::ops::{Range, RangeFrom};
 
 use rustc_abi::{ExternAbi, FieldIdx};
-use rustc_attr_parsing::InlineAttr;
+use rustc_attr_parsing::{InlineAttr, OptimizeAttr};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_index::Idx;
@@ -770,6 +770,10 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>(
         return Err("never inline attribute");
     }
 
+    if let OptimizeAttr::DoNotOptimize = callee_attrs.optimize {
+        return Err("has DoNotOptimize attribute");
+    }
+
     // Reachability pass defines which functions are eligible for inlining. Generally inlining
     // other functions is incorrect because they could reference symbols that aren't exported.
     let is_generic = callsite.callee.args.non_erasable_generics().next().is_some();
diff --git a/tests/codegen/issues/issue-136329-optnone-noinline.rs b/tests/codegen/issues/issue-136329-optnone-noinline.rs
new file mode 100644
index 00000000000..57c9e47a499
--- /dev/null
+++ b/tests/codegen/issues/issue-136329-optnone-noinline.rs
@@ -0,0 +1,21 @@
+//! Ensure that `#[optimize(none)]` functions are never inlined
+
+//@ compile-flags: -Copt-level=3
+
+#![feature(optimize_attribute)]
+
+#[optimize(none)]
+pub fn foo() {
+    let _x = 123;
+}
+
+// CHECK-LABEL: define{{.*}}void @bar
+// CHECK: start:
+// CHECK: {{.*}}call {{.*}}void
+// CHECK: ret void
+#[no_mangle]
+pub fn bar() {
+    foo();
+}
+
+fn main() {}