Skip to content

Commit

Permalink
fix for divergence
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertdev committed Sep 5, 2024
1 parent be6b3c1 commit 7a0922c
Show file tree
Hide file tree
Showing 18 changed files with 79 additions and 28 deletions.
12 changes: 10 additions & 2 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2429,21 +2429,29 @@ pub enum AsmMacro {
}

impl AsmMacro {
pub const fn macro_name(&self) -> &'static str {
pub const fn macro_name(self) -> &'static str {
match self {
AsmMacro::Asm => "asm",
AsmMacro::GlobalAsm => "global_asm",
AsmMacro::NakedAsm => "naked_asm",
}
}

pub const fn is_supported_option(&self, option: InlineAsmOptions) -> bool {
pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
match self {
AsmMacro::Asm => true,
AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
}
}

pub const fn diverges(self, options: InlineAsmOptions) -> bool {
match self {
AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
AsmMacro::GlobalAsm => true,
AsmMacro::NakedAsm => true,
}
}
}

/// Inline assembly.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,7 @@ impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
}

TerminatorKind::InlineAsm {
asm_macro: _,
template: _,
operands,
options: _,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> {
}
}
TerminatorKind::InlineAsm {
asm_macro: _,
template: _,
operands,
options: _,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
"tail calls are not yet supported in `rustc_codegen_cranelift` backend"
),
TerminatorKind::InlineAsm {
asm_macro,
template,
operands,
options,
Expand All @@ -512,7 +513,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
);
}

let have_labels = if options.contains(InlineAsmOptions::NORETURN) {
let have_labels = if asm_macro.diverges(options) {
!targets.is_empty()
} else {
targets.len() > 1
Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::cmp;
use rustc_ast as ast;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::lang_items::LangItem;
use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTerminateReason};
use rustc_middle::mir::{
self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason,
};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Instance, Ty};
Expand Down Expand Up @@ -1156,6 +1158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&mut self,
helper: TerminatorCodegenHelper<'tcx>,
bx: &mut Bx,
asm_macro: InlineAsmMacro,
terminator: &mir::Terminator<'tcx>,
template: &[ast::InlineAsmTemplatePiece],
operands: &[mir::InlineAsmOperand<'tcx>],
Expand Down Expand Up @@ -1226,11 +1229,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&operands,
options,
line_spans,
if options.contains(InlineAsmOptions::NORETURN) {
None
} else {
targets.get(0).copied()
},
if asm_macro.diverges(options) { None } else { targets.get(0).copied() },
unwind,
instance,
mergeable_succ,
Expand Down Expand Up @@ -1406,6 +1405,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}

mir::TerminatorKind::InlineAsm {
asm_macro,
template,
ref operands,
options,
Expand All @@ -1415,6 +1415,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} => self.codegen_asm_terminator(
helper,
bx,
asm_macro,
terminator,
template,
operands,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ pub trait Machine<'tcx>: Sized {
///
/// This should take care of jumping to the next block (one of `targets`) when asm goto
/// is triggered, `targets[0]` when the assembly falls through, or diverge in case of
/// `InlineAsmOptions::NORETURN` being set.
/// naked_asm! or `InlineAsmOptions::NORETURN` being set.
fn eval_inline_asm(
_ecx: &mut InterpCx<'tcx, Self>,
_template: &'tcx [InlineAsmTemplatePiece],
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3307,11 +3307,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
let mut diverge = match asm.asm_macro {
rustc_ast::AsmMacro::Asm => asm.options.contains(ast::InlineAsmOptions::NORETURN),
rustc_ast::AsmMacro::GlobalAsm => true,
rustc_ast::AsmMacro::NakedAsm => true,
};
let mut diverge = asm.asm_macro.diverges(asm.options);

for (op, _op_sp) in asm.operands {
match op {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::fs;
use std::io::{self, Write as _};
use std::path::{Path, PathBuf};

use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_ast::InlineAsmTemplatePiece;
use rustc_middle::mir::interpret::{
alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer,
Provenance,
Expand Down Expand Up @@ -1024,9 +1024,9 @@ impl<'tcx> TerminatorKind<'tcx> {
vec!["real".into(), "unwind".into()]
}
FalseUnwind { unwind: _, .. } => vec!["real".into()],
InlineAsm { options, ref targets, unwind, .. } => {
InlineAsm { asm_macro, options, ref targets, unwind, .. } => {
let mut vec = Vec::with_capacity(targets.len() + 1);
if !options.contains(InlineAsmOptions::NORETURN) {
if !asm_macro.diverges(options) {
vec.push("return".into());
}
vec.resize(targets.len(), "label".into());
Expand Down
24 changes: 23 additions & 1 deletion compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,25 @@ impl CallSource {
}
}

#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
#[derive(TypeFoldable, TypeVisitable)]
/// The macro that an inline assembly block was created by
pub enum InlineAsmMacro {
/// The `asm!` macro
Asm,
/// The `naked_asm!` macro
NakedAsm,
}

impl InlineAsmMacro {
pub const fn diverges(self, options: InlineAsmOptions) -> bool {
match self {
InlineAsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
InlineAsmMacro::NakedAsm => true,
}
}
}

///////////////////////////////////////////////////////////////////////////
// Terminators

Expand Down Expand Up @@ -858,6 +877,9 @@ pub enum TerminatorKind<'tcx> {
/// Block ends with an inline assembly block. This is a terminator since
/// inline assembly is allowed to diverge.
InlineAsm {
/// Macro used to create this inline asm: one of `asm!` or `naked_asm!`
asm_macro: InlineAsmMacro,

/// The template for the inline assembly, with placeholders.
template: &'tcx [InlineAsmTemplatePiece],

Expand All @@ -873,7 +895,7 @@ pub enum TerminatorKind<'tcx> {

/// Valid targets for the inline assembly.
/// The first element is the fallthrough destination, unless
/// InlineAsmOptions::NORETURN is set.
/// asm_macro == InlineAsmMacro::NakedAsm or InlineAsmOptions::NORETURN is set.
targets: Box<[BasicBlock]>,

/// Action to be taken if the inline assembly unwinds. This is present
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/mir/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ impl<'tcx> TerminatorKind<'tcx> {
},

InlineAsm {
asm_macro: _,
template: _,
ref operands,
options: _,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ macro_rules! make_mir_visitor {
}

TerminatorKind::InlineAsm {
asm_macro: _,
template: _,
operands,
options: _,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::cmp::Ordering;
use std::fmt;
use std::ops::Index;

use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
Expand Down Expand Up @@ -173,6 +173,7 @@ pub struct ClosureExpr<'tcx> {

#[derive(Clone, Debug, HashStable)]
pub struct InlineAsmExpr<'tcx> {
pub asm_macro: AsmMacro,
pub template: &'tcx [InlineAsmTemplatePiece],
pub operands: Box<[InlineAsmOperand<'tcx>]>,
pub options: InlineAsmOptions,
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_middle/src/thir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,13 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
NamedConst { def_id: _, args: _, user_ty: _ } => {}
ConstParam { param: _, def_id: _ } => {}
StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
InlineAsm(box InlineAsmExpr { ref operands, template: _, options: _, line_spans: _ }) => {
InlineAsm(box InlineAsmExpr {
asm_macro: _,
ref operands,
template: _,
options: _,
line_spans: _,
}) => {
for op in &**operands {
use InlineAsmOperand::*;
match op {
Expand Down
19 changes: 13 additions & 6 deletions compiler/rustc_mir_build/src/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::iter;

use rustc_ast::InlineAsmOptions;
use rustc_ast::{AsmMacro, InlineAsmOptions};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
Expand Down Expand Up @@ -392,6 +392,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.unit()
}
ExprKind::InlineAsm(box InlineAsmExpr {
asm_macro,
template,
ref operands,
options,
Expand All @@ -400,11 +401,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
use rustc_middle::{mir, thir};

let destination_block = this.cfg.start_new_block();
let mut targets = if options.contains(InlineAsmOptions::NORETURN) {
vec![]
} else {
vec![destination_block]
};
let mut targets =
if asm_macro.diverges(options) { vec![] } else { vec![destination_block] };

let operands = operands
.into_iter()
Expand Down Expand Up @@ -484,10 +482,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
}

let asm_macro = match asm_macro {
AsmMacro::Asm => InlineAsmMacro::Asm,
AsmMacro::GlobalAsm => {
span_bug!(expr_span, "unexpected global_asm! in inline asm")
}
AsmMacro::NakedAsm => InlineAsmMacro::NakedAsm,
};

this.cfg.terminate(
block,
source_info,
TerminatorKind::InlineAsm {
asm_macro,
template,
operands,
options,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ impl<'tcx> Cx<'tcx> {
}

hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
asm_macro: asm.asm_macro,
template: asm.template,
operands: asm
.operands
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir_build/src/thir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,10 +811,12 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
}

fn print_inline_asm_expr(&mut self, expr: &InlineAsmExpr<'tcx>, depth_lvl: usize) {
let InlineAsmExpr { template, operands, options, line_spans } = expr;
let InlineAsmExpr { asm_macro, template, operands, options, line_spans } = expr;

print_indented!(self, "InlineAsmExpr {", depth_lvl);

print_indented!(self, format!("asm_macro: {:?}", asm_macro), depth_lvl + 1);

print_indented!(self, "template: [", depth_lvl + 1);
for template_piece in template.iter() {
print_indented!(self, format!("{:?}", template_piece), depth_lvl + 2);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_dataflow/src/move_paths/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
}
}
TerminatorKind::InlineAsm {
asm_macro: _,
template: _,
ref operands,
options: _,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_smir/src/rustc_smir/convert/mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
}
}
mir::TerminatorKind::InlineAsm {
asm_macro: _,
template,
operands,
options,
Expand Down

0 comments on commit 7a0922c

Please sign in to comment.