]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_mir_transform/src/inline.rs
Merge commit 'd822110d3b5625b9dc80ccc442e06fc3cc851d76' into clippyup
[rust.git] / compiler / rustc_mir_transform / src / inline.rs
index d7dd5fc8528454ca76c0a78ce2f1decdbedb437f..9174f04887e4229aa9f7596b7c101df5298148d8 100644 (file)
@@ -375,7 +375,12 @@ fn check_codegen_attributes(
             return Err("incompatible sanitizer set");
         }
 
-        if callee_attrs.instruction_set != self.codegen_fn_attrs.instruction_set {
+        // Two functions are compatible if the callee has no attribute (meaning
+        // that it's codegen agnostic), or sets an attribute that is identical
+        // to this function's attribute.
+        if callee_attrs.instruction_set.is_some()
+            && callee_attrs.instruction_set != self.codegen_fn_attrs.instruction_set
+        {
             return Err("incompatible instruction set");
         }
 
@@ -453,6 +458,15 @@ fn check_mir_body(
                 if ty.needs_drop(tcx, self.param_env) && let Some(unwind) = unwind {
                         work_list.push(unwind);
                     }
+            } else if callee_attrs.instruction_set != self.codegen_fn_attrs.instruction_set
+                && matches!(term.kind, TerminatorKind::InlineAsm { .. })
+            {
+                // During the attribute checking stage we allow a callee with no
+                // instruction_set assigned to count as compatible with a function that does
+                // assign one. However, during this stage we require an exact match when any
+                // inline-asm is detected. LLVM will still possibly do an inline later on
+                // if the no-attribute function ends up with the same instruction set anyway.
+                return Err("Cannot move inline-asm across instruction sets");
             } else {
                 work_list.extend(term.successors())
             }