about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_attr_data_structures/src/attributes.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs15
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs2
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--tests/codegen/optimize-attr-1.rs14
-rw-r--r--tests/ui/feature-gates/feature-gate-optimize_attribute.rs3
-rw-r--r--tests/ui/feature-gates/feature-gate-optimize_attribute.stderr14
8 files changed, 45 insertions, 14 deletions
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index def6b16ee8a..810a254a7e1 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -38,7 +38,11 @@ pub enum InstructionSetAttr {
 #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub enum OptimizeAttr {
     None,
+    /// `#[optimize(none)]`
+    DoNotOptimize,
+    /// `#[optimize(speed)]`
     Speed,
+    /// `#[optimize(size)]`
     Size,
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 95e0481b035..cb1758c467c 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -336,6 +336,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         OptimizeAttr::None => {
             to_add.extend(default_optimisation_attrs(cx));
         }
+        OptimizeAttr::DoNotOptimize => {
+            to_add.push(llvm::AttributeKind::OptimizeNone.create_attr(cx.llcx));
+        }
         OptimizeAttr::Size => {
             to_add.push(llvm::AttributeKind::MinSize.create_attr(cx.llcx));
             to_add.push(llvm::AttributeKind::OptimizeForSize.create_attr(cx.llcx));
@@ -343,12 +346,12 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         OptimizeAttr::Speed => {}
     }
 
-    let inline =
-        if codegen_fn_attrs.inline == InlineAttr::None && instance.def.requires_inline(cx.tcx) {
-            InlineAttr::Hint
-        } else {
-            codegen_fn_attrs.inline
-        };
+    // `optnone` requires `noinline`
+    let inline = match (codegen_fn_attrs.inline, &codegen_fn_attrs.optimize) {
+        (_, OptimizeAttr::DoNotOptimize) => InlineAttr::Never,
+        (InlineAttr::None, _) if instance.def.requires_inline(cx.tcx) => InlineAttr::Hint,
+        (inline, _) => inline,
+    };
     to_add.extend(inline_attr(cx, inline));
 
     // The `uwtable` attribute according to LLVM is:
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 83724af604d..6099dec2bb2 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -1053,10 +1053,7 @@ pub(crate) fn provide(providers: &mut Providers) {
 
         let any_for_speed = defids.items().any(|id| {
             let CodegenFnAttrs { optimize, .. } = tcx.codegen_fn_attrs(*id);
-            match optimize {
-                attr::OptimizeAttr::None | attr::OptimizeAttr::Size => false,
-                attr::OptimizeAttr::Speed => true,
-            }
+            matches!(optimize, attr::OptimizeAttr::Speed)
         });
 
         if any_for_speed {
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 1daa17fbaf3..6f40ebb9b6e 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -592,6 +592,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                 OptimizeAttr::Size
             } else if list_contains_name(items, sym::speed) {
                 OptimizeAttr::Speed
+            } else if list_contains_name(items, sym::none) {
+                OptimizeAttr::DoNotOptimize
             } else {
                 err(items[0].span(), "invalid argument");
                 OptimizeAttr::None
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 68e0191f45e..966f7730918 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -532,7 +532,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
     // RFC 2412
     gated!(
-        optimize, Normal, template!(List: "size|speed"), ErrorPreceding,
+        optimize, Normal, template!(List: "none|size|speed"), ErrorPreceding,
         EncodeCrossCrate::No, optimize_attribute, experimental!(optimize)
     ),
 
diff --git a/tests/codegen/optimize-attr-1.rs b/tests/codegen/optimize-attr-1.rs
index 3aee44791e0..db6bdcf9a8b 100644
--- a/tests/codegen/optimize-attr-1.rs
+++ b/tests/codegen/optimize-attr-1.rs
@@ -37,11 +37,23 @@ pub fn speed() -> i32 {
     4 + 4
 }
 
+// CHECK-LABEL: define{{.*}}i32 @none
+// CHECK-SAME: [[NONE_ATTRS:#[0-9]+]]
+// SIZE-OPT: alloca
+// SPEED-OPT: alloca
+#[no_mangle]
+#[optimize(none)]
+pub fn none() -> i32 {
+    let arr = [0, 1, 2, 3, 4];
+    arr[4]
+}
+
 // NO-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}}
 // SPEED-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}}
 // SIZE-OPT-DAG: attributes [[NOTHING_ATTRS]] = {{.*}}optsize{{.*}}
 // SIZE-OPT-DAG: attributes [[SIZE_ATTRS]] = {{.*}}minsize{{.*}}optsize{{.*}}
+// CHECK-DAG: attributes [[NONE_ATTRS]] = {{.*}}noinline{{.*}}optnone{{.*}}
 
-// SIZE-OPT: attributes [[SPEED_ATTRS]]
+// SIZE-OPT-DAG: attributes [[SPEED_ATTRS]]
 // SIZE-OPT-NOT: minsize
 // SIZE-OPT-NOT: optsize
diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs
index 7f9cada6a47..77cc307c9f4 100644
--- a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs
+++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs
@@ -6,6 +6,9 @@ fn size() {}
 #[optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 fn speed() {}
 
+#[optimize(none)] //~ ERROR the `#[optimize]` attribute is an experimental feature
+fn none() {}
+
 #[optimize(banana)]
 //~^ ERROR the `#[optimize]` attribute is an experimental feature
 //~| ERROR E0722
diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
index ca8f4a078f0..4e6e4ac2703 100644
--- a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
+++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr
@@ -21,6 +21,16 @@ LL | #[optimize(speed)]
 error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:9:1
    |
+LL | #[optimize(none)]
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #54882 <https://github.com/rust-lang/rust/issues/54882> for more information
+   = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the `#[optimize]` attribute is an experimental feature
+  --> $DIR/feature-gate-optimize_attribute.rs:12:1
+   |
 LL | #[optimize(banana)]
    | ^^^^^^^^^^^^^^^^^^^
    |
@@ -29,12 +39,12 @@ LL | #[optimize(banana)]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0722]: invalid argument
-  --> $DIR/feature-gate-optimize_attribute.rs:9:12
+  --> $DIR/feature-gate-optimize_attribute.rs:12:12
    |
 LL | #[optimize(banana)]
    |            ^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0658, E0722.
 For more information about an error, try `rustc --explain E0658`.