Skip to content

Commit 5bf5153

Browse files
committed
Fix non-dynamic indexing into vector types
1 parent 478bc5b commit 5bf5153

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

src/value_and_place.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use crate::prelude::*;
44

55
use cranelift_codegen::ir::immediates::Offset32;
6+
use cranelift_codegen::ir::{InstructionData, Opcode};
67

78
fn codegen_field<'tcx>(
89
fx: &mut FunctionCx<'_, '_, 'tcx>,
@@ -457,13 +458,15 @@ impl<'tcx> CPlace<'tcx> {
457458
}
458459
}
459460

461+
#[track_caller]
460462
pub(crate) fn to_ptr(self) -> Pointer {
461463
match self.to_ptr_maybe_unsized() {
462464
(ptr, None) => ptr,
463465
(_, Some(_)) => bug!("Expected sized cplace, found {:?}", self),
464466
}
465467
}
466468

469+
#[track_caller]
467470
pub(crate) fn to_ptr_maybe_unsized(self) -> (Pointer, Option<Value>) {
468471
match self.inner {
469472
CPlaceInner::Addr(ptr, extra) => (ptr, extra),
@@ -787,7 +790,36 @@ impl<'tcx> CPlace<'tcx> {
787790
index: Value,
788791
) -> CPlace<'tcx> {
789792
let (elem_layout, ptr) = match self.layout().ty.kind() {
790-
ty::Array(elem_ty, _) => (fx.layout_of(*elem_ty), self.to_ptr()),
793+
ty::Array(elem_ty, _) => {
794+
let elem_layout = fx.layout_of(*elem_ty);
795+
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+
}
816+
CPlaceInner::Addr(addr, None) => (elem_layout, addr),
817+
CPlaceInner::Addr(_, Some(_))
818+
| CPlaceInner::VarPair(_, _, _)
819+
| CPlaceInner::VarLane(_, _, _) => bug!("Can't index into {self:?}"),
820+
}
821+
// FIXME use VarLane in case of Var with simd type
822+
}
791823
ty::Slice(elem_ty) => (fx.layout_of(*elem_ty), self.to_ptr_maybe_unsized().0),
792824
_ => bug!("place_index({:?})", self.layout().ty),
793825
};

0 commit comments

Comments
 (0)