Skip to content

Commit b012356

Browse files
authoredFeb 21, 2025
Rollup merge of #137361 - scottmcm:mcp-838-prep, r=compiler-errors
Refactor `OperandRef::extract_field` to prep for MCP838 cc rust-lang/compiler-team#838 This still supports exactly the same cases as it did before, just rearranged a bit to better emphasize what doesn't work.
2 parents ef14e9a + da77b39 commit b012356

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed
 

Diff for: ‎compiler/rustc_codegen_ssa/src/mir/operand.rs

+24-22
Original file line numberDiff line numberDiff line change
@@ -358,19 +358,33 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
358358
let field = self.layout.field(bx.cx(), i);
359359
let offset = self.layout.fields.offset(i);
360360

361-
let val = if field.is_zst() {
362-
OperandValue::ZeroSized
363-
} else if field.size == self.layout.size {
364-
assert_eq!(offset.bytes(), 0);
365-
if let Some(field_val) = fx.codegen_transmute_operand(bx, *self, field) {
366-
field_val
367-
} else {
368-
// we have to go through memory for things like
361+
if !bx.is_backend_ref(self.layout) && bx.is_backend_ref(field) {
362+
if let BackendRepr::Vector { count, .. } = self.layout.backend_repr
363+
&& let BackendRepr::Memory { sized: true } = field.backend_repr
364+
&& count.is_power_of_two()
365+
{
366+
assert_eq!(field.size, self.layout.size);
367+
// This is being deprecated, but for now stdarch still needs it for
369368
// Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
370369
let place = PlaceRef::alloca(bx, field);
371370
self.val.store(bx, place.val.with_type(self.layout));
372-
bx.load_operand(place).val
371+
return bx.load_operand(place);
372+
} else {
373+
// Part of https://github.com/rust-lang/compiler-team/issues/838
374+
bug!("Non-ref type {self:?} cannot project to ref field type {field:?}");
373375
}
376+
}
377+
378+
let val = if field.is_zst() {
379+
OperandValue::ZeroSized
380+
} else if field.size == self.layout.size {
381+
assert_eq!(offset.bytes(), 0);
382+
fx.codegen_transmute_operand(bx, *self, field).unwrap_or_else(|| {
383+
bug!(
384+
"Expected `codegen_transmute_operand` to handle equal-size \
385+
field {i:?} projection from {self:?} to {field:?}"
386+
)
387+
})
374388
} else {
375389
let (in_scalar, imm) = match (self.val, self.layout.backend_repr) {
376390
// Extract a scalar component from a pair.
@@ -385,11 +399,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
385399
}
386400
}
387401

388-
// `#[repr(simd)]` types are also immediate.
389-
(OperandValue::Immediate(llval), BackendRepr::Vector { .. }) => {
390-
(None, bx.extract_element(llval, bx.cx().const_usize(i as u64)))
391-
}
392-
393402
_ => {
394403
span_bug!(fx.mir.span, "OperandRef::extract_field({:?}): not applicable", self)
395404
}
@@ -415,14 +424,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
415424
imm
416425
}
417426
}
418-
BackendRepr::Memory { sized: true } => {
419-
span_bug!(
420-
fx.mir.span,
421-
"Projecting into a simd type with padding doesn't work; \
422-
See <https://github.com/rust-lang/rust/issues/137108>",
423-
);
424-
}
425-
BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { sized: false } => bug!(),
427+
BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { .. } => bug!(),
426428
})
427429
};
428430

0 commit comments

Comments
 (0)
Please sign in to comment.