Skip to content

Commit eed1f75

Browse files
committed
Don't store vector types in ssa variables
They have been causing a lot of trouble. For example current MIR building thinks that it is fine to dynamically index into them. And there are different paths depending on if the repr(simd) struct uses fields or a single array as interior. There is also trouble with moving the inner array of a repr(simd) type that is an array wrapper. If performance becomes a concern, I will implement this in a more principled way.
1 parent 6bced6e commit eed1f75

File tree

7 files changed

+15
-167
lines changed

7 files changed

+15
-167
lines changed

scripts/test_rustc_tests.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ rm tests/incremental/spike-neg2.rs # same
112112

113113
rm tests/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors
114114

115-
rm tests/ui/simd/intrinsic/generic-as.rs # crash when accessing vector type field (#1318)
116115
rm tests/ui/simd/simd-bitmask.rs # crash
117116

118117
# bugs in the test suite

src/abi/comments.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ pub(super) fn add_local_place_comments<'tcx>(
100100
assert_eq!(local, place_local);
101101
("ssa", Cow::Owned(format!("var=({}, {})", var1.index(), var2.index())))
102102
}
103-
CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(),
104103
CPlaceInner::Addr(ptr, meta) => {
105104
let meta = if let Some(meta) = meta {
106105
Cow::Owned(format!("meta={}", meta))

src/abi/pass_mode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
8484
attrs
8585
)],
8686
Abi::Vector { .. } => {
87-
let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap();
87+
let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout);
8888
smallvec![AbiParam::new(vector_ty)]
8989
}
9090
_ => unreachable!("{:?}", self.layout.abi),
@@ -135,7 +135,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
135135
(None, vec![AbiParam::new(scalar_to_clif_type(tcx, scalar))])
136136
}
137137
Abi::Vector { .. } => {
138-
let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap();
138+
let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout);
139139
(None, vec![AbiParam::new(vector_ty)])
140140
}
141141
_ => unreachable!("{:?}", self.layout.abi),

src/common.rs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,6 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
7272
pointer_ty(tcx)
7373
}
7474
}
75-
ty::Adt(adt_def, _) if adt_def.repr().simd() => {
76-
let (element, count) = match &tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().abi
77-
{
78-
Abi::Vector { element, count } => (*element, *count),
79-
_ => unreachable!(),
80-
};
81-
82-
match scalar_to_clif_type(tcx, element).by(u32::try_from(count).unwrap()) {
83-
// Cranelift currently only implements icmp for 128bit vectors.
84-
Some(vector_ty) if vector_ty.bits() == 128 => vector_ty,
85-
_ => return None,
86-
}
87-
}
8875
ty::Param(_) => bug!("ty param {:?}", ty),
8976
_ => return None,
9077
})
@@ -96,12 +83,7 @@ fn clif_pair_type_from_ty<'tcx>(
9683
) -> Option<(types::Type, types::Type)> {
9784
Some(match ty.kind() {
9885
ty::Tuple(types) if types.len() == 2 => {
99-
let a = clif_type_from_ty(tcx, types[0])?;
100-
let b = clif_type_from_ty(tcx, types[1])?;
101-
if a.is_vector() || b.is_vector() {
102-
return None;
103-
}
104-
(a, b)
86+
(clif_type_from_ty(tcx, types[0])?, clif_type_from_ty(tcx, types[1])?)
10587
}
10688
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
10789
if has_ptr_meta(tcx, *pointee_ty) {

src/intrinsics/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,13 @@ fn report_atomic_type_validation_error<'tcx>(
5151
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
5252
}
5353

54-
pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> Option<Type> {
54+
pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> Type {
5555
let (element, count) = match layout.abi {
5656
Abi::Vector { element, count } => (element, count),
5757
_ => unreachable!(),
5858
};
5959

60-
match scalar_to_clif_type(tcx, element).by(u32::try_from(count).unwrap()) {
61-
// Cranelift currently only implements icmp for 128bit vectors.
62-
Some(vector_ty) if vector_ty.bits() == 128 => Some(vector_ty),
63-
_ => None,
64-
}
60+
scalar_to_clif_type(tcx, element).by(u32::try_from(count).unwrap()).unwrap()
6561
}
6662

6763
fn simd_for_each_lane<'tcx>(

src/intrinsics/simd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
253253
}
254254

255255
ret.write_cvalue(fx, base);
256-
let ret_lane = ret.place_field(fx, mir::Field::new(idx.try_into().unwrap()));
256+
let ret_lane = ret.place_lane(fx, idx.try_into().unwrap());
257257
ret_lane.write_cvalue(fx, val);
258258
}
259259

src/value_and_place.rs

Lines changed: 9 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use crate::prelude::*;
44

55
use cranelift_codegen::ir::immediates::Offset32;
6-
use cranelift_codegen::ir::{InstructionData, Opcode};
76

87
fn codegen_field<'tcx>(
98
fx: &mut FunctionCx<'_, '_, 'tcx>,
@@ -166,9 +165,6 @@ impl<'tcx> CValue<'tcx> {
166165
CValueInner::ByRef(ptr, None) => {
167166
let clif_ty = match layout.abi {
168167
Abi::Scalar(scalar) => scalar_to_clif_type(fx.tcx, scalar),
169-
Abi::Vector { element, count } => scalar_to_clif_type(fx.tcx, element)
170-
.by(u32::try_from(count).unwrap())
171-
.unwrap(),
172168
_ => unreachable!("{:?}", layout.ty),
173169
};
174170
let mut flags = MemFlags::new();
@@ -214,17 +210,7 @@ impl<'tcx> CValue<'tcx> {
214210
) -> CValue<'tcx> {
215211
let layout = self.1;
216212
match self.0 {
217-
CValueInner::ByVal(val) => match layout.abi {
218-
Abi::Vector { element: _, count } => {
219-
let count = u8::try_from(count).expect("SIMD type with more than 255 lanes???");
220-
let field = u8::try_from(field.index()).unwrap();
221-
assert!(field < count);
222-
let lane = fx.bcx.ins().extractlane(val, field);
223-
let field_layout = layout.field(&*fx, usize::from(field));
224-
CValue::by_val(lane, field_layout)
225-
}
226-
_ => unreachable!("value_field for ByVal with abi {:?}", layout.abi),
227-
},
213+
CValueInner::ByVal(_) => unreachable!(),
228214
CValueInner::ByValPair(val1, val2) => match layout.abi {
229215
Abi::ScalarPair(_, _) => {
230216
let val = match field.as_u32() {
@@ -258,16 +244,7 @@ impl<'tcx> CValue<'tcx> {
258244
let lane_layout = fx.layout_of(lane_ty);
259245
assert!(lane_idx < lane_count);
260246
match self.0 {
261-
CValueInner::ByVal(val) => match layout.abi {
262-
Abi::Vector { element: _, count: _ } => {
263-
assert!(lane_count <= u8::MAX.into(), "SIMD type with more than 255 lanes???");
264-
let lane_idx = u8::try_from(lane_idx).unwrap();
265-
let lane = fx.bcx.ins().extractlane(val, lane_idx);
266-
CValue::by_val(lane, lane_layout)
267-
}
268-
_ => unreachable!("value_lane for ByVal with abi {:?}", layout.abi),
269-
},
270-
CValueInner::ByValPair(_, _) => unreachable!(),
247+
CValueInner::ByVal(_) | CValueInner::ByValPair(_, _) => unreachable!(),
271248
CValueInner::ByRef(ptr, None) => {
272249
let field_offset = lane_layout.size * lane_idx;
273250
let field_ptr = ptr.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap());
@@ -348,7 +325,6 @@ pub(crate) struct CPlace<'tcx> {
348325
pub(crate) enum CPlaceInner {
349326
Var(Local, Variable),
350327
VarPair(Local, Variable, Variable),
351-
VarLane(Local, Variable, u8),
352328
Addr(Pointer, Option<Value>),
353329
}
354330

@@ -442,12 +418,6 @@ impl<'tcx> CPlace<'tcx> {
442418
//fx.bcx.set_val_label(val2, cranelift_codegen::ir::ValueLabel::new(var2.index()));
443419
CValue::by_val_pair(val1, val2, layout)
444420
}
445-
CPlaceInner::VarLane(_local, var, lane) => {
446-
let val = fx.bcx.use_var(var);
447-
//fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index()));
448-
let val = fx.bcx.ins().extractlane(val, lane);
449-
CValue::by_val(val, layout)
450-
}
451421
CPlaceInner::Addr(ptr, extra) => {
452422
if let Some(extra) = extra {
453423
CValue::by_ref_unsized(ptr, extra, layout)
@@ -470,9 +440,9 @@ impl<'tcx> CPlace<'tcx> {
470440
pub(crate) fn to_ptr_maybe_unsized(self) -> (Pointer, Option<Value>) {
471441
match self.inner {
472442
CPlaceInner::Addr(ptr, extra) => (ptr, extra),
473-
CPlaceInner::Var(_, _)
474-
| CPlaceInner::VarPair(_, _, _)
475-
| CPlaceInner::VarLane(_, _, _) => bug!("Expected CPlace::Addr, found {:?}", self),
443+
CPlaceInner::Var(_, _) | CPlaceInner::VarPair(_, _, _) => {
444+
bug!("Expected CPlace::Addr, found {:?}", self)
445+
}
476446
}
477447
}
478448

@@ -565,26 +535,6 @@ impl<'tcx> CPlace<'tcx> {
565535
let dst_layout = self.layout();
566536
let to_ptr = match self.inner {
567537
CPlaceInner::Var(_local, var) => {
568-
if let ty::Array(element, len) = dst_layout.ty.kind() {
569-
// Can only happen for vector types
570-
let len = u32::try_from(len.eval_target_usize(fx.tcx, ParamEnv::reveal_all()))
571-
.unwrap();
572-
let vector_ty = fx.clif_type(*element).unwrap().by(len).unwrap();
573-
574-
let data = match from.0 {
575-
CValueInner::ByRef(ptr, None) => {
576-
let mut flags = MemFlags::new();
577-
flags.set_notrap();
578-
ptr.load(fx, vector_ty, flags)
579-
}
580-
CValueInner::ByVal(_)
581-
| CValueInner::ByValPair(_, _)
582-
| CValueInner::ByRef(_, Some(_)) => bug!("array should be ByRef"),
583-
};
584-
585-
fx.bcx.def_var(var, data);
586-
return;
587-
}
588538
let data = CValue(from.0, dst_layout).load_scalar(fx);
589539
let dst_ty = fx.clif_type(self.layout().ty).unwrap();
590540
transmute_value(fx, var, data, dst_ty);
@@ -603,22 +553,6 @@ impl<'tcx> CPlace<'tcx> {
603553
transmute_value(fx, var2, data2, dst_ty2);
604554
return;
605555
}
606-
CPlaceInner::VarLane(_local, var, lane) => {
607-
let data = from.load_scalar(fx);
608-
609-
// First get the old vector
610-
let vector = fx.bcx.use_var(var);
611-
//fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
612-
613-
// Next insert the written lane into the vector
614-
let vector = fx.bcx.ins().insertlane(vector, data, lane);
615-
616-
// Finally write the new vector
617-
//fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index()));
618-
fx.bcx.def_var(var, vector);
619-
620-
return;
621-
}
622556
CPlaceInner::Addr(ptr, None) => {
623557
if dst_layout.size == Size::ZERO || dst_layout.abi == Abi::Uninhabited {
624558
return;
@@ -631,7 +565,6 @@ impl<'tcx> CPlace<'tcx> {
631565
let mut flags = MemFlags::new();
632566
flags.set_notrap();
633567
match from.layout().abi {
634-
// FIXME make Abi::Vector work too
635568
Abi::Scalar(_) => {
636569
let val = from.load_scalar(fx);
637570
to_ptr.store(fx, val, flags);
@@ -692,39 +625,6 @@ impl<'tcx> CPlace<'tcx> {
692625
let layout = self.layout();
693626

694627
match self.inner {
695-
CPlaceInner::Var(local, var) => match layout.ty.kind() {
696-
ty::Array(_, _) => {
697-
// Can only happen for vector types
698-
return CPlace {
699-
inner: CPlaceInner::VarLane(local, var, field.as_u32().try_into().unwrap()),
700-
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
701-
};
702-
}
703-
ty::Adt(adt_def, substs) if layout.ty.is_simd() => {
704-
let f0_ty = adt_def.non_enum_variant().fields[0].ty(fx.tcx, substs);
705-
706-
match f0_ty.kind() {
707-
ty::Array(_, _) => {
708-
assert_eq!(field.as_u32(), 0);
709-
return CPlace {
710-
inner: CPlaceInner::Var(local, var),
711-
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
712-
};
713-
}
714-
_ => {
715-
return CPlace {
716-
inner: CPlaceInner::VarLane(
717-
local,
718-
var,
719-
field.as_u32().try_into().unwrap(),
720-
),
721-
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
722-
};
723-
}
724-
}
725-
}
726-
_ => {}
727-
},
728628
CPlaceInner::VarPair(local, var1, var2) => {
729629
let layout = layout.field(&*fx, field.index());
730630

@@ -766,15 +666,8 @@ impl<'tcx> CPlace<'tcx> {
766666
assert!(lane_idx < lane_count);
767667

768668
match self.inner {
769-
CPlaceInner::Var(local, var) => {
770-
assert!(matches!(layout.abi, Abi::Vector { .. }));
771-
CPlace {
772-
inner: CPlaceInner::VarLane(local, var, lane_idx.try_into().unwrap()),
773-
layout: lane_layout,
774-
}
775-
}
669+
CPlaceInner::Var(_, _) => unreachable!(),
776670
CPlaceInner::VarPair(_, _, _) => unreachable!(),
777-
CPlaceInner::VarLane(_, _, _) => unreachable!(),
778671
CPlaceInner::Addr(ptr, None) => {
779672
let field_offset = lane_layout.size * lane_idx;
780673
let field_ptr = ptr.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap());
@@ -793,32 +686,11 @@ impl<'tcx> CPlace<'tcx> {
793686
ty::Array(elem_ty, _) => {
794687
let elem_layout = fx.layout_of(*elem_ty);
795688
match self.inner {
796-
CPlaceInner::Var(local, var) => {
797-
// This is a hack to handle `vector_val.0[1]`. It doesn't allow dynamic
798-
// indexing.
799-
let lane_idx = match fx.bcx.func.dfg.insts
800-
[fx.bcx.func.dfg.value_def(index).unwrap_inst()]
801-
{
802-
InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => imm,
803-
_ => bug!(
804-
"Dynamic indexing into a vector type is not supported: {self:?}[{index}]"
805-
),
806-
};
807-
return CPlace {
808-
inner: CPlaceInner::VarLane(
809-
local,
810-
var,
811-
lane_idx.bits().try_into().unwrap(),
812-
),
813-
layout: elem_layout,
814-
};
815-
}
816689
CPlaceInner::Addr(addr, None) => (elem_layout, addr),
817-
CPlaceInner::Addr(_, Some(_))
818-
| CPlaceInner::VarPair(_, _, _)
819-
| CPlaceInner::VarLane(_, _, _) => bug!("Can't index into {self:?}"),
690+
CPlaceInner::Var(_, _)
691+
| CPlaceInner::Addr(_, Some(_))
692+
| CPlaceInner::VarPair(_, _, _) => bug!("Can't index into {self:?}"),
820693
}
821-
// FIXME use VarLane in case of Var with simd type
822694
}
823695
ty::Slice(elem_ty) => (fx.layout_of(*elem_ty), self.to_ptr_maybe_unsized().0),
824696
_ => bug!("place_index({:?})", self.layout().ty),

0 commit comments

Comments
 (0)