Skip to content

Commit 7a0922c

Browse files
committed
fix for divergence
1 parent be6b3c1 commit 7a0922c

File tree

18 files changed

+79
-28
lines changed

18 files changed

+79
-28
lines changed

Diff for: compiler/rustc_ast/src/ast.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -2429,21 +2429,29 @@ pub enum AsmMacro {
24292429
}
24302430

24312431
impl AsmMacro {
2432-
pub const fn macro_name(&self) -> &'static str {
2432+
pub const fn macro_name(self) -> &'static str {
24332433
match self {
24342434
AsmMacro::Asm => "asm",
24352435
AsmMacro::GlobalAsm => "global_asm",
24362436
AsmMacro::NakedAsm => "naked_asm",
24372437
}
24382438
}
24392439

2440-
pub const fn is_supported_option(&self, option: InlineAsmOptions) -> bool {
2440+
pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
24412441
match self {
24422442
AsmMacro::Asm => true,
24432443
AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
24442444
AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
24452445
}
24462446
}
2447+
2448+
pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2449+
match self {
2450+
AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2451+
AsmMacro::GlobalAsm => true,
2452+
AsmMacro::NakedAsm => true,
2453+
}
2454+
}
24472455
}
24482456

24492457
/// Inline assembly.

Diff for: compiler/rustc_borrowck/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
742742
}
743743

744744
TerminatorKind::InlineAsm {
745+
asm_macro: _,
745746
template: _,
746747
operands,
747748
options: _,

Diff for: compiler/rustc_borrowck/src/polonius/loan_invalidations.rs

+1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> {
169169
}
170170
}
171171
TerminatorKind::InlineAsm {
172+
asm_macro: _,
172173
template: _,
173174
operands,
174175
options: _,

Diff for: compiler/rustc_codegen_cranelift/src/base.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
498498
"tail calls are not yet supported in `rustc_codegen_cranelift` backend"
499499
),
500500
TerminatorKind::InlineAsm {
501+
asm_macro,
501502
template,
502503
operands,
503504
options,
@@ -512,7 +513,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
512513
);
513514
}
514515

515-
let have_labels = if options.contains(InlineAsmOptions::NORETURN) {
516+
let have_labels = if asm_macro.diverges(options) {
516517
!targets.is_empty()
517518
} else {
518519
targets.len() > 1

Diff for: compiler/rustc_codegen_ssa/src/mir/block.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use std::cmp;
33
use rustc_ast as ast;
44
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
55
use rustc_hir::lang_items::LangItem;
6-
use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTerminateReason};
6+
use rustc_middle::mir::{
7+
self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason,
8+
};
79
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
810
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
911
use rustc_middle::ty::{self, Instance, Ty};
@@ -1156,6 +1158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11561158
&mut self,
11571159
helper: TerminatorCodegenHelper<'tcx>,
11581160
bx: &mut Bx,
1161+
asm_macro: InlineAsmMacro,
11591162
terminator: &mir::Terminator<'tcx>,
11601163
template: &[ast::InlineAsmTemplatePiece],
11611164
operands: &[mir::InlineAsmOperand<'tcx>],
@@ -1226,11 +1229,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12261229
&operands,
12271230
options,
12281231
line_spans,
1229-
if options.contains(InlineAsmOptions::NORETURN) {
1230-
None
1231-
} else {
1232-
targets.get(0).copied()
1233-
},
1232+
if asm_macro.diverges(options) { None } else { targets.get(0).copied() },
12341233
unwind,
12351234
instance,
12361235
mergeable_succ,
@@ -1406,6 +1405,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14061405
}
14071406

14081407
mir::TerminatorKind::InlineAsm {
1408+
asm_macro,
14091409
template,
14101410
ref operands,
14111411
options,
@@ -1415,6 +1415,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14151415
} => self.codegen_asm_terminator(
14161416
helper,
14171417
bx,
1418+
asm_macro,
14181419
terminator,
14191420
template,
14201421
operands,

Diff for: compiler/rustc_const_eval/src/interpret/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ pub trait Machine<'tcx>: Sized {
393393
///
394394
/// This should take care of jumping to the next block (one of `targets`) when asm goto
395395
/// is triggered, `targets[0]` when the assembly falls through, or diverge in case of
396-
/// `InlineAsmOptions::NORETURN` being set.
396+
/// naked_asm! or `InlineAsmOptions::NORETURN` being set.
397397
fn eval_inline_asm(
398398
_ecx: &mut InterpCx<'tcx, Self>,
399399
_template: &'tcx [InlineAsmTemplatePiece],

Diff for: compiler/rustc_hir_typeck/src/expr.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -3307,11 +3307,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33073307
}
33083308

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

33163312
for (op, _op_sp) in asm.operands {
33173313
match op {

Diff for: compiler/rustc_middle/src/mir/pretty.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::fs;
44
use std::io::{self, Write as _};
55
use std::path::{Path, PathBuf};
66

7-
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
7+
use rustc_ast::InlineAsmTemplatePiece;
88
use rustc_middle::mir::interpret::{
99
alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer,
1010
Provenance,
@@ -1024,9 +1024,9 @@ impl<'tcx> TerminatorKind<'tcx> {
10241024
vec!["real".into(), "unwind".into()]
10251025
}
10261026
FalseUnwind { unwind: _, .. } => vec!["real".into()],
1027-
InlineAsm { options, ref targets, unwind, .. } => {
1027+
InlineAsm { asm_macro, options, ref targets, unwind, .. } => {
10281028
let mut vec = Vec::with_capacity(targets.len() + 1);
1029-
if !options.contains(InlineAsmOptions::NORETURN) {
1029+
if !asm_macro.diverges(options) {
10301030
vec.push("return".into());
10311031
}
10321032
vec.resize(targets.len(), "label".into());

Diff for: compiler/rustc_middle/src/mir/syntax.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,25 @@ impl CallSource {
604604
}
605605
}
606606

607+
#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
608+
#[derive(TypeFoldable, TypeVisitable)]
609+
/// The macro that an inline assembly block was created by
610+
pub enum InlineAsmMacro {
611+
/// The `asm!` macro
612+
Asm,
613+
/// The `naked_asm!` macro
614+
NakedAsm,
615+
}
616+
617+
impl InlineAsmMacro {
618+
pub const fn diverges(self, options: InlineAsmOptions) -> bool {
619+
match self {
620+
InlineAsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
621+
InlineAsmMacro::NakedAsm => true,
622+
}
623+
}
624+
}
625+
607626
///////////////////////////////////////////////////////////////////////////
608627
// Terminators
609628

@@ -858,6 +877,9 @@ pub enum TerminatorKind<'tcx> {
858877
/// Block ends with an inline assembly block. This is a terminator since
859878
/// inline assembly is allowed to diverge.
860879
InlineAsm {
880+
/// Macro used to create this inline asm: one of `asm!` or `naked_asm!`
881+
asm_macro: InlineAsmMacro,
882+
861883
/// The template for the inline assembly, with placeholders.
862884
template: &'tcx [InlineAsmTemplatePiece],
863885

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

874896
/// Valid targets for the inline assembly.
875897
/// The first element is the fallthrough destination, unless
876-
/// InlineAsmOptions::NORETURN is set.
898+
/// asm_macro == InlineAsmMacro::NakedAsm or InlineAsmOptions::NORETURN is set.
877899
targets: Box<[BasicBlock]>,
878900

879901
/// Action to be taken if the inline assembly unwinds. This is present

Diff for: compiler/rustc_middle/src/mir/terminator.rs

+1
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ impl<'tcx> TerminatorKind<'tcx> {
655655
},
656656

657657
InlineAsm {
658+
asm_macro: _,
658659
template: _,
659660
ref operands,
660661
options: _,

Diff for: compiler/rustc_middle/src/mir/visit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ macro_rules! make_mir_visitor {
576576
}
577577

578578
TerminatorKind::InlineAsm {
579+
asm_macro: _,
579580
template: _,
580581
operands,
581582
options: _,

Diff for: compiler/rustc_middle/src/thir.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::cmp::Ordering;
1212
use std::fmt;
1313
use std::ops::Index;
1414

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

174174
#[derive(Clone, Debug, HashStable)]
175175
pub struct InlineAsmExpr<'tcx> {
176+
pub asm_macro: AsmMacro,
176177
pub template: &'tcx [InlineAsmTemplatePiece],
177178
pub operands: Box<[InlineAsmOperand<'tcx>]>,
178179
pub options: InlineAsmOptions,

Diff for: compiler/rustc_middle/src/thir/visit.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,13 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
145145
NamedConst { def_id: _, args: _, user_ty: _ } => {}
146146
ConstParam { param: _, def_id: _ } => {}
147147
StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
148-
InlineAsm(box InlineAsmExpr { ref operands, template: _, options: _, line_spans: _ }) => {
148+
InlineAsm(box InlineAsmExpr {
149+
asm_macro: _,
150+
ref operands,
151+
template: _,
152+
options: _,
153+
line_spans: _,
154+
}) => {
149155
for op in &**operands {
150156
use InlineAsmOperand::*;
151157
match op {

Diff for: compiler/rustc_mir_build/src/build/expr/into.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::iter;
44

5-
use rustc_ast::InlineAsmOptions;
5+
use rustc_ast::{AsmMacro, InlineAsmOptions};
66
use rustc_data_structures::fx::FxHashMap;
77
use rustc_data_structures::stack::ensure_sufficient_stack;
88
use rustc_hir as hir;
@@ -392,6 +392,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
392392
block.unit()
393393
}
394394
ExprKind::InlineAsm(box InlineAsmExpr {
395+
asm_macro,
395396
template,
396397
ref operands,
397398
options,
@@ -400,11 +401,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
400401
use rustc_middle::{mir, thir};
401402

402403
let destination_block = this.cfg.start_new_block();
403-
let mut targets = if options.contains(InlineAsmOptions::NORETURN) {
404-
vec![]
405-
} else {
406-
vec![destination_block]
407-
};
404+
let mut targets =
405+
if asm_macro.diverges(options) { vec![] } else { vec![destination_block] };
408406

409407
let operands = operands
410408
.into_iter()
@@ -484,10 +482,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
484482
this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
485483
}
486484

485+
let asm_macro = match asm_macro {
486+
AsmMacro::Asm => InlineAsmMacro::Asm,
487+
AsmMacro::GlobalAsm => {
488+
span_bug!(expr_span, "unexpected global_asm! in inline asm")
489+
}
490+
AsmMacro::NakedAsm => InlineAsmMacro::NakedAsm,
491+
};
492+
487493
this.cfg.terminate(
488494
block,
489495
source_info,
490496
TerminatorKind::InlineAsm {
497+
asm_macro,
491498
template,
492499
operands,
493500
options,

Diff for: compiler/rustc_mir_build/src/thir/cx/expr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ impl<'tcx> Cx<'tcx> {
597597
}
598598

599599
hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
600+
asm_macro: asm.asm_macro,
600601
template: asm.template,
601602
operands: asm
602603
.operands

Diff for: compiler/rustc_mir_build/src/thir/print.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -811,10 +811,12 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
811811
}
812812

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

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

818+
print_indented!(self, format!("asm_macro: {:?}", asm_macro), depth_lvl + 1);
819+
818820
print_indented!(self, "template: [", depth_lvl + 1);
819821
for template_piece in template.iter() {
820822
print_indented!(self, format!("{:?}", template_piece), depth_lvl + 2);

Diff for: compiler/rustc_mir_dataflow/src/move_paths/builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
496496
}
497497
}
498498
TerminatorKind::InlineAsm {
499+
asm_macro: _,
499500
template: _,
500501
ref operands,
501502
options: _,

Diff for: compiler/rustc_smir/src/rustc_smir/convert/mir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
654654
}
655655
}
656656
mir::TerminatorKind::InlineAsm {
657+
asm_macro: _,
657658
template,
658659
operands,
659660
options,

0 commit comments

Comments
 (0)