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

``