Skip to content

Commit 015d2bc

Browse files
committedApr 5, 2021
Auto merge of #83864 - Dylan-DPC:rollup-78an86n, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #80525 (wasm64 support) - #83019 (core: disable `ptr::swap_nonoverlapping_one`'s block optimization on SPIR-V.) - #83717 (rustdoc: Separate filter-empty-string out into its own function) - #83807 (Tests: Remove redundant `ignore-tidy-linelength` annotations) - #83815 (ptr::addr_of documentation improvements) - #83820 (Remove attribute `#[link_args]`) - #83841 (Allow clobbering unsupported registers in asm!) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
·
1.88.01.53.0
2 parents 35aa636 + f8709ec commit 015d2bc

File tree

319 files changed

+1914
-2142
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

319 files changed

+1914
-2142
lines changed
 

‎compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,46 +1499,64 @@ impl<'hir> LoweringContext<'_, 'hir> {
14991499
// previous iteration.
15001500
required_features.clear();
15011501

1502-
// Validate register classes against currently enabled target
1503-
// features. We check that at least one type is available for
1504-
// the current target.
15051502
let reg_class = reg.reg_class();
15061503
if reg_class == asm::InlineAsmRegClass::Err {
15071504
continue;
15081505
}
1509-
for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) {
1510-
if let Some(feature) = feature {
1511-
if self.sess.target_features.contains(&Symbol::intern(feature)) {
1506+
1507+
// We ignore target feature requirements for clobbers: if the
1508+
// feature is disabled then the compiler doesn't care what we
1509+
// do with the registers.
1510+
//
1511+
// Note that this is only possible for explicit register
1512+
// operands, which cannot be used in the asm string.
1513+
let is_clobber = matches!(
1514+
op,
1515+
hir::InlineAsmOperand::Out {
1516+
reg: asm::InlineAsmRegOrRegClass::Reg(_),
1517+
late: _,
1518+
expr: None
1519+
}
1520+
);
1521+
1522+
if !is_clobber {
1523+
// Validate register classes against currently enabled target
1524+
// features. We check that at least one type is available for
1525+
// the current target.
1526+
for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) {
1527+
if let Some(feature) = feature {
1528+
if self.sess.target_features.contains(&Symbol::intern(feature)) {
1529+
required_features.clear();
1530+
break;
1531+
} else {
1532+
required_features.push(feature);
1533+
}
1534+
} else {
15121535
required_features.clear();
15131536
break;
1514-
} else {
1515-
required_features.push(feature);
15161537
}
1517-
} else {
1518-
required_features.clear();
1519-
break;
15201538
}
1521-
}
1522-
// We are sorting primitive strs here and can use unstable sort here
1523-
required_features.sort_unstable();
1524-
required_features.dedup();
1525-
match &required_features[..] {
1526-
[] => {}
1527-
[feature] => {
1528-
let msg = format!(
1529-
"register class `{}` requires the `{}` target feature",
1530-
reg_class.name(),
1531-
feature
1532-
);
1533-
sess.struct_span_err(op_sp, &msg).emit();
1534-
}
1535-
features => {
1536-
let msg = format!(
1537-
"register class `{}` requires at least one target feature: {}",
1538-
reg_class.name(),
1539-
features.join(", ")
1540-
);
1541-
sess.struct_span_err(op_sp, &msg).emit();
1539+
// We are sorting primitive strs here and can use unstable sort here
1540+
required_features.sort_unstable();
1541+
required_features.dedup();
1542+
match &required_features[..] {
1543+
[] => {}
1544+
[feature] => {
1545+
let msg = format!(
1546+
"register class `{}` requires the `{}` target feature",
1547+
reg_class.name(),
1548+
feature
1549+
);
1550+
sess.struct_span_err(op_sp, &msg).emit();
1551+
}
1552+
features => {
1553+
let msg = format!(
1554+
"register class `{}` requires at least one target feature: {}",
1555+
reg_class.name(),
1556+
features.join(", ")
1557+
);
1558+
sess.struct_span_err(op_sp, &msg).emit();
1559+
}
15421560
}
15431561
}
15441562

‎compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxHashMap;
1414
use rustc_hir as hir;
1515
use rustc_middle::ty::layout::TyAndLayout;
1616
use rustc_middle::{bug, span_bug};
17-
use rustc_span::{Pos, Span};
17+
use rustc_span::{Pos, Span, Symbol};
1818
use rustc_target::abi::*;
1919
use rustc_target::asm::*;
2020

@@ -125,15 +125,39 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
125125

126126
// Collect the types of output operands
127127
let mut constraints = vec![];
128+
let mut clobbers = vec![];
128129
let mut output_types = vec![];
129130
let mut op_idx = FxHashMap::default();
130131
for (idx, op) in operands.iter().enumerate() {
131132
match *op {
132133
InlineAsmOperandRef::Out { reg, late, place } => {
134+
let is_target_supported = |reg_class: InlineAsmRegClass| {
135+
for &(_, feature) in reg_class.supported_types(asm_arch) {
136+
if let Some(feature) = feature {
137+
if self.tcx.sess.target_features.contains(&Symbol::intern(feature))
138+
{
139+
return true;
140+
}
141+
} else {
142+
// Register class is unconditionally supported
143+
return true;
144+
}
145+
}
146+
false
147+
};
148+
133149
let mut layout = None;
134150
let ty = if let Some(ref place) = place {
135151
layout = Some(&place.layout);
136152
llvm_fixup_output_type(self.cx, reg.reg_class(), &place.layout)
153+
} else if !is_target_supported(reg.reg_class()) {
154+
// We turn discarded outputs into clobber constraints
155+
// if the target feature needed by the register class is
156+
// disabled. This is necessary otherwise LLVM will try
157+
// to actually allocate a register for the dummy output.
158+
assert!(matches!(reg, InlineAsmRegOrRegClass::Reg(_)));
159+
clobbers.push(format!("~{}", reg_to_llvm(reg, None)));
160+
continue;
137161
} else {
138162
// If the output is discarded, we don't really care what
139163
// type is used. We're just using this to tell LLVM to
@@ -244,6 +268,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
244268
}
245269
}
246270

271+
constraints.append(&mut clobbers);
247272
if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) {
248273
match asm_arch {
249274
InlineAsmArch::AArch64 | InlineAsmArch::Arm => {

0 commit comments

Comments
 (0)
Please sign in to comment.