about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2022-01-12 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2022-01-12 18:51:31 +0100
commit000b36c505a8865322c376486791cdee8f38d0c5 (patch)
tree3efb3d84c08ebe0f3d2e43eeeac59dbc5f79b0b2
parent72e74d7b9cf1a7901650227e74650f1fcc797600 (diff)
downloadrust-000b36c505a8865322c376486791cdee8f38d0c5.tar.gz
rust-000b36c505a8865322c376486791cdee8f38d0c5.zip
Remove deprecated LLVM-style inline assembly
-rw-r--r--compiler/rustc_ast/src/ast.rs39
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs17
-rw-r--r--compiler/rustc_ast/src/visit.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs33
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs9
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs56
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs9
-rw-r--r--compiler/rustc_borrowck/src/def_use.rs3
-rw-r--r--compiler/rustc_borrowck/src/invalidation.rs27
-rw-r--r--compiler/rustc_borrowck/src/lib.rs36
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs9
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/llvm_asm.rs303
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs12
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs107
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs47
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/asm.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs1
-rw-r--r--compiler/rustc_hir/src/arena.rs1
-rw-r--r--compiler/rustc_hir/src/hir.rs39
-rw-r--r--compiler/rustc_hir/src/intravisit.rs4
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs61
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs14
-rw-r--r--compiler/rustc_middle/src/mir/spanview.rs1
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs18
-rw-r--r--compiler/rustc_middle/src/thir.rs6
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs8
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs1
-rw-r--r--compiler/rustc_mir_build/src/build/expr/category.rs3
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/stmt.rs32
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs3
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs6
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs5
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs11
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs5
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs1
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs19
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs3
-rw-r--r--compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs1
-rw-r--r--compiler/rustc_mir_transform/src/separate_const_switch.rs8
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs3
-rw-r--r--compiler/rustc_mir_transform/src/simplify_try.rs4
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_prop.rs13
-rw-r--r--compiler/rustc_passes/src/liveness.rs36
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs16
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs2
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs6
-rw-r--r--compiler/rustc_typeck/src/expr_use_visitor.rs12
-rw-r--r--compiler/rustc_typeck/src/mem_categorization.rs1
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/macros/mod.rs26
-rw-r--r--library/core/src/prelude/v1.rs4
-rw-r--r--library/std/src/lib.rs5
-rw-r--r--library/std/src/prelude/v1.rs5
68 files changed, 27 insertions, 1132 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index a2d32cdc00f..079b9e43373 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1266,7 +1266,7 @@ impl Expr {
             ExprKind::Break(..) => ExprPrecedence::Break,
             ExprKind::Continue(..) => ExprPrecedence::Continue,
             ExprKind::Ret(..) => ExprPrecedence::Ret,
-            ExprKind::InlineAsm(..) | ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
+            ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
             ExprKind::MacCall(..) => ExprPrecedence::Mac,
             ExprKind::Struct(..) => ExprPrecedence::Struct,
             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
@@ -1423,8 +1423,6 @@ pub enum ExprKind {
 
     /// Output of the `asm!()` macro.
     InlineAsm(P<InlineAsm>),
-    /// Output of the `llvm_asm!()` macro.
-    LlvmInlineAsm(P<LlvmInlineAsm>),
 
     /// A macro invocation; pre-expansion.
     MacCall(MacCall),
@@ -2076,41 +2074,6 @@ pub struct InlineAsm {
     pub line_spans: Vec<Span>,
 }
 
-/// Inline assembly dialect.
-///
-/// E.g., `"intel"` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
-#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Hash, HashStable_Generic)]
-pub enum LlvmAsmDialect {
-    Att,
-    Intel,
-}
-
-/// LLVM-style inline assembly.
-///
-/// E.g., `"={eax}"(result)` as in `llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")`.
-#[derive(Clone, Encodable, Decodable, Debug)]
-pub struct LlvmInlineAsmOutput {
-    pub constraint: Symbol,
-    pub expr: P<Expr>,
-    pub is_rw: bool,
-    pub is_indirect: bool,
-}
-
-/// LLVM-style inline assembly.
-///
-/// E.g., `llvm_asm!("NOP");`.
-#[derive(Clone, Encodable, Decodable, Debug)]
-pub struct LlvmInlineAsm {
-    pub asm: Symbol,
-    pub asm_str_style: StrStyle,
-    pub outputs: Vec<LlvmInlineAsmOutput>,
-    pub inputs: Vec<(Symbol, P<Expr>)>,
-    pub clobbers: Vec<Symbol>,
-    pub volatile: bool,
-    pub alignstack: bool,
-    pub dialect: LlvmAsmDialect,
-}
-
 /// A parameter in a function header.
 ///
 /// E.g., `bar: usize` as in `fn foo(bar: usize)`.
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 9ef78aaf667..564a8a8c872 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1350,23 +1350,6 @@ pub fn noop_visit_expr<T: MutVisitor>(
             visit_opt(expr, |expr| vis.visit_expr(expr));
         }
         ExprKind::InlineAsm(asm) => noop_visit_inline_asm(asm, vis),
-        ExprKind::LlvmInlineAsm(asm) => {
-            let LlvmInlineAsm {
-                asm: _,
-                asm_str_style: _,
-                outputs,
-                inputs,
-                clobbers: _,
-                volatile: _,
-                alignstack: _,
-                dialect: _,
-            } = asm.deref_mut();
-            for out in outputs {
-                let LlvmInlineAsmOutput { constraint: _, expr, is_rw: _, is_indirect: _ } = out;
-                vis.visit_expr(expr);
-            }
-            visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr));
-        }
         ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
         ExprKind::Struct(se) => {
             let StructExpr { qself, path, fields, rest } = se.deref_mut();
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 6840f092da6..0b95270a4e1 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -864,14 +864,6 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         ExprKind::MacCall(ref mac) => visitor.visit_mac_call(mac),
         ExprKind::Paren(ref subexpression) => visitor.visit_expr(subexpression),
         ExprKind::InlineAsm(ref asm) => walk_inline_asm(visitor, asm),
-        ExprKind::LlvmInlineAsm(ref ia) => {
-            for &(_, ref input) in &ia.inputs {
-                visitor.visit_expr(input)
-            }
-            for output in &ia.outputs {
-                visitor.visit_expr(&output.expr)
-            }
-        }
         ExprKind::Yield(ref optional_expression) => {
             walk_list!(visitor, visit_expr, optional_expression);
         }
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 75f384405bb..15bf1a5a2ab 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -226,7 +226,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ExprKind::InlineAsm(ref asm) => {
                     hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm))
                 }
-                ExprKind::LlvmInlineAsm(ref asm) => self.lower_expr_llvm_asm(asm),
                 ExprKind::Struct(ref se) => {
                     let rest = match &se.rest {
                         StructRest::Base(e) => Some(self.lower_expr(e)),
@@ -1284,38 +1283,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
         result
     }
 
-    fn lower_expr_llvm_asm(&mut self, asm: &LlvmInlineAsm) -> hir::ExprKind<'hir> {
-        let inner = hir::LlvmInlineAsmInner {
-            inputs: asm.inputs.iter().map(|&(c, _)| c).collect(),
-            outputs: asm
-                .outputs
-                .iter()
-                .map(|out| hir::LlvmInlineAsmOutput {
-                    constraint: out.constraint,
-                    is_rw: out.is_rw,
-                    is_indirect: out.is_indirect,
-                    span: self.lower_span(out.expr.span),
-                })
-                .collect(),
-            asm: asm.asm,
-            asm_str_style: asm.asm_str_style,
-            clobbers: asm.clobbers.clone(),
-            volatile: asm.volatile,
-            alignstack: asm.alignstack,
-            dialect: asm.dialect,
-        };
-        let hir_asm = hir::LlvmInlineAsm {
-            inner,
-            inputs_exprs: self.arena.alloc_from_iter(
-                asm.inputs.iter().map(|&(_, ref input)| self.lower_expr_mut(input)),
-            ),
-            outputs_exprs: self
-                .arena
-                .alloc_from_iter(asm.outputs.iter().map(|out| self.lower_expr_mut(&out.expr))),
-        };
-        hir::ExprKind::LlvmInlineAsm(self.arena.alloc(hir_asm))
-    }
-
     fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
         hir::ExprField {
             hir_id: self.next_id(),
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 6237a01f694..45920bb27d5 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -960,15 +960,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 return;
             }
             ExprKind::Let(..) if !let_allowed => this.ban_let_expr(expr),
-            ExprKind::LlvmInlineAsm(..) if !this.session.target.allow_asm => {
-                struct_span_err!(
-                    this.session,
-                    expr.span,
-                    E0472,
-                    "llvm_asm! is unsupported on this target"
-                )
-                .emit();
-            }
             ExprKind::Match(expr, arms) => {
                 this.visit_expr(expr);
                 for arm in arms {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index fa9a20f2e03..f4fc2789d9e 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -2168,62 +2168,6 @@ impl<'a> State<'a> {
                 self.word("asm!");
                 self.print_inline_asm(a);
             }
-            ast::ExprKind::LlvmInlineAsm(ref a) => {
-                self.word("llvm_asm!");
-                self.popen();
-                self.print_symbol(a.asm, a.asm_str_style);
-                self.word_space(":");
-
-                self.commasep(Inconsistent, &a.outputs, |s, out| {
-                    let constraint = out.constraint.as_str();
-                    let mut ch = constraint.chars();
-                    match ch.next() {
-                        Some('=') if out.is_rw => {
-                            s.print_string(&format!("+{}", ch.as_str()), ast::StrStyle::Cooked)
-                        }
-                        _ => s.print_string(&constraint, ast::StrStyle::Cooked),
-                    }
-                    s.popen();
-                    s.print_expr(&out.expr);
-                    s.pclose();
-                });
-                self.space();
-                self.word_space(":");
-
-                self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| {
-                    s.print_symbol(co, ast::StrStyle::Cooked);
-                    s.popen();
-                    s.print_expr(o);
-                    s.pclose();
-                });
-                self.space();
-                self.word_space(":");
-
-                self.commasep(Inconsistent, &a.clobbers, |s, &co| {
-                    s.print_symbol(co, ast::StrStyle::Cooked);
-                });
-
-                let mut options = vec![];
-                if a.volatile {
-                    options.push("volatile");
-                }
-                if a.alignstack {
-                    options.push("alignstack");
-                }
-                if a.dialect == ast::LlvmAsmDialect::Intel {
-                    options.push("intel");
-                }
-
-                if !options.is_empty() {
-                    self.space();
-                    self.word_space(":");
-                    self.commasep(Inconsistent, &options, |s, &co| {
-                        s.print_string(co, ast::StrStyle::Cooked);
-                    });
-                }
-
-                self.pclose();
-            }
             ast::ExprKind::MacCall(ref m) => self.print_mac(m),
             ast::ExprKind::Paren(ref e) => {
                 self.popen();
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 15372ec1534..f0036f09c38 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -8,7 +8,6 @@ use rustc_mir_dataflow::ResultsVisitable;
 use rustc_mir_dataflow::{self, fmt::DebugWithContext, CallReturnPlaces, GenKill};
 use rustc_mir_dataflow::{Analysis, Direction, Results};
 use std::fmt;
-use std::iter;
 
 use crate::{
     places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, ToRegionVid,
@@ -385,14 +384,6 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
                 self.kill_borrows_on_place(trans, Place::from(local));
             }
 
-            mir::StatementKind::LlvmInlineAsm(ref asm) => {
-                for (output, kind) in iter::zip(&*asm.outputs, &asm.asm.outputs) {
-                    if !kind.is_indirect && !kind.is_rw {
-                        self.kill_borrows_on_place(trans, *output);
-                    }
-                }
-            }
-
             mir::StatementKind::FakeRead(..)
             | mir::StatementKind::SetDiscriminant { .. }
             | mir::StatementKind::StorageLive(..)
diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs
index 70acbc9ee2d..eec994f88b9 100644
--- a/compiler/rustc_borrowck/src/def_use.rs
+++ b/compiler/rustc_borrowck/src/def_use.rs
@@ -16,9 +16,6 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
 
         PlaceContext::MutatingUse(MutatingUseContext::Store) |
 
-        // This is potentially both a def and a use...
-        PlaceContext::MutatingUse(MutatingUseContext::LlvmAsmOutput) |
-
         // We let Call define the result in both the success and
         // unwind cases. This is not really correct, however it
         // does not seem to be observable due to the way that we
diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs
index c03e4d8a448..820fc2e7e4a 100644
--- a/compiler/rustc_borrowck/src/invalidation.rs
+++ b/compiler/rustc_borrowck/src/invalidation.rs
@@ -5,12 +5,11 @@ use rustc_middle::mir::{BorrowKind, Mutability, Operand};
 use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
 use rustc_middle::mir::{Statement, StatementKind};
 use rustc_middle::ty::TyCtxt;
-use std::iter;
 
 use crate::{
     borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, path_utils::*, AccessDepth,
     Activation, ArtificialField, BorrowIndex, Deep, JustWrite, LocalMutationIsAllowed, MutateMode,
-    Read, ReadKind, ReadOrWrite, Reservation, Shallow, Write, WriteAndRead, WriteKind,
+    Read, ReadKind, ReadOrWrite, Reservation, Shallow, Write, WriteKind,
 };
 
 pub(super) fn generate_invalidates<'tcx>(
@@ -67,30 +66,6 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
             StatementKind::SetDiscriminant { place, variant_index: _ } => {
                 self.mutate_place(location, **place, Shallow(None), JustWrite);
             }
-            StatementKind::LlvmInlineAsm(asm) => {
-                for (o, output) in iter::zip(&asm.asm.outputs, &*asm.outputs) {
-                    if o.is_indirect {
-                        // FIXME(eddyb) indirect inline asm outputs should
-                        // be encoded through MIR place derefs instead.
-                        self.access_place(
-                            location,
-                            *output,
-                            (Deep, Read(ReadKind::Copy)),
-                            LocalMutationIsAllowed::No,
-                        );
-                    } else {
-                        self.mutate_place(
-                            location,
-                            *output,
-                            if o.is_rw { Deep } else { Shallow(None) },
-                            if o.is_rw { WriteAndRead } else { JustWrite },
-                        );
-                    }
-                }
-                for (_, input) in asm.inputs.iter() {
-                    self.consume_operand(location, input);
-                }
-            }
             StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
                 ref src,
                 ref dst,
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index fe34d6e7ca9..c9fc7b690c1 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -40,7 +40,6 @@ use either::Either;
 use smallvec::SmallVec;
 use std::cell::RefCell;
 use std::collections::BTreeMap;
-use std::iter;
 use std::mem;
 use std::rc::Rc;
 
@@ -55,7 +54,7 @@ use rustc_mir_dataflow::MoveDataParamEnv;
 use self::diagnostics::{AccessKind, RegionName};
 use self::location::LocationTable;
 use self::prefixes::PrefixSet;
-use self::MutateMode::{JustWrite, WriteAndRead};
+use self::MutateMode::JustWrite;
 use facts::AllFacts;
 
 use self::path_utils::*;
@@ -653,39 +652,6 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
             StatementKind::SetDiscriminant { place, variant_index: _ } => {
                 self.mutate_place(location, (**place, span), Shallow(None), JustWrite, flow_state);
             }
-            StatementKind::LlvmInlineAsm(ref asm) => {
-                for (o, output) in iter::zip(&asm.asm.outputs, &*asm.outputs) {
-                    if o.is_indirect {
-                        // FIXME(eddyb) indirect inline asm outputs should
-                        // be encoded through MIR place derefs instead.
-                        self.access_place(
-                            location,
-                            (*output, o.span),
-                            (Deep, Read(ReadKind::Copy)),
-                            LocalMutationIsAllowed::No,
-                            flow_state,
-                        );
-                        self.check_if_path_or_subpath_is_moved(
-                            location,
-                            InitializationRequiringAction::Use,
-                            (output.as_ref(), o.span),
-                            flow_state,
-                        );
-                    } else {
-                        self.mutate_place(
-                            location,
-                            (*output, o.span),
-                            if o.is_rw { Deep } else { Shallow(None) },
-                            if o.is_rw { WriteAndRead } else { JustWrite },
-                            flow_state,
-                        );
-                    }
-                }
-                for (_, input) in asm.inputs.iter() {
-                    self.consume_operand(location, (input, span), flow_state);
-                }
-            }
-
             StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
                 ..
             }) => {
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 1f745f977d4..a58d506eebb 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1477,7 +1477,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             StatementKind::FakeRead(..)
             | StatementKind::StorageLive(..)
             | StatementKind::StorageDead(..)
-            | StatementKind::LlvmInlineAsm { .. }
             | StatementKind::Retag { .. }
             | StatementKind::Coverage(..)
             | StatementKind::Nop => {}
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 1a93b9be99e..304c74e6326 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -50,15 +50,6 @@ pub fn parse_asm_args<'a>(
         return Err(diag.struct_span_err(sp, "requires at least a template string argument"));
     }
 
-    // Detect use of the legacy llvm_asm! syntax (which used to be called asm!)
-    if !is_global_asm && p.look_ahead(1, |t| *t == token::Colon || *t == token::ModSep) {
-        let mut err =
-            diag.struct_span_err(sp, "the legacy LLVM-style asm! syntax is no longer supported");
-        err.note("consider migrating to the new asm! syntax specified in RFC 2873");
-        err.note("alternatively, switch to llvm_asm! to keep your code working as it is");
-        return Err(err);
-    }
-
     let first_template = p.parse_expr()?;
     let mut args = AsmArgs {
         templates: vec![first_template],
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 8c3ef2864f4..65f785b9097 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -33,7 +33,6 @@ mod env;
 mod format;
 mod format_foreign;
 mod global_allocator;
-mod llvm_asm;
 mod log_syntax;
 mod panic;
 mod source_util;
@@ -78,7 +77,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         include_str: source_util::expand_include_str,
         include: source_util::expand_include,
         line: source_util::expand_line,
-        llvm_asm: llvm_asm::expand_llvm_asm,
         log_syntax: log_syntax::expand_log_syntax,
         module_path: source_util::expand_mod,
         option_env: env::expand_option_env,
diff --git a/compiler/rustc_builtin_macros/src/llvm_asm.rs b/compiler/rustc_builtin_macros/src/llvm_asm.rs
deleted file mode 100644
index d72bfa660e5..00000000000
--- a/compiler/rustc_builtin_macros/src/llvm_asm.rs
+++ /dev/null
@@ -1,303 +0,0 @@
-// Llvm-style inline assembly support.
-//
-use State::*;
-
-use rustc_ast as ast;
-use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Token};
-use rustc_ast::tokenstream::{self, TokenStream};
-use rustc_ast::LlvmAsmDialect;
-use rustc_errors::{struct_span_err, DiagnosticBuilder, PResult};
-use rustc_expand::base::*;
-use rustc_parse::parser::Parser;
-use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
-
-enum State {
-    Asm,
-    Outputs,
-    Inputs,
-    Clobbers,
-    Options,
-    StateNone,
-}
-
-impl State {
-    fn next(&self) -> State {
-        match *self {
-            Asm => Outputs,
-            Outputs => Inputs,
-            Inputs => Clobbers,
-            Clobbers => Options,
-            Options => StateNone,
-            StateNone => StateNone,
-        }
-    }
-}
-
-const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel];
-
-pub fn expand_llvm_asm<'cx>(
-    cx: &'cx mut ExtCtxt<'_>,
-    sp: Span,
-    tts: TokenStream,
-) -> Box<dyn MacResult + 'cx> {
-    let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
-        Ok(Some(inline_asm)) => inline_asm,
-        Ok(None) => return DummyResult::any(sp),
-        Err(mut err) => {
-            err.emit();
-            return DummyResult::any(sp);
-        }
-    };
-
-    // If there are no outputs, the inline assembly is executed just for its side effects,
-    // so ensure that it is volatile
-    if inline_asm.outputs.is_empty() {
-        inline_asm.volatile = true;
-    }
-
-    MacEager::expr(P(ast::Expr {
-        id: ast::DUMMY_NODE_ID,
-        kind: ast::ExprKind::LlvmInlineAsm(P(inline_asm)),
-        span: cx.with_def_site_ctxt(sp),
-        attrs: ast::AttrVec::new(),
-        tokens: None,
-    }))
-}
-
-fn parse_asm_str<'a>(p: &mut Parser<'a>) -> PResult<'a, Symbol> {
-    match p.parse_str_lit() {
-        Ok(str_lit) => Ok(str_lit.symbol_unescaped),
-        Err(opt_lit) => {
-            let span = opt_lit.map_or(p.token.span, |lit| lit.span);
-            let mut err = p.sess.span_diagnostic.struct_span_err(span, "expected string literal");
-            err.span_label(span, "not a string literal");
-            Err(err)
-        }
-    }
-}
-
-fn parse_inline_asm<'a>(
-    cx: &mut ExtCtxt<'a>,
-    sp: Span,
-    tts: TokenStream,
-) -> Result<Option<ast::LlvmInlineAsm>, DiagnosticBuilder<'a>> {
-    // Split the tts before the first colon, to avoid `llvm_asm!("x": y)`  being
-    // parsed as `llvm_asm!(z)` with `z = "x": y` which is type ascription.
-    let first_colon = tts
-        .trees()
-        .position(|tt| {
-            matches!(
-                tt,
-                tokenstream::TokenTree::Token(Token { kind: token::Colon | token::ModSep, .. })
-            )
-        })
-        .unwrap_or(tts.len());
-    let mut p = cx.new_parser_from_tts(tts.trees().skip(first_colon).collect());
-    let mut asm = kw::Empty;
-    let mut asm_str_style = None;
-    let mut outputs = Vec::new();
-    let mut inputs = Vec::new();
-    let mut clobs = Vec::new();
-    let mut volatile = false;
-    let mut alignstack = false;
-    let mut dialect = LlvmAsmDialect::Att;
-
-    let mut state = Asm;
-
-    'statement: loop {
-        match state {
-            Asm => {
-                if asm_str_style.is_some() {
-                    // If we already have a string with instructions,
-                    // ending up in Asm state again is an error.
-                    return Err(struct_span_err!(
-                        cx.sess.parse_sess.span_diagnostic,
-                        sp,
-                        E0660,
-                        "malformed inline assembly"
-                    ));
-                }
-                // Nested parser, stop before the first colon (see above).
-                let mut p2 = cx.new_parser_from_tts(tts.trees().take(first_colon).collect());
-
-                if p2.token == token::Eof {
-                    let mut err =
-                        cx.struct_span_err(sp, "macro requires a string literal as an argument");
-                    err.span_label(sp, "string literal required");
-                    return Err(err);
-                }
-
-                let expr = p2.parse_expr()?;
-                let (s, style) =
-                    match expr_to_string(cx, expr, "inline assembly must be a string literal") {
-                        Some((s, st)) => (s, st),
-                        None => return Ok(None),
-                    };
-
-                // This is most likely malformed.
-                if p2.token != token::Eof {
-                    let mut extra_tts = p2.parse_all_token_trees()?;
-                    extra_tts.extend(tts.trees().skip(first_colon));
-                    p = cx.new_parser_from_tts(extra_tts.into_iter().collect());
-                }
-
-                asm = s;
-                asm_str_style = Some(style);
-            }
-            Outputs => {
-                while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
-                    if !outputs.is_empty() {
-                        p.eat(&token::Comma);
-                    }
-
-                    let constraint = parse_asm_str(&mut p)?;
-
-                    let span = p.prev_token.span;
-
-                    p.expect(&token::OpenDelim(token::Paren))?;
-                    let expr = p.parse_expr()?;
-                    p.expect(&token::CloseDelim(token::Paren))?;
-
-                    // Expands a read+write operand into two operands.
-                    //
-                    // Use '+' modifier when you want the same expression
-                    // to be both an input and an output at the same time.
-                    // It's the opposite of '=&' which means that the memory
-                    // cannot be shared with any other operand (usually when
-                    // a register is clobbered early.)
-                    let constraint_str = constraint.as_str();
-                    let mut ch = constraint_str.chars();
-                    let output = match ch.next() {
-                        Some('=') => None,
-                        Some('+') => Some(Symbol::intern(&format!("={}", ch.as_str()))),
-                        _ => {
-                            struct_span_err!(
-                                cx.sess.parse_sess.span_diagnostic,
-                                span,
-                                E0661,
-                                "output operand constraint lacks '=' or '+'"
-                            )
-                            .emit();
-                            None
-                        }
-                    };
-
-                    let is_rw = output.is_some();
-                    let is_indirect = constraint_str.contains('*');
-                    outputs.push(ast::LlvmInlineAsmOutput {
-                        constraint: output.unwrap_or(constraint),
-                        expr,
-                        is_rw,
-                        is_indirect,
-                    });
-                }
-            }
-            Inputs => {
-                while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
-                    if !inputs.is_empty() {
-                        p.eat(&token::Comma);
-                    }
-
-                    let constraint = parse_asm_str(&mut p)?;
-
-                    if constraint.as_str().starts_with('=') {
-                        struct_span_err!(
-                            cx.sess.parse_sess.span_diagnostic,
-                            p.prev_token.span,
-                            E0662,
-                            "input operand constraint contains '='"
-                        )
-                        .emit();
-                    } else if constraint.as_str().starts_with('+') {
-                        struct_span_err!(
-                            cx.sess.parse_sess.span_diagnostic,
-                            p.prev_token.span,
-                            E0663,
-                            "input operand constraint contains '+'"
-                        )
-                        .emit();
-                    }
-
-                    p.expect(&token::OpenDelim(token::Paren))?;
-                    let input = p.parse_expr()?;
-                    p.expect(&token::CloseDelim(token::Paren))?;
-
-                    inputs.push((constraint, input));
-                }
-            }
-            Clobbers => {
-                while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
-                    if !clobs.is_empty() {
-                        p.eat(&token::Comma);
-                    }
-
-                    let s = parse_asm_str(&mut p)?;
-
-                    if OPTIONS.iter().any(|&opt| s == opt) {
-                        cx.span_warn(p.prev_token.span, "expected a clobber, found an option");
-                    } else if s.as_str().starts_with('{') || s.as_str().ends_with('}') {
-                        struct_span_err!(
-                            cx.sess.parse_sess.span_diagnostic,
-                            p.prev_token.span,
-                            E0664,
-                            "clobber should not be surrounded by braces"
-                        )
-                        .emit();
-                    }
-
-                    clobs.push(s);
-                }
-            }
-            Options => {
-                let option = parse_asm_str(&mut p)?;
-
-                if option == sym::volatile {
-                    // Indicates that the inline assembly has side effects
-                    // and must not be optimized out along with its outputs.
-                    volatile = true;
-                } else if option == sym::alignstack {
-                    alignstack = true;
-                } else if option == sym::intel {
-                    dialect = LlvmAsmDialect::Intel;
-                } else {
-                    cx.span_warn(p.prev_token.span, "unrecognized option");
-                }
-
-                if p.token == token::Comma {
-                    p.eat(&token::Comma);
-                }
-            }
-            StateNone => (),
-        }
-
-        loop {
-            // MOD_SEP is a double colon '::' without space in between.
-            // When encountered, the state must be advanced twice.
-            match (&p.token.kind, state.next(), state.next().next()) {
-                (&token::Colon, StateNone, _) | (&token::ModSep, _, StateNone) => {
-                    p.bump();
-                    break 'statement;
-                }
-                (&token::Colon, st, _) | (&token::ModSep, _, st) => {
-                    p.bump();
-                    state = st;
-                }
-                (&token::Eof, ..) => break 'statement,
-                _ => break,
-            }
-        }
-    }
-
-    Ok(Some(ast::LlvmInlineAsm {
-        asm,
-        asm_str_style: asm_str_style.unwrap(),
-        outputs,
-        inputs,
-        clobbers: clobs,
-        volatile,
-        alignstack,
-        dialect,
-    }))
-}
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index b16f5af66f2..5a889734f21 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -749,18 +749,6 @@ fn codegen_stmt<'tcx>(
         | StatementKind::Retag { .. }
         | StatementKind::AscribeUserType(..) => {}
 
-        StatementKind::LlvmInlineAsm(asm) => {
-            match asm.asm.asm.as_str().trim() {
-                "" => {
-                    // Black box
-                }
-                _ => fx.tcx.sess.span_fatal(
-                    stmt.source_info.span,
-                    "Legacy `llvm_asm!` inline assembly is not supported. \
-                    Try using the new `asm!` instead.",
-                ),
-            }
-        }
         StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"),
         StatementKind::CopyNonOverlapping(inner) => {
             let dst = codegen_operand(fx, &inner.dst);
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index 9a6c45ae98d..7ef09a1a614 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -506,7 +506,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
                         {
                             return None;
                         }
-                        StatementKind::LlvmInlineAsm(_) | StatementKind::CopyNonOverlapping(_) => {
+                        StatementKind::CopyNonOverlapping(_) => {
                             return None;
                         } // conservative handling
                         StatementKind::Assign(_)
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 453bcd601d3..d620b24e067 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -4,7 +4,6 @@ use rustc_codegen_ssa::mir::operand::OperandValue;
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::{AsmBuilderMethods, AsmMethods, BaseTypeMethods, BuilderMethods, GlobalAsmOperandRef, InlineAsmOperandRef};
 
-use rustc_hir::LlvmInlineAsmInner;
 use rustc_middle::{bug, ty::Instance};
 use rustc_span::{Span, Symbol};
 use rustc_target::asm::*;
@@ -106,17 +105,6 @@ enum ConstraintOrRegister {
 
 
 impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
-    fn codegen_llvm_inline_asm(&mut self, _ia: &LlvmInlineAsmInner, _outputs: Vec<PlaceRef<'tcx, RValue<'gcc>>>, _inputs: Vec<RValue<'gcc>>, span: Span) -> bool {
-        self.sess().struct_span_err(span, "GCC backend does not support `llvm_asm!`")
-            .help("consider using the `asm!` macro instead")
-            .emit();
-
-        // We return `true` even if we've failed to generate the asm
-        // because we want to suppress the "malformed inline assembly" error
-        // generated by the frontend.
-        true
-    }
-
     fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], _instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) {
         if options.contains(InlineAsmOptions::MAY_UNWIND) {
             self.sess()
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index caf16c1939d..8335f841bec 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -7,13 +7,10 @@ use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 
-use rustc_ast::LlvmAsmDialect;
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_codegen_ssa::mir::operand::OperandValue;
-use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_hir as hir;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::{bug, span_bug, ty::Instance};
 use rustc_span::{Pos, Span, Symbol};
@@ -24,100 +21,6 @@ use libc::{c_char, c_uint};
 use tracing::debug;
 
 impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
-    fn codegen_llvm_inline_asm(
-        &mut self,
-        ia: &hir::LlvmInlineAsmInner,
-        outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
-        mut inputs: Vec<&'ll Value>,
-        span: Span,
-    ) -> bool {
-        let mut ext_constraints = vec![];
-        let mut output_types = vec![];
-
-        // Prepare the output operands
-        let mut indirect_outputs = vec![];
-        for (i, (out, &place)) in ia.outputs.iter().zip(&outputs).enumerate() {
-            if out.is_rw {
-                let operand = self.load_operand(place);
-                if let OperandValue::Immediate(_) = operand.val {
-                    inputs.push(operand.immediate());
-                }
-                ext_constraints.push(i.to_string());
-            }
-            if out.is_indirect {
-                let operand = self.load_operand(place);
-                if let OperandValue::Immediate(_) = operand.val {
-                    indirect_outputs.push(operand.immediate());
-                }
-            } else {
-                output_types.push(place.layout.llvm_type(self.cx));
-            }
-        }
-        if !indirect_outputs.is_empty() {
-            indirect_outputs.extend_from_slice(&inputs);
-            inputs = indirect_outputs;
-        }
-
-        let clobbers = ia.clobbers.iter().map(|s| format!("~{{{}}}", &s));
-
-        // Default per-arch clobbers
-        // Basically what clang does
-        let arch_clobbers = match &self.sess().target.arch[..] {
-            "x86" | "x86_64" => &["~{dirflag}", "~{fpsr}", "~{flags}"][..],
-            "mips" | "mips64" => &["~{$1}"],
-            _ => &[],
-        };
-
-        let all_constraints = ia
-            .outputs
-            .iter()
-            .map(|out| out.constraint.to_string())
-            .chain(ia.inputs.iter().map(|s| s.to_string()))
-            .chain(ext_constraints)
-            .chain(clobbers)
-            .chain(arch_clobbers.iter().map(|s| (*s).to_string()))
-            .collect::<Vec<String>>()
-            .join(",");
-
-        debug!("Asm Constraints: {}", &all_constraints);
-
-        // Depending on how many outputs we have, the return type is different
-        let num_outputs = output_types.len();
-        let output_type = match num_outputs {
-            0 => self.type_void(),
-            1 => output_types[0],
-            _ => self.type_struct(&output_types, false),
-        };
-
-        let asm = ia.asm.as_str();
-        let r = inline_asm_call(
-            self,
-            &asm,
-            &all_constraints,
-            &inputs,
-            output_type,
-            ia.volatile,
-            ia.alignstack,
-            ia.dialect,
-            &[span],
-            false,
-            None,
-        );
-        if r.is_none() {
-            return false;
-        }
-        let r = r.unwrap();
-
-        // Again, based on how many outputs we have
-        let outputs = ia.outputs.iter().zip(&outputs).filter(|&(o, _)| !o.is_indirect);
-        for (i, (_, &place)) in outputs.enumerate() {
-            let v = if num_outputs == 1 { r } else { self.extract_value(r, i as u64) };
-            OperandValue::Immediate(v).store(self, place);
-        }
-
-        true
-    }
-
     fn codegen_inline_asm(
         &mut self,
         template: &[InlineAsmTemplatePiece],
@@ -349,9 +252,9 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             InlineAsmArch::X86 | InlineAsmArch::X86_64
                 if !options.contains(InlineAsmOptions::ATT_SYNTAX) =>
             {
-                LlvmAsmDialect::Intel
+                llvm::AsmDialect::Intel
             }
-            _ => LlvmAsmDialect::Att,
+            _ => llvm::AsmDialect::Att,
         };
         let result = inline_asm_call(
             self,
@@ -455,7 +358,7 @@ pub(crate) fn inline_asm_call<'ll>(
     output: &'ll llvm::Type,
     volatile: bool,
     alignstack: bool,
-    dia: LlvmAsmDialect,
+    dia: llvm::AsmDialect,
     line_spans: &[Span],
     unwind: bool,
     dest_catch_funclet: Option<(
@@ -498,7 +401,7 @@ pub(crate) fn inline_asm_call<'ll>(
                 cons.len(),
                 volatile,
                 alignstack,
-                llvm::AsmDialect::from_generic(dia),
+                dia,
                 can_throw,
             );
 
@@ -522,7 +425,7 @@ pub(crate) fn inline_asm_call<'ll>(
             // we just encode the start position of each line.
             // FIXME: Figure out a way to pass the entire line spans.
             let mut srcloc = vec![];
-            if dia == LlvmAsmDialect::Intel && line_spans.len() > 1 {
+            if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
                 // LLVM inserts an extra line to add the ".intel_syntax", so add
                 // a dummy srcloc entry for it.
                 //
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 1e795efa2e1..cebb6d13c4e 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -7,7 +7,6 @@ use crate::type_of::LayoutLlvmExt;
 use crate::va_arg::emit_va_arg;
 use crate::value::Value;
 
-use rustc_ast as ast;
 use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh};
 use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
@@ -351,7 +350,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     self.type_void(),
                     true,
                     false,
-                    ast::LlvmAsmDialect::Att,
+                    llvm::AsmDialect::Att,
                     &[span],
                     false,
                     None,
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index f2782f84f55..bc8d7b3e9e2 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -423,22 +423,13 @@ pub enum MetadataType {
 }
 
 /// LLVMRustAsmDialect
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
 pub enum AsmDialect {
     Att,
     Intel,
 }
 
-impl AsmDialect {
-    pub fn from_generic(asm: rustc_ast::LlvmAsmDialect) -> Self {
-        match asm {
-            rustc_ast::LlvmAsmDialect::Att => AsmDialect::Att,
-            rustc_ast::LlvmAsmDialect::Intel => AsmDialect::Intel,
-        }
-    }
-}
-
 /// LLVMRustCodeGenOptLevel
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index b1b3f1d6d81..d768d4920c5 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -211,7 +211,6 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
 
             PlaceContext::MutatingUse(
                 MutatingUseContext::Store
-                | MutatingUseContext::LlvmAsmOutput
                 | MutatingUseContext::AsmOutput
                 | MutatingUseContext::Borrow
                 | MutatingUseContext::AddressOf
diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index 2c96987d339..773dc2adcfa 100644
--- a/compiler/rustc_codegen_ssa/src/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
@@ -1,9 +1,7 @@
-use rustc_errors::struct_span_err;
 use rustc_middle::mir;
 
 use super::FunctionCx;
 use super::LocalRef;
-use super::OperandValue;
 use crate::traits::BuilderMethods;
 use crate::traits::*;
 
@@ -66,51 +64,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
                 bx
             }
-            mir::StatementKind::LlvmInlineAsm(ref asm) => {
-                let outputs = asm
-                    .outputs
-                    .iter()
-                    .map(|output| self.codegen_place(&mut bx, output.as_ref()))
-                    .collect();
-
-                let input_vals = asm.inputs.iter().fold(
-                    Vec::with_capacity(asm.inputs.len()),
-                    |mut acc, (span, input)| {
-                        let op = self.codegen_operand(&mut bx, input);
-                        if let OperandValue::Immediate(_) = op.val {
-                            acc.push(op.immediate());
-                        } else {
-                            struct_span_err!(
-                                bx.sess(),
-                                span.to_owned(),
-                                E0669,
-                                "invalid value for constraint in inline assembly"
-                            )
-                            .emit();
-                        }
-                        acc
-                    },
-                );
-
-                if input_vals.len() == asm.inputs.len() {
-                    let res = bx.codegen_llvm_inline_asm(
-                        &asm.asm,
-                        outputs,
-                        input_vals,
-                        statement.source_info.span,
-                    );
-                    if !res {
-                        struct_span_err!(
-                            bx.sess(),
-                            statement.source_info.span,
-                            E0668,
-                            "malformed inline assembly"
-                        )
-                        .emit();
-                    }
-                }
-                bx
-            }
             mir::StatementKind::Coverage(box ref coverage) => {
                 self.codegen_coverage(&mut bx, coverage.clone(), statement.source_info.scope);
                 bx
diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs
index 65f3c754d2d..11111a79744 100644
--- a/compiler/rustc_codegen_ssa/src/traits/asm.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs
@@ -3,7 +3,6 @@ use crate::mir::operand::OperandRef;
 use crate::mir::place::PlaceRef;
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_hir::def_id::DefId;
-use rustc_hir::LlvmInlineAsmInner;
 use rustc_middle::ty::Instance;
 use rustc_span::Span;
 use rustc_target::asm::InlineAsmRegOrRegClass;
@@ -43,15 +42,6 @@ pub enum GlobalAsmOperandRef {
 
 pub trait AsmBuilderMethods<'tcx>: BackendTypes {
     /// Take an inline assembly expression and splat it out via LLVM
-    fn codegen_llvm_inline_asm(
-        &mut self,
-        ia: &LlvmInlineAsmInner,
-        outputs: Vec<PlaceRef<'tcx, Self::Value>>,
-        inputs: Vec<Self::Value>,
-        span: Span,
-    ) -> bool;
-
-    /// Take an inline assembly expression and splat it out via LLVM
     fn codegen_inline_asm(
         &mut self,
         template: &[InlineAsmTemplatePiece],
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 3daa1d3c2b3..57ba9b40992 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -140,8 +140,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             // Defined to do nothing. These are added by optimization passes, to avoid changing the
             // size of MIR constantly.
             Nop => {}
-
-            LlvmInlineAsm { .. } => throw_unsup_format!("inline assembly is not supported"),
         }
 
         self.stack_mut()[frame_idx].loc.as_mut().unwrap().statement_index += 1;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index dd749c03934..f619af051ca 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -752,10 +752,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
         self.super_statement(statement, location);
 
         match statement.kind {
-            StatementKind::LlvmInlineAsm { .. } => {
-                self.check_op(ops::InlineAsm);
-            }
-
             StatementKind::Assign(..)
             | StatementKind::SetDiscriminant { .. }
             | StatementKind::FakeRead(..)
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index c3f81a3ab83..22ef0b2dda5 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -352,7 +352,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             StatementKind::SetDiscriminant { .. }
             | StatementKind::StorageLive(..)
             | StatementKind::StorageDead(..)
-            | StatementKind::LlvmInlineAsm(..)
             | StatementKind::Retag(_, _)
             | StatementKind::Coverage(_)
             | StatementKind::Nop => {}
diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs
index edad00ed6a2..27ec4619064 100644
--- a/compiler/rustc_hir/src/arena.rs
+++ b/compiler/rustc_hir/src/arena.rs
@@ -30,7 +30,6 @@ macro_rules! arena_types {
             [] impl_item_ref: rustc_hir::ImplItemRef,
             [] item: rustc_hir::Item<'tcx>,
             [] inline_asm: rustc_hir::InlineAsm<'tcx>,
-            [] llvm_inline_asm: rustc_hir::LlvmInlineAsm<'tcx>,
             [] local: rustc_hir::Local<'tcx>,
             [] mod_: rustc_hir::Mod<'tcx>,
             [] owner_info: rustc_hir::OwnerInfo<'tcx>,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index f03d8eea40b..0d6ef7734e4 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -5,8 +5,8 @@ use crate::intravisit::FnKind;
 use crate::LangItem;
 
 use rustc_ast::util::parser::ExprPrecedence;
-use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
-use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, TraitObjectSyntax, UintTy};
+use rustc_ast::{self as ast, CrateSugar};
+use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
 pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
 pub use rustc_ast::{CaptureBy, Movability, Mutability};
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
@@ -1471,7 +1471,6 @@ impl Expr<'_> {
             ExprKind::Continue(..) => ExprPrecedence::Continue,
             ExprKind::Ret(..) => ExprPrecedence::Ret,
             ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
-            ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
             ExprKind::Struct(..) => ExprPrecedence::Struct,
             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
             ExprKind::Yield(..) => ExprPrecedence::Yield,
@@ -1531,7 +1530,6 @@ impl Expr<'_> {
             | ExprKind::Loop(..)
             | ExprKind::Assign(..)
             | ExprKind::InlineAsm(..)
-            | ExprKind::LlvmInlineAsm(..)
             | ExprKind::AssignOp(..)
             | ExprKind::Lit(_)
             | ExprKind::ConstBlock(..)
@@ -1614,7 +1612,6 @@ impl Expr<'_> {
             | ExprKind::Loop(..)
             | ExprKind::Assign(..)
             | ExprKind::InlineAsm(..)
-            | ExprKind::LlvmInlineAsm(..)
             | ExprKind::AssignOp(..)
             | ExprKind::ConstBlock(..)
             | ExprKind::Box(..)
@@ -1755,8 +1752,6 @@ pub enum ExprKind<'hir> {
 
     /// Inline assembly (from `asm!`), with its outputs and inputs.
     InlineAsm(&'hir InlineAsm<'hir>),
-    /// Inline assembly (from `llvm_asm!`), with its outputs and inputs.
-    LlvmInlineAsm(&'hir LlvmInlineAsm<'hir>),
 
     /// A struct or struct-like variant literal expression.
     ///
@@ -2368,36 +2363,6 @@ pub struct InlineAsm<'hir> {
     pub line_spans: &'hir [Span],
 }
 
-#[derive(Copy, Clone, Encodable, Decodable, Debug, Hash, HashStable_Generic, PartialEq)]
-pub struct LlvmInlineAsmOutput {
-    pub constraint: Symbol,
-    pub is_rw: bool,
-    pub is_indirect: bool,
-    pub span: Span,
-}
-
-// NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR,
-// it needs to be `Clone` and `Decodable` and use plain `Vec<T>` instead of
-// arena-allocated slice.
-#[derive(Clone, Encodable, Decodable, Debug, Hash, HashStable_Generic, PartialEq)]
-pub struct LlvmInlineAsmInner {
-    pub asm: Symbol,
-    pub asm_str_style: StrStyle,
-    pub outputs: Vec<LlvmInlineAsmOutput>,
-    pub inputs: Vec<Symbol>,
-    pub clobbers: Vec<Symbol>,
-    pub volatile: bool,
-    pub alignstack: bool,
-    pub dialect: LlvmAsmDialect,
-}
-
-#[derive(Debug, HashStable_Generic)]
-pub struct LlvmInlineAsm<'hir> {
-    pub inner: LlvmInlineAsmInner,
-    pub outputs_exprs: &'hir [Expr<'hir>],
-    pub inputs_exprs: &'hir [Expr<'hir>],
-}
-
 /// Represents a parameter in a function header.
 #[derive(Debug, HashStable_Generic)]
 pub struct Param<'hir> {
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index d0eee422202..ca64af2c93c 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -1251,10 +1251,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
         ExprKind::InlineAsm(ref asm) => {
             walk_inline_asm(visitor, asm);
         }
-        ExprKind::LlvmInlineAsm(ref asm) => {
-            walk_list!(visitor, visit_expr, asm.outputs_exprs);
-            walk_list!(visitor, visit_expr, asm.inputs_exprs);
-        }
         ExprKind::Yield(ref subexpression, _) => {
             visitor.visit_expr(subexpression);
         }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 4c9e2d7fe42..bf2dae5edf1 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1581,67 +1581,6 @@ impl<'a> State<'a> {
                 self.word("asm!");
                 self.print_inline_asm(asm);
             }
-            hir::ExprKind::LlvmInlineAsm(ref a) => {
-                let i = &a.inner;
-                self.word("llvm_asm!");
-                self.popen();
-                self.print_symbol(i.asm, i.asm_str_style);
-                self.word_space(":");
-
-                let mut out_idx = 0;
-                self.commasep(Inconsistent, &i.outputs, |s, out| {
-                    let constraint = out.constraint.as_str();
-                    let mut ch = constraint.chars();
-                    match ch.next() {
-                        Some('=') if out.is_rw => {
-                            s.print_string(&format!("+{}", ch.as_str()), ast::StrStyle::Cooked)
-                        }
-                        _ => s.print_string(&constraint, ast::StrStyle::Cooked),
-                    }
-                    s.popen();
-                    s.print_expr(&a.outputs_exprs[out_idx]);
-                    s.pclose();
-                    out_idx += 1;
-                });
-                self.space();
-                self.word_space(":");
-
-                let mut in_idx = 0;
-                self.commasep(Inconsistent, &i.inputs, |s, &co| {
-                    s.print_symbol(co, ast::StrStyle::Cooked);
-                    s.popen();
-                    s.print_expr(&a.inputs_exprs[in_idx]);
-                    s.pclose();
-                    in_idx += 1;
-                });
-                self.space();
-                self.word_space(":");
-
-                self.commasep(Inconsistent, &i.clobbers, |s, &co| {
-                    s.print_symbol(co, ast::StrStyle::Cooked);
-                });
-
-                let mut options = vec![];
-                if i.volatile {
-                    options.push("volatile");
-                }
-                if i.alignstack {
-                    options.push("alignstack");
-                }
-                if i.dialect == ast::LlvmAsmDialect::Intel {
-                    options.push("intel");
-                }
-
-                if !options.is_empty() {
-                    self.space();
-                    self.word_space(":");
-                    self.commasep(Inconsistent, &options, |s, &co| {
-                        s.print_string(co, ast::StrStyle::Cooked);
-                    });
-                }
-
-                self.pclose();
-            }
             hir::ExprKind::Yield(ref expr, _) => {
                 self.word_space("yield");
                 self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 6d1d9dd9720..38c379919d2 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1565,10 +1565,6 @@ pub enum StatementKind<'tcx> {
     /// End the current live range for the storage of the local.
     StorageDead(Local),
 
-    /// Executes a piece of inline Assembly. Stored in a Box to keep the size
-    /// of `StatementKind` low.
-    LlvmInlineAsm(Box<LlvmInlineAsm<'tcx>>),
-
     /// Retag references in the given place, ensuring they got fresh tags. This is
     /// part of the Stacked Borrows model. These statements are currently only interpreted
     /// by miri and only generated when "-Z mir-emit-retag" is passed.
@@ -1688,13 +1684,6 @@ pub enum FakeReadCause {
     ForIndex,
 }
 
-#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
-pub struct LlvmInlineAsm<'tcx> {
-    pub asm: hir::LlvmInlineAsmInner,
-    pub outputs: Box<[Place<'tcx>]>,
-    pub inputs: Box<[(Span, Operand<'tcx>)]>,
-}
-
 impl Debug for Statement<'_> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
         use self::StatementKind::*;
@@ -1719,9 +1708,6 @@ impl Debug for Statement<'_> {
             SetDiscriminant { ref place, variant_index } => {
                 write!(fmt, "discriminant({:?}) = {:?}", place, variant_index)
             }
-            LlvmInlineAsm(ref asm) => {
-                write!(fmt, "llvm_asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs)
-            }
             AscribeUserType(box (ref place, ref c_ty), ref variance) => {
                 write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
             }
diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs
index 507f9971981..589e1579d39 100644
--- a/compiler/rustc_middle/src/mir/spanview.rs
+++ b/compiler/rustc_middle/src/mir/spanview.rs
@@ -245,7 +245,6 @@ pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str {
         SetDiscriminant { .. } => "SetDiscriminant",
         StorageLive(..) => "StorageLive",
         StorageDead(..) => "StorageDead",
-        LlvmInlineAsm(..) => "LlvmInlineAsm",
         Retag(..) => "Retag",
         AscribeUserType(..) => "AscribeUserType",
         Coverage(..) => "Coverage",
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index f301c68a7c0..4452ac5e3e0 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -408,19 +408,6 @@ macro_rules! make_mir_visitor {
                             location
                         );
                     }
-                    StatementKind::LlvmInlineAsm(asm) => {
-                        for output in & $($mutability)? asm.outputs[..] {
-                            self.visit_place(
-                                output,
-                                PlaceContext::MutatingUse(MutatingUseContext::LlvmAsmOutput),
-                                location
-                            );
-                        }
-                        for (span, input) in & $($mutability)? asm.inputs[..] {
-                            self.visit_span(span);
-                            self.visit_operand(input, location);
-                        }
-                    }
                     StatementKind::Retag(kind, place) => {
                         self.visit_retag(kind, place, location);
                     }
@@ -1178,10 +1165,6 @@ pub enum NonMutatingUseContext {
 pub enum MutatingUseContext {
     /// Appears as LHS of an assignment.
     Store,
-    /// Can often be treated as a `Store`, but needs to be separate because
-    /// ASM is allowed to read outputs as well, so a `Store`-`LlvmAsmOutput` sequence
-    /// cannot be simplified the way a `Store`-`Store` can be.
-    LlvmAsmOutput,
     /// Output operand of an inline assembly block.
     AsmOutput,
     /// Destination of a call.
@@ -1271,7 +1254,6 @@ impl PlaceContext {
             PlaceContext::MutatingUse(
                 MutatingUseContext::Store
                     | MutatingUseContext::Call
-                    | MutatingUseContext::LlvmAsmOutput
                     | MutatingUseContext::AsmOutput,
             )
         )
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index d2e3ce97d12..eef42666f2a 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -431,12 +431,6 @@ pub enum ExprKind<'tcx> {
     },
     /// An expression taking a reference to a thread local.
     ThreadLocalRef(DefId),
-    /// Inline LLVM assembly, i.e. `llvm_asm!()`.
-    LlvmInlineAsm {
-        asm: &'tcx hir::LlvmInlineAsmInner,
-        outputs: Box<[ExprId]>,
-        inputs: Box<[ExprId]>,
-    },
     /// A `yield` expression.
     Yield {
         value: ExprId,
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 7fc15e02fcd..9f9947341c5 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -145,14 +145,6 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
             }
         }
         ThreadLocalRef(_) => {}
-        LlvmInlineAsm { ref outputs, ref inputs, asm: _ } => {
-            for &out_expr in &**outputs {
-                visitor.visit_expr(&visitor.thir()[out_expr]);
-            }
-            for &in_expr in &**inputs {
-                visitor.visit_expr(&visitor.thir()[in_expr]);
-            }
-        }
         Yield { value } => visitor.visit_expr(&visitor.thir()[value]),
     }
 }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 98b1a8b4d76..fe56544dab3 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -225,7 +225,6 @@ TrivialTypeFoldableAndLiftImpls! {
     ::rustc_hir::def_id::DefId,
     ::rustc_hir::def_id::LocalDefId,
     ::rustc_hir::HirId,
-    ::rustc_hir::LlvmInlineAsmInner,
     ::rustc_hir::MatchSource,
     ::rustc_hir::Mutability,
     ::rustc_hir::Unsafety,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index b3126b72bb8..167b3aaed46 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -570,7 +570,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::ConstBlock { .. }
             | ExprKind::StaticRef { .. }
             | ExprKind::InlineAsm { .. }
-            | ExprKind::LlvmInlineAsm { .. }
             | ExprKind::Yield { .. }
             | ExprKind::ThreadLocalRef(_)
             | ExprKind::Call { .. } => {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 9a86d465f98..1dc49256a6a 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -350,7 +350,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::Continue { .. }
             | ExprKind::Return { .. }
             | ExprKind::InlineAsm { .. }
-            | ExprKind::LlvmInlineAsm { .. }
             | ExprKind::PlaceTypeAscription { .. }
             | ExprKind::ValueTypeAscription { .. } => {
                 // these do not have corresponding `Rvalue` variants,
diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs
index fcda52e5581..d31f6ed9384 100644
--- a/compiler/rustc_mir_build/src/build/expr/category.rs
+++ b/compiler/rustc_mir_build/src/build/expr/category.rs
@@ -67,8 +67,7 @@ impl Category {
             | ExprKind::Repeat { .. }
             | ExprKind::Assign { .. }
             | ExprKind::AssignOp { .. }
-            | ExprKind::ThreadLocalRef(_)
-            | ExprKind::LlvmInlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
+            | ExprKind::ThreadLocalRef(_) => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
 
             ExprKind::ConstBlock { .. } | ExprKind::Literal { .. } | ExprKind::StaticRef { .. } => {
                 Some(Category::Constant)
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index d9896ff5ac9..43060ecfced 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -477,9 +477,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             // These cases don't actually need a destination
-            ExprKind::Assign { .. }
-            | ExprKind::AssignOp { .. }
-            | ExprKind::LlvmInlineAsm { .. } => {
+            ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
                 unpack!(block = this.stmt_expr(block, expr, None));
                 this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
                 block.unit()
diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs
index 4245535450a..7419c5b2f75 100644
--- a/compiler/rustc_mir_build/src/build/expr/stmt.rs
+++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs
@@ -101,38 +101,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 BreakableTarget::Return,
                 source_info,
             ),
-            ExprKind::LlvmInlineAsm { asm, ref outputs, ref inputs } => {
-                debug!("stmt_expr LlvmInlineAsm block_context.push(SubExpr) : {:?}", expr);
-                this.block_context.push(BlockFrame::SubExpr);
-                let outputs = outputs
-                    .into_iter()
-                    .copied()
-                    .map(|output| unpack!(block = this.as_place(block, &this.thir[output])))
-                    .collect::<Vec<_>>()
-                    .into_boxed_slice();
-                let inputs = inputs
-                    .into_iter()
-                    .copied()
-                    .map(|input| {
-                        let input = &this.thir[input];
-                        (input.span, unpack!(block = this.as_local_operand(block, &input)))
-                    })
-                    .collect::<Vec<_>>()
-                    .into_boxed_slice();
-                this.cfg.push(
-                    block,
-                    Statement {
-                        source_info,
-                        kind: StatementKind::LlvmInlineAsm(Box::new(LlvmInlineAsm {
-                            asm: asm.clone(),
-                            outputs,
-                            inputs,
-                        })),
-                    },
-                );
-                this.block_context.pop();
-                block.unit()
-            }
             _ => {
                 assert!(
                     statement_scope.is_some(),
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 7940bd1f33d..8ca2449cea9 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -329,7 +329,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             | ExprKind::Box { .. }
             | ExprKind::If { .. }
             | ExprKind::InlineAsm { .. }
-            | ExprKind::LlvmInlineAsm { .. }
             | ExprKind::LogicalOp { .. }
             | ExprKind::Use { .. } => {
                 // We don't need to save the old value and restore it
@@ -377,7 +376,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     self.requires_unsafe(expr.span, DerefOfRawPointer);
                 }
             }
-            ExprKind::InlineAsm { .. } | ExprKind::LlvmInlineAsm { .. } => {
+            ExprKind::InlineAsm { .. } => {
                 self.requires_unsafe(expr.span, UseOfInlineAssembly);
             }
             ExprKind::Adt(box Adt {
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index bdde6b4a356..6865dd202cf 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -570,12 +570,6 @@ impl<'tcx> Cx<'tcx> {
                 line_spans: asm.line_spans,
             },
 
-            hir::ExprKind::LlvmInlineAsm(ref asm) => ExprKind::LlvmInlineAsm {
-                asm: &asm.inner,
-                outputs: self.mirror_exprs(asm.outputs_exprs),
-                inputs: self.mirror_exprs(asm.inputs_exprs),
-            },
-
             hir::ExprKind::ConstBlock(ref anon_const) => {
                 let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
                 let value = ty::Const::from_inline_const(self.tcx, anon_const_def_id);
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index 65c388f8124..4871320fdb5 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -176,7 +176,6 @@ impl DefUse {
             // All other contexts are uses...
             PlaceContext::MutatingUse(
                 MutatingUseContext::AddressOf
-                | MutatingUseContext::LlvmAsmOutput
                 | MutatingUseContext::Borrow
                 | MutatingUseContext::Drop
                 | MutatingUseContext::Retag,
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index 896377f2bc3..60cde6546dc 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -134,11 +134,6 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
             | StatementKind::SetDiscriminant { box place, .. } => {
                 trans.gen(place.local);
             }
-            StatementKind::LlvmInlineAsm(asm) => {
-                for place in &*asm.outputs {
-                    trans.gen(place.local);
-                }
-            }
 
             // Nothing to do for these. Match exhaustively so this fails to compile when new
             // variants are added.
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 2e00b4f9a5e..26bbc34e780 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -4,7 +4,6 @@ use rustc_middle::mir::*;
 use rustc_middle::ty::{self, TyCtxt};
 use smallvec::{smallvec, SmallVec};
 
-use std::iter;
 use std::mem;
 
 use super::abs_domain::Lift;
@@ -293,16 +292,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             StatementKind::FakeRead(box (_, place)) => {
                 self.create_move_path(*place);
             }
-            StatementKind::LlvmInlineAsm(ref asm) => {
-                for (output, kind) in iter::zip(&*asm.outputs, &asm.asm.outputs) {
-                    if !kind.is_indirect {
-                        self.gather_init(output.as_ref(), InitKind::Deep);
-                    }
-                }
-                for (_, input) in asm.inputs.iter() {
-                    self.gather_operand(input);
-                }
-            }
             StatementKind::StorageLive(_) => {}
             StatementKind::StorageDead(local) => {
                 self.gather_move(Place::from(*local));
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index a40c4d1c366..4a773c5772d 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -104,10 +104,6 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
                 // safe (at least as emitted during MIR construction)
             }
 
-            StatementKind::LlvmInlineAsm { .. } => self.require_unsafe(
-                UnsafetyViolationKind::General,
-                UnsafetyViolationDetails::UseOfInlineAssembly,
-            ),
             StatementKind::CopyNonOverlapping(..) => unreachable!(),
         }
         self.super_statement(statement, location);
@@ -208,7 +204,6 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
                             MutatingUseContext::Store
                                 | MutatingUseContext::Drop
                                 | MutatingUseContext::AsmOutput
-                                | MutatingUseContext::LlvmAsmOutput
                         )
                     );
                 // If this is just an assignment, determine if the assigned type needs dropping.
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index e3ff6ad4549..7649fafc355 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -1035,8 +1035,7 @@ impl Visitor<'_> for CanConstProp {
 
             // These could be propagated with a smarter analysis or just some careful thinking about
             // whether they'd be fine right now.
-            MutatingUse(MutatingUseContext::LlvmAsmOutput)
-            | MutatingUse(MutatingUseContext::Yield)
+            MutatingUse(MutatingUseContext::Yield)
             | MutatingUse(MutatingUseContext::Drop)
             | MutatingUse(MutatingUseContext::Retag)
             // These can't ever be propagated under any scheme, as we can't reason about indirect
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index b5356a817f7..a9161580bc6 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -835,7 +835,6 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span>
         | StatementKind::CopyNonOverlapping(..)
         | StatementKind::Assign(_)
         | StatementKind::SetDiscriminant { .. }
-        | StatementKind::LlvmInlineAsm(_)
         | StatementKind::Retag(_, _)
         | StatementKind::AscribeUserType(_, _) => {
             Some(statement.source_info.span)
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 2b382468be0..d469be74641 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -534,25 +534,6 @@ impl<'a> Conflicts<'a> {
             // eliminate the resulting self-assignments automatically.
             StatementKind::Assign(_) => {}
 
-            StatementKind::LlvmInlineAsm(asm) => {
-                // Inputs and outputs must not overlap.
-                for (_, input) in &*asm.inputs {
-                    if let Some(in_place) = input.place() {
-                        if !in_place.is_indirect() {
-                            for out_place in &*asm.outputs {
-                                if !out_place.is_indirect() && !in_place.is_indirect() {
-                                    self.record_local_conflict(
-                                        in_place.local,
-                                        out_place.local,
-                                        "aliasing llvm_asm! operands",
-                                    );
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
             StatementKind::SetDiscriminant { .. }
             | StatementKind::StorageLive(..)
             | StatementKind::StorageDead(..)
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 08247e6f22a..433a1c6ad67 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -1449,9 +1449,6 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> {
                 self.check_assigned_place(*lhs, |this| this.visit_rvalue(rhs, location));
             }
 
-            // FIXME: Does `llvm_asm!` have any aliasing requirements?
-            StatementKind::LlvmInlineAsm(_) => {}
-
             StatementKind::FakeRead(..)
             | StatementKind::SetDiscriminant { .. }
             | StatementKind::StorageLive(_)
diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
index 2a73e341f16..77fb092d580 100644
--- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
+++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
@@ -50,7 +50,6 @@ impl RemoveNoopLandingPads {
 
                 StatementKind::Assign { .. }
                 | StatementKind::SetDiscriminant { .. }
-                | StatementKind::LlvmInlineAsm { .. }
                 | StatementKind::CopyNonOverlapping(..)
                 | StatementKind::Retag { .. } => {
                     return false;
diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs
index 612fce71f91..d265720e182 100644
--- a/compiler/rustc_mir_transform/src/separate_const_switch.rs
+++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs
@@ -239,10 +239,6 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData<
                 }
             }
 
-            // If inline assembly is found, we probably should
-            // not try to analyze the code
-            StatementKind::LlvmInlineAsm(_) => return false,
-
             // These statements have no influence on the place
             // we are interested in
             StatementKind::FakeRead(_)
@@ -320,10 +316,6 @@ fn find_determining_place<'tcx>(
             | StatementKind::CopyNonOverlapping(_)
             | StatementKind::Nop => {}
 
-            // If inline assembly is found, we probably should
-            // not try to analyze the code
-            StatementKind::LlvmInlineAsm(_) => return None,
-
             // If the discriminant is set, it is always set
             // as a constant, so the job is already done.
             // As we are **ignoring projections**, if the place
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index 7992124bacd..7e0c8e233e9 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -483,8 +483,7 @@ impl UsedLocals {
 impl<'tcx> Visitor<'tcx> for UsedLocals {
     fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
         match statement.kind {
-            StatementKind::LlvmInlineAsm(..)
-            | StatementKind::CopyNonOverlapping(..)
+            StatementKind::CopyNonOverlapping(..)
             | StatementKind::Retag(..)
             | StatementKind::Coverage(..)
             | StatementKind::FakeRead(..)
diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs
index 7761d4006d3..d5507fcc78c 100644
--- a/compiler/rustc_mir_transform/src/simplify_try.rs
+++ b/compiler/rustc_mir_transform/src/simplify_try.rs
@@ -631,10 +631,6 @@ impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> {
                     .filter(|(_, bb)| {
                         // Reaching `unreachable` is UB so assume it doesn't happen.
                         bb.terminator().kind != TerminatorKind::Unreachable
-                    // But `asm!(...)` could abort the program,
-                    // so we cannot assume that the `unreachable` terminator itself is reachable.
-                    // FIXME(Centril): use a normalization pass instead of a check.
-                    || bb.statements.iter().any(|stmt| matches!(stmt.kind, StatementKind::LlvmInlineAsm(..)))
                     })
                     .peekable();
 
diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs
index 9e755ab141a..f916ca36217 100644
--- a/compiler/rustc_mir_transform/src/unreachable_prop.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs
@@ -23,23 +23,14 @@ impl MirPass<'_> for UnreachablePropagation {
 
         for (bb, bb_data) in traversal::postorder(body) {
             let terminator = bb_data.terminator();
-            // HACK: If the block contains any asm statement it is not regarded as unreachable.
-            // This is a temporary solution that handles possibly diverging asm statements.
-            // Accompanying testcases: mir-opt/unreachable_asm.rs and mir-opt/unreachable_asm_2.rs
-            let asm_stmt_in_block = || {
-                bb_data.statements.iter().any(|stmt: &Statement<'_>| {
-                    matches!(stmt.kind, StatementKind::LlvmInlineAsm(..))
-                })
-            };
-
-            if terminator.kind == TerminatorKind::Unreachable && !asm_stmt_in_block() {
+            if terminator.kind == TerminatorKind::Unreachable {
                 unreachable_blocks.insert(bb);
             } else {
                 let is_unreachable = |succ: BasicBlock| unreachable_blocks.contains(&succ);
                 let terminator_kind_opt = remove_successors(&terminator.kind, is_unreachable);
 
                 if let Some(terminator_kind) = terminator_kind_opt {
-                    if terminator_kind == TerminatorKind::Unreachable && !asm_stmt_in_block() {
+                    if terminator_kind == TerminatorKind::Unreachable {
                         unreachable_blocks.insert(bb);
                     }
                     replacements.insert(bb, terminator_kind);
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 9ee305b712f..4660d047885 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -103,7 +103,6 @@ use rustc_span::Span;
 use std::collections::VecDeque;
 use std::io;
 use std::io::prelude::*;
-use std::iter;
 use std::rc::Rc;
 
 mod rwu_table;
@@ -470,7 +469,6 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
             | hir::ExprKind::Struct(..)
             | hir::ExprKind::Repeat(..)
             | hir::ExprKind::InlineAsm(..)
-            | hir::ExprKind::LlvmInlineAsm(..)
             | hir::ExprKind::Box(..)
             | hir::ExprKind::Type(..)
             | hir::ExprKind::Err
@@ -1091,26 +1089,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 succ
             }
 
-            hir::ExprKind::LlvmInlineAsm(ref asm) => {
-                let ia = &asm.inner;
-                let outputs = asm.outputs_exprs;
-                let inputs = asm.inputs_exprs;
-                let succ = iter::zip(&ia.outputs, outputs).rev().fold(succ, |succ, (o, output)| {
-                    // see comment on places
-                    // in propagate_through_place_components()
-                    if o.is_indirect {
-                        self.propagate_through_expr(output, succ)
-                    } else {
-                        let acc = if o.is_rw { ACC_WRITE | ACC_READ } else { ACC_WRITE };
-                        let succ = self.write_place(output, succ, acc);
-                        self.propagate_through_place_components(output, succ)
-                    }
-                });
-
-                // Inputs are executed first. Propagate last because of rev order
-                self.propagate_through_exprs(inputs, succ)
-            }
-
             hir::ExprKind::Lit(..)
             | hir::ExprKind::ConstBlock(..)
             | hir::ExprKind::Err
@@ -1387,20 +1365,6 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
             }
         }
 
-        hir::ExprKind::LlvmInlineAsm(ref asm) => {
-            for input in asm.inputs_exprs {
-                this.visit_expr(input);
-            }
-
-            // Output operands must be places
-            for (o, output) in iter::zip(&asm.inner.outputs, asm.outputs_exprs) {
-                if !o.is_indirect {
-                    this.check_place(output);
-                }
-                this.visit_expr(output);
-            }
-        }
-
         hir::ExprKind::Let(let_expr) => {
             this.check_unused_vars_in_pat(let_expr.pat, None, |_, _, _, _| {});
         }
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 07cb165d796..dd14dce4b5b 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -236,22 +236,6 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
                 self.check_inline_asm(expr.hir_id, asm, span);
             }
 
-            ExprKind::LlvmInlineAsm(..) => {
-                self.items.push((ItemKind::Asm, span));
-                self.tcx.struct_span_lint_hir(
-                    UNSUPPORTED_NAKED_FUNCTIONS,
-                    expr.hir_id,
-                    span,
-                    |lint| {
-                        lint.build(
-                            "the LLVM-style inline assembly is unsupported in naked functions",
-                        )
-                        .help("use the new asm! syntax specified in RFC 2873")
-                        .emit();
-                    },
-                );
-            }
-
             ExprKind::DropTemps(..) | ExprKind::Block(..) | ExprKind::Err => {
                 hir::intravisit::walk_expr(self, expr);
             }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 84cf8878af8..9b906a735db 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -786,7 +786,6 @@ symbols! {
         linkage,
         lint_reasons,
         literal,
-        llvm_asm,
         load,
         loaded_from_disk,
         local,
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 0ea3a18ca34..76e51b8d7d9 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -480,7 +480,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
             // let expressions imply control flow
             ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } =>
                 self.error(node.span, "control flow is not supported in generic constants")?,
-            ExprKind::LlvmInlineAsm { .. } | ExprKind::InlineAsm { .. } => {
+            ExprKind::InlineAsm { .. } => {
                 self.error(node.span, "assembly is not supported in generic constants")?
             }
 
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 14180526d84..3b6e87b6a88 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -282,12 +282,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[]),
             ExprKind::InlineAsm(asm) => self.check_expr_asm(asm),
-            ExprKind::LlvmInlineAsm(asm) => {
-                for expr in asm.outputs_exprs.iter().chain(asm.inputs_exprs.iter()) {
-                    self.check_expr(expr);
-                }
-                tcx.mk_unit()
-            }
             ExprKind::Break(destination, ref expr_opt) => {
                 self.check_expr_break(destination, expr_opt.as_deref(), expr)
             }
diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index 1ae0ff30364..564aac4825a 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -17,7 +17,6 @@ use rustc_middle::hir::place::ProjectionKind;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, adjustment, AdtKind, Ty, TyCtxt};
 use rustc_target::abi::VariantIdx;
-use std::iter;
 
 use crate::mem_categorization as mc;
 
@@ -360,17 +359,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                 }
             }
 
-            hir::ExprKind::LlvmInlineAsm(ia) => {
-                for (o, output) in iter::zip(&ia.inner.outputs, ia.outputs_exprs) {
-                    if o.is_indirect {
-                        self.consume_expr(output);
-                    } else {
-                        self.mutate_expr(output);
-                    }
-                }
-                self.consume_exprs(ia.inputs_exprs);
-            }
-
             hir::ExprKind::Continue(..)
             | hir::ExprKind::Lit(..)
             | hir::ExprKind::ConstBlock(..)
diff --git a/compiler/rustc_typeck/src/mem_categorization.rs b/compiler/rustc_typeck/src/mem_categorization.rs
index 440ce04e61a..2c2d2be8bb5 100644
--- a/compiler/rustc_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_typeck/src/mem_categorization.rs
@@ -378,7 +378,6 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
             | hir::ExprKind::Struct(..)
             | hir::ExprKind::Repeat(..)
             | hir::ExprKind::InlineAsm(..)
-            | hir::ExprKind::LlvmInlineAsm(..)
             | hir::ExprKind::Box(..)
             | hir::ExprKind::Err => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)),
         }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 4bd94e3ce39..d8ac816fb15 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -180,7 +180,6 @@
 #![feature(intrinsics)]
 #![feature(lang_items)]
 #![feature(link_llvm_intrinsics)]
-#![feature(llvm_asm)]
 #![feature(min_specialization)]
 #![feature(mixed_integer_ops)]
 #![feature(must_not_suspend)]
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index d8f6c85e428..5184eb91bf3 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1373,32 +1373,6 @@ pub(crate) mod builtin {
         ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
     }
 
-    /// LLVM-style inline assembly.
-    ///
-    /// Read the [unstable book] for the usage.
-    ///
-    /// [unstable book]: ../unstable-book/library-features/llvm-asm.html
-    #[unstable(
-        feature = "llvm_asm",
-        issue = "70173",
-        reason = "prefer using the new asm! syntax instead"
-    )]
-    #[rustc_deprecated(
-        since = "1.56",
-        reason = "will be removed from the compiler, use asm! instead"
-    )]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! llvm_asm {
-        ("assembly template"
-                        : $("output"(operand),)*
-                        : $("input"(operand),)*
-                        : $("clobbers",)*
-                        : $("options",)*) => {
-            /* compiler built-in */
-        };
-    }
-
     /// Prints passed tokens into the standard output.
     #[unstable(
         feature = "log_syntax",
diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs
index 0fb8846288b..d91289fad20 100644
--- a/library/core/src/prelude/v1.rs
+++ b/library/core/src/prelude/v1.rs
@@ -56,8 +56,8 @@ pub use crate::hash::macros::Hash;
 #[doc(no_inline)]
 pub use crate::{
     assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
-    format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax, module_path,
-    option_env, stringify, trace_macros,
+    format_args_nl, include, include_bytes, include_str, line, log_syntax, module_path, option_env,
+    stringify, trace_macros,
 };
 
 #[unstable(
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 4ba4e2a528e..51d5f1cd4e1 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -294,7 +294,6 @@
 #![feature(intra_doc_pointers)]
 #![feature(lang_items)]
 #![feature(linkage)]
-#![feature(llvm_asm)]
 #![feature(log_syntax)]
 #![feature(map_try_insert)]
 #![feature(maybe_uninit_extra)]
@@ -572,8 +571,8 @@ pub use core::{
 #[allow(deprecated)]
 pub use core::{
     assert, assert_matches, cfg, column, compile_error, concat, concat_idents, const_format_args,
-    env, file, format_args, format_args_nl, include, include_bytes, include_str, line, llvm_asm,
-    log_syntax, module_path, option_env, stringify, trace_macros,
+    env, file, format_args, format_args_nl, include, include_bytes, include_str, line, log_syntax,
+    module_path, option_env, stringify, trace_macros,
 };
 
 #[unstable(
diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs
index b52bcdfca9e..53124daa3a6 100644
--- a/library/std/src/prelude/v1.rs
+++ b/library/std/src/prelude/v1.rs
@@ -40,9 +40,8 @@ pub use crate::result::Result::{self, Err, Ok};
 #[doc(no_inline)]
 pub use core::prelude::v1::{
     assert, cfg, column, compile_error, concat, concat_idents, env, file, format_args,
-    format_args_nl, include, include_bytes, include_str, line, llvm_asm, log_syntax, module_path,
-    option_env, stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq,
-    PartialOrd,
+    format_args_nl, include, include_bytes, include_str, line, log_syntax, module_path, option_env,
+    stringify, trace_macros, Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd,
 };
 
 #[unstable(