Auto merge of #123886 - scottmcm:more-rvalue-operands, r= · rust-lang/rust@1d0d3d3 (original) (raw)
`@@ -15,7 +15,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
`
15
15
`use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, Ty, TyCtxt};
`
16
16
`use rustc_session::config::OptLevel;
`
17
17
`use rustc_span::{Span, DUMMY_SP};
`
18
``
`-
use rustc_target::abi::{self, FIRST_VARIANT};
`
``
18
`+
use rustc_target::abi::{self, FieldIdx, FIRST_VARIANT};
`
19
19
``
20
20
`impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
`
21
21
`#[instrument(level = "trace", skip(self, bx))]
`
`@@ -720,12 +720,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
`
720
720
`OperandRef { val: OperandValue::Immediate(static_), layout }
`
721
721
`}
`
722
722
` mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
`
723
``
`-
mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => {
`
``
723
`+
mir::Rvalue::Repeat(..) => {
`
724
724
`` // According to rvalue_creates_operand
, only ZST
``
725
``
`-
// aggregate rvalues are allowed to be operands.
`
``
725
`+
// repat rvalues are allowed to be operands.
`
726
726
`let ty = rvalue.ty(self.mir, self.cx.tcx());
`
727
727
`OperandRef::zero_sized(self.cx.layout_of(self.monomorphize(ty)))
`
728
728
`}
`
``
729
`+
mir::Rvalue::Aggregate(ref kind, ref fields) => {
`
``
730
`+
let ty = rvalue.ty(self.mir, self.cx.tcx());
`
``
731
`+
let ty = self.monomorphize(ty);
`
``
732
`+
let layout = self.cx.layout_of(self.monomorphize(ty));
`
``
733
`+
match **kind {
`
``
734
`+
_ if layout.is_zst() => OperandRef::zero_sized(layout),
`
``
735
`+
mir::AggregateKind::Tuple => {
`
``
736
`+
debug_assert_eq!(
`
``
737
`+
fields.len(),
`
``
738
`+
2,
`
``
739
`+
"We should only get pairs, but got {rvalue:?}"
`
``
740
`+
);
`
``
741
`+
let a = self.codegen_operand(bx, &fields[FieldIdx::ZERO]);
`
``
742
`+
let b = self.codegen_operand(bx, &fields[FieldIdx::from_u32(1)]);
`
``
743
`+
let val = OperandValue::Pair(a.immediate(), b.immediate());
`
``
744
`+
OperandRef { val, layout }
`
``
745
`+
}
`
``
746
`+
mir::AggregateKind::Adt(..) => {
`
``
747
`+
let (field_idx, _) = layout
`
``
748
`+
.non_1zst_field(self.cx)
`
``
749
`+
.expect("only transparent non-ZST structs should get here");
`
``
750
`+
let field = self.codegen_operand(bx, &fields[field_idx]);
`
``
751
`+
// While the size is the same, since the struct is transparent,
`
``
752
`` +
// calling transmute here handles the i1
-vs-i8
issues for bool
.
``
``
753
`+
let Some(val) = self.codegen_transmute_operand(bx, field, layout) else {
`
``
754
`+
bug!("Couldn't transmute {field:?} to {layout:?}");
`
``
755
`+
};
`
``
756
`+
OperandRef { val, layout }
`
``
757
`+
}
`
``
758
`+
_ => bug!("Unexpected in codegen_rvalue_operand: {rvalue:?}"),
`
``
759
`+
}
`
``
760
`+
}
`
729
761
` mir::Rvalue::ShallowInitBox(ref operand, content_ty) => {
`
730
762
`let operand = self.codegen_operand(bx, operand);
`
731
763
`let val = operand.immediate();
`
`@@ -1032,12 +1064,37 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
`
1032
1064
` mir::Rvalue::ThreadLocalRef(_) |
`
1033
1065
` mir::Rvalue::Use(..) => // (*)
`
1034
1066
`true,
`
1035
``
`-
mir::Rvalue::Repeat(..) |
`
1036
``
`-
mir::Rvalue::Aggregate(..) => {
`
``
1067
`+
mir::Rvalue::Repeat(..) => {
`
1037
1068
`let ty = rvalue.ty(self.mir, self.cx.tcx());
`
1038
1069
`let ty = self.monomorphize(ty);
`
1039
``
`` -
// For ZST this can be OperandValueKind::ZeroSized
.
``
1040
``
`-
self.cx.spanned_layout_of(ty, span).is_zst()
`
``
1070
`+
let layout = self.cx.spanned_layout_of(ty, span);
`
``
1071
`+
layout.is_zst()
`
``
1072
`+
}
`
``
1073
`+
mir::Rvalue::Aggregate(ref kind, ref fields) => {
`
``
1074
`+
let ty = rvalue.ty(self.mir, self.cx.tcx());
`
``
1075
`+
let ty = self.monomorphize(ty);
`
``
1076
`+
let layout = self.cx.spanned_layout_of(ty, span);
`
``
1077
`+
match **kind {
`
``
1078
`+
// OperandValue::ZeroSized is easy
`
``
1079
`+
_ if layout.is_zst() => true,
`
``
1080
`+
// 2-Tuple of scalars is an easy scalar pair
`
``
1081
`+
mir::AggregateKind::Tuple => {
`
``
1082
`+
fields.len() == 2
`
``
1083
`+
&& self.cx.is_backend_scalar_pair(layout)
`
``
1084
`+
&& fields.iter().all(|field| {
`
``
1085
`+
let field_ty = field.ty(self.mir, self.cx.tcx());
`
``
1086
`+
let field_ty = self.monomorphize(field_ty);
`
``
1087
`+
let field_layout = self.cx.spanned_layout_of(field_ty, span);
`
``
1088
`+
self.cx.is_backend_immediate(field_layout)
`
``
1089
`+
})
`
``
1090
`+
}
`
``
1091
`+
// If a non-union is transparent, we can pass it along
`
``
1092
`+
mir::AggregateKind::Adt(_, _, _, _, None) => {
`
``
1093
`+
ty.ty_adt_def().is_some_and(|def| def.repr().transparent())
`
``
1094
`+
&& !self.cx.is_backend_ref(layout)
`
``
1095
`+
}
`
``
1096
`+
_ => false,
`
``
1097
`+
}
`
1041
1098
`}
`
1042
1099
`}
`
1043
1100
``