Skip to content

Commit dd288d2

Browse files
committed
Fix vector types containing an array field with mir opts enabled
1 parent 516b478 commit dd288d2

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

src/value_and_place.rs

+48-3
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,26 @@ impl<'tcx> CPlace<'tcx> {
510510
let dst_layout = self.layout();
511511
let to_ptr = match self.inner {
512512
CPlaceInner::Var(_local, var) => {
513+
if let ty::Array(element, len) = dst_layout.ty.kind() {
514+
// Can only happen for vector types
515+
let len =
516+
u16::try_from(len.eval_usize(fx.tcx, ParamEnv::reveal_all())).unwrap();
517+
let vector_ty = fx.clif_type(element).unwrap().by(len).unwrap();
518+
519+
let data = match from.0 {
520+
CValueInner::ByRef(ptr, None) => {
521+
let mut flags = MemFlags::new();
522+
flags.set_notrap();
523+
ptr.load(fx, vector_ty, flags)
524+
}
525+
CValueInner::ByVal(_)
526+
| CValueInner::ByValPair(_, _)
527+
| CValueInner::ByRef(_, Some(_)) => bug!("array should be ByRef"),
528+
};
529+
530+
fx.bcx.def_var(var, data);
531+
return;
532+
}
513533
let data = CValue(from.0, dst_layout).load_scalar(fx);
514534
let dst_ty = fx.clif_type(self.layout().ty).unwrap();
515535
transmute_value(fx, var, data, dst_ty);
@@ -603,14 +623,39 @@ impl<'tcx> CPlace<'tcx> {
603623
let layout = self.layout();
604624

605625
match self.inner {
606-
CPlaceInner::Var(local, var) => {
607-
if let Abi::Vector { .. } = layout.abi {
626+
CPlaceInner::Var(local, var) => match layout.ty.kind() {
627+
ty::Array(_, _) => {
628+
// Can only happen for vector types
608629
return CPlace {
609630
inner: CPlaceInner::VarLane(local, var, field.as_u32().try_into().unwrap()),
610631
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
611632
};
612633
}
613-
}
634+
ty::Adt(adt_def, substs) if layout.ty.is_simd() => {
635+
let f0_ty = adt_def.non_enum_variant().fields[0].ty(fx.tcx, substs);
636+
637+
match f0_ty.kind() {
638+
ty::Array(_, _) => {
639+
assert_eq!(field.as_u32(), 0);
640+
return CPlace {
641+
inner: CPlaceInner::Var(local, var),
642+
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
643+
};
644+
}
645+
_ => {
646+
return CPlace {
647+
inner: CPlaceInner::VarLane(
648+
local,
649+
var,
650+
field.as_u32().try_into().unwrap(),
651+
),
652+
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
653+
};
654+
}
655+
}
656+
}
657+
_ => {}
658+
},
614659
CPlaceInner::VarPair(local, var1, var2) => {
615660
let layout = layout.field(&*fx, field.index());
616661

0 commit comments

Comments
 (0)