Skip to content

Commit bca5f37

Browse files
committed
Auto merge of rust-lang#137446 - matthiaskrgr:rollup-16moy6v, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#135501 (Inject `compiler_builtins` during postprocessing and ensure it is made private) - rust-lang#137121 (stabilize `(const_)ptr_sub_ptr`) - rust-lang#137180 (Give `global_asm` a fake body to store typeck results, represent `sym fn` as a hir expr to fix `sym fn` operands with lifetimes) - rust-lang#137256 (compiler: untangle SIMD alignment assumptions) - rust-lang#137383 (stabilize `unsigned_is_multiple_of`) - rust-lang#137415 (Remove invalid suggestion of into_iter for extern macro) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0769736 + e780b89 commit bca5f37

File tree

94 files changed

+703
-538
lines changed

Some content is hidden

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

94 files changed

+703
-538
lines changed

compiler/rustc_abi/src/callconv/reg.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl Reg {
5757
128 => dl.f128_align.abi,
5858
_ => panic!("unsupported float: {self:?}"),
5959
},
60-
RegKind::Vector => dl.vector_align(self.size).abi,
60+
RegKind::Vector => dl.llvmlike_vector_align(self.size).abi,
6161
}
6262
}
6363
}

compiler/rustc_abi/src/layout.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
310310
let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
311311
let mut max_repr_align = repr.align;
312312

313-
// If all the non-ZST fields have the same ABI and union ABI optimizations aren't
314-
// disabled, we can use that common ABI for the union as a whole.
313+
// If all the non-ZST fields have the same repr and union repr optimizations aren't
314+
// disabled, we can use that common repr for the union as a whole.
315315
struct AbiMismatch;
316-
let mut common_non_zst_abi_and_align = if repr.inhibits_union_abi_opt() {
316+
let mut common_non_zst_repr_and_align = if repr.inhibits_union_abi_opt() {
317317
// Can't optimize
318318
Err(AbiMismatch)
319319
} else {
@@ -337,14 +337,14 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
337337
continue;
338338
}
339339

340-
if let Ok(common) = common_non_zst_abi_and_align {
340+
if let Ok(common) = common_non_zst_repr_and_align {
341341
// Discard valid range information and allow undef
342342
let field_abi = field.backend_repr.to_union();
343343

344344
if let Some((common_abi, common_align)) = common {
345345
if common_abi != field_abi {
346346
// Different fields have different ABI: disable opt
347-
common_non_zst_abi_and_align = Err(AbiMismatch);
347+
common_non_zst_repr_and_align = Err(AbiMismatch);
348348
} else {
349349
// Fields with the same non-Aggregate ABI should also
350350
// have the same alignment
@@ -357,7 +357,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
357357
}
358358
} else {
359359
// First non-ZST field: record its ABI and alignment
360-
common_non_zst_abi_and_align = Ok(Some((field_abi, field.align.abi)));
360+
common_non_zst_repr_and_align = Ok(Some((field_abi, field.align.abi)));
361361
}
362362
}
363363
}
@@ -376,16 +376,25 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
376376

377377
// If all non-ZST fields have the same ABI, we may forward that ABI
378378
// for the union as a whole, unless otherwise inhibited.
379-
let abi = match common_non_zst_abi_and_align {
379+
let backend_repr = match common_non_zst_repr_and_align {
380380
Err(AbiMismatch) | Ok(None) => BackendRepr::Memory { sized: true },
381-
Ok(Some((abi, _))) => {
382-
if abi.inherent_align(dl).map(|a| a.abi) != Some(align.abi) {
383-
// Mismatched alignment (e.g. union is #[repr(packed)]): disable opt
381+
Ok(Some((repr, _))) => match repr {
382+
// Mismatched alignment (e.g. union is #[repr(packed)]): disable opt
383+
BackendRepr::Scalar(_) | BackendRepr::ScalarPair(_, _)
384+
if repr.scalar_align(dl).unwrap() != align.abi =>
385+
{
384386
BackendRepr::Memory { sized: true }
385-
} else {
386-
abi
387387
}
388-
}
388+
// Vectors require at least element alignment, else disable the opt
389+
BackendRepr::Vector { element, count: _ } if element.align(dl).abi > align.abi => {
390+
BackendRepr::Memory { sized: true }
391+
}
392+
// the alignment tests passed and we can use this
393+
BackendRepr::Scalar(..)
394+
| BackendRepr::ScalarPair(..)
395+
| BackendRepr::Vector { .. }
396+
| BackendRepr::Memory { .. } => repr,
397+
},
389398
};
390399

391400
let Some(union_field_count) = NonZeroUsize::new(only_variant.len()) else {
@@ -400,7 +409,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
400409
Ok(LayoutData {
401410
variants: Variants::Single { index: only_variant_idx },
402411
fields: FieldsShape::Union(union_field_count),
403-
backend_repr: abi,
412+
backend_repr,
404413
largest_niche: None,
405414
uninhabited: false,
406415
align,

compiler/rustc_abi/src/lib.rs

+49-44
Original file line numberDiff line numberDiff line change
@@ -408,16 +408,21 @@ impl TargetDataLayout {
408408
}
409409
}
410410

411+
/// psABI-mandated alignment for a vector type, if any
411412
#[inline]
412-
pub fn vector_align(&self, vec_size: Size) -> AbiAndPrefAlign {
413-
for &(size, align) in &self.vector_align {
414-
if size == vec_size {
415-
return align;
416-
}
417-
}
418-
// Default to natural alignment, which is what LLVM does.
419-
// That is, use the size, rounded up to a power of 2.
420-
AbiAndPrefAlign::new(Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap())
413+
fn cabi_vector_align(&self, vec_size: Size) -> Option<AbiAndPrefAlign> {
414+
self.vector_align
415+
.iter()
416+
.find(|(size, _align)| *size == vec_size)
417+
.map(|(_size, align)| *align)
418+
}
419+
420+
/// an alignment resembling the one LLVM would pick for a vector
421+
#[inline]
422+
pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAndPrefAlign {
423+
self.cabi_vector_align(vec_size).unwrap_or(AbiAndPrefAlign::new(
424+
Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap(),
425+
))
421426
}
422427
}
423428

@@ -810,20 +815,19 @@ impl Align {
810815
self.bits().try_into().unwrap()
811816
}
812817

813-
/// Computes the best alignment possible for the given offset
814-
/// (the largest power of two that the offset is a multiple of).
818+
/// Obtain the greatest factor of `size` that is an alignment
819+
/// (the largest power of two the Size is a multiple of).
815820
///
816-
/// N.B., for an offset of `0`, this happens to return `2^64`.
821+
/// Note that all numbers are factors of 0
817822
#[inline]
818-
pub fn max_for_offset(offset: Size) -> Align {
819-
Align { pow2: offset.bytes().trailing_zeros() as u8 }
823+
pub fn max_aligned_factor(size: Size) -> Align {
824+
Align { pow2: size.bytes().trailing_zeros() as u8 }
820825
}
821826

822-
/// Lower the alignment, if necessary, such that the given offset
823-
/// is aligned to it (the offset is a multiple of the alignment).
827+
/// Reduces Align to an aligned factor of `size`.
824828
#[inline]
825-
pub fn restrict_for_offset(self, offset: Size) -> Align {
826-
self.min(Align::max_for_offset(offset))
829+
pub fn restrict_for_offset(self, size: Size) -> Align {
830+
self.min(Align::max_aligned_factor(size))
827831
}
828832
}
829833

@@ -1455,37 +1459,38 @@ impl BackendRepr {
14551459
matches!(*self, BackendRepr::Scalar(s) if s.is_bool())
14561460
}
14571461

1458-
/// Returns the fixed alignment of this ABI, if any is mandated.
1459-
pub fn inherent_align<C: HasDataLayout>(&self, cx: &C) -> Option<AbiAndPrefAlign> {
1460-
Some(match *self {
1461-
BackendRepr::Scalar(s) => s.align(cx),
1462-
BackendRepr::ScalarPair(s1, s2) => s1.align(cx).max(s2.align(cx)),
1463-
BackendRepr::Vector { element, count } => {
1464-
cx.data_layout().vector_align(element.size(cx) * count)
1465-
}
1466-
BackendRepr::Memory { .. } => return None,
1467-
})
1462+
/// The psABI alignment for a `Scalar` or `ScalarPair`
1463+
///
1464+
/// `None` for other variants.
1465+
pub fn scalar_align<C: HasDataLayout>(&self, cx: &C) -> Option<Align> {
1466+
match *self {
1467+
BackendRepr::Scalar(s) => Some(s.align(cx).abi),
1468+
BackendRepr::ScalarPair(s1, s2) => Some(s1.align(cx).max(s2.align(cx)).abi),
1469+
// The align of a Vector can vary in surprising ways
1470+
BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => None,
1471+
}
14681472
}
14691473

1470-
/// Returns the fixed size of this ABI, if any is mandated.
1471-
pub fn inherent_size<C: HasDataLayout>(&self, cx: &C) -> Option<Size> {
1472-
Some(match *self {
1473-
BackendRepr::Scalar(s) => {
1474-
// No padding in scalars.
1475-
s.size(cx)
1476-
}
1474+
/// The psABI size for a `Scalar` or `ScalarPair`
1475+
///
1476+
/// `None` for other variants
1477+
pub fn scalar_size<C: HasDataLayout>(&self, cx: &C) -> Option<Size> {
1478+
match *self {
1479+
// No padding in scalars.
1480+
BackendRepr::Scalar(s) => Some(s.size(cx)),
1481+
// May have some padding between the pair.
14771482
BackendRepr::ScalarPair(s1, s2) => {
1478-
// May have some padding between the pair.
14791483
let field2_offset = s1.size(cx).align_to(s2.align(cx).abi);
1480-
(field2_offset + s2.size(cx)).align_to(self.inherent_align(cx)?.abi)
1484+
let size = (field2_offset + s2.size(cx)).align_to(
1485+
self.scalar_align(cx)
1486+
// We absolutely must have an answer here or everything is FUBAR.
1487+
.unwrap(),
1488+
);
1489+
Some(size)
14811490
}
1482-
BackendRepr::Vector { element, count } => {
1483-
// No padding in vectors, except possibly for trailing padding
1484-
// to make the size a multiple of align (e.g. for vectors of size 3).
1485-
(element.size(cx) * count).align_to(self.inherent_align(cx)?.abi)
1486-
}
1487-
BackendRepr::Memory { .. } => return None,
1488-
})
1491+
// The size of a Vector can vary in surprising ways
1492+
BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => None,
1493+
}
14891494
}
14901495

14911496
/// Discard validity range information and allow undef.

compiler/rustc_ast_lowering/src/asm.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use std::collections::hash_map::Entry;
22
use std::fmt::Write;
33

4-
use rustc_ast::ptr::P;
54
use rustc_ast::*;
65
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
76
use rustc_hir as hir;
87
use rustc_hir::def::{DefKind, Res};
98
use rustc_session::parse::feature_err;
10-
use rustc_span::{Span, kw, sym};
9+
use rustc_span::{Span, sym};
1110
use rustc_target::asm;
1211

1312
use super::LoweringContext;
@@ -230,20 +229,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
230229
tokens: None,
231230
};
232231

233-
// Wrap the expression in an AnonConst.
234-
let parent_def_id = self.current_hir_id_owner.def_id;
235-
let node_id = self.next_node_id();
236-
self.create_def(
237-
parent_def_id,
238-
node_id,
239-
kw::Empty,
240-
DefKind::AnonConst,
241-
*op_sp,
242-
);
243-
let anon_const = AnonConst { id: node_id, value: P(expr) };
244-
hir::InlineAsmOperand::SymFn {
245-
anon_const: self.lower_anon_const_to_anon_const(&anon_const),
246-
}
232+
hir::InlineAsmOperand::SymFn { expr: self.lower_expr(&expr) }
247233
}
248234
}
249235
InlineAsmOperand::Label { block } => {

compiler/rustc_ast_lowering/src/item.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
251251
.arena
252252
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
253253
},
254-
ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)),
254+
ItemKind::GlobalAsm(asm) => {
255+
let asm = self.lower_inline_asm(span, asm);
256+
let fake_body =
257+
self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
258+
hir::ItemKind::GlobalAsm { asm, fake_body }
259+
}
255260
ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
256261
// We lower
257262
//

compiler/rustc_borrowck/src/universal_regions.rs

+24-5
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ pub(crate) enum DefiningTy<'tcx> {
126126
/// The MIR represents an inline const. The signature has no inputs and a
127127
/// single return value found via `InlineConstArgs::ty`.
128128
InlineConst(DefId, GenericArgsRef<'tcx>),
129+
130+
// Fake body for a global asm. Not particularly useful or interesting,
131+
// but we need it so we can properly store the typeck results of the asm
132+
// operands, which aren't associated with a body otherwise.
133+
GlobalAsm(DefId),
129134
}
130135

131136
impl<'tcx> DefiningTy<'tcx> {
@@ -138,9 +143,10 @@ impl<'tcx> DefiningTy<'tcx> {
138143
DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(),
139144
DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(),
140145
DefiningTy::Coroutine(_, args) => args.as_coroutine().upvar_tys(),
141-
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
142-
ty::List::empty()
143-
}
146+
DefiningTy::FnDef(..)
147+
| DefiningTy::Const(..)
148+
| DefiningTy::InlineConst(..)
149+
| DefiningTy::GlobalAsm(_) => ty::List::empty(),
144150
}
145151
}
146152

@@ -152,7 +158,10 @@ impl<'tcx> DefiningTy<'tcx> {
152158
DefiningTy::Closure(..)
153159
| DefiningTy::CoroutineClosure(..)
154160
| DefiningTy::Coroutine(..) => 1,
155-
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => 0,
161+
DefiningTy::FnDef(..)
162+
| DefiningTy::Const(..)
163+
| DefiningTy::InlineConst(..)
164+
| DefiningTy::GlobalAsm(_) => 0,
156165
}
157166
}
158167

@@ -171,7 +180,8 @@ impl<'tcx> DefiningTy<'tcx> {
171180
| DefiningTy::Coroutine(def_id, ..)
172181
| DefiningTy::FnDef(def_id, ..)
173182
| DefiningTy::Const(def_id, ..)
174-
| DefiningTy::InlineConst(def_id, ..) => def_id,
183+
| DefiningTy::InlineConst(def_id, ..)
184+
| DefiningTy::GlobalAsm(def_id) => def_id,
175185
}
176186
}
177187
}
@@ -411,6 +421,7 @@ impl<'tcx> UniversalRegions<'tcx> {
411421
tcx.def_path_str_with_args(def_id, args),
412422
));
413423
}
424+
DefiningTy::GlobalAsm(_) => unreachable!(),
414425
}
415426
}
416427

@@ -633,6 +644,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
633644
DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
634645
}
635646
}
647+
648+
BodyOwnerKind::GlobalAsm => DefiningTy::GlobalAsm(self.mir_def.to_def_id()),
636649
}
637650
}
638651

@@ -666,6 +679,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
666679
}
667680

668681
DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args,
682+
683+
DefiningTy::GlobalAsm(_) => ty::List::empty(),
669684
};
670685

671686
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
@@ -802,6 +817,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
802817
let ty = args.as_inline_const().ty();
803818
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
804819
}
820+
821+
DefiningTy::GlobalAsm(def_id) => {
822+
ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()]))
823+
}
805824
};
806825

807826
// FIXME(#129952): We probably want a more principled approach here.

0 commit comments

Comments
 (0)