Handle not all immediates having abi::Scalar
s · rust-lang/rust@d757c4b (original) (raw)
`@@ -223,13 +223,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
`
223
223
`let OperandValueKind::Immediate(in_scalar) = operand_kind else {
`
224
224
`bug!("Found {operand_kind:?} for operand {operand:?}");
`
225
225
`};
`
226
``
`-
if let OperandValueKind::Immediate(out_scalar) = cast_kind
`
227
``
`-
&& in_scalar.size(self.cx) == out_scalar.size(self.cx)
`
228
``
`-
{
`
229
``
`-
let cast_bty = bx.backend_type(cast);
`
230
``
`-
Some(OperandValue::Immediate(
`
231
``
`-
self.transmute_immediate(bx, imm, in_scalar, out_scalar, cast_bty),
`
232
``
`-
))
`
``
226
`+
if let OperandValueKind::Immediate(out_scalar) = cast_kind {
`
``
227
`+
match (in_scalar, out_scalar) {
`
``
228
`+
(ScalarOrZst::Zst, ScalarOrZst::Zst) => {
`
``
229
`+
Some(OperandRef::new_zst(bx, cast).val)
`
``
230
`+
}
`
``
231
`+
(ScalarOrZst::Scalar(in_scalar), ScalarOrZst::Scalar(out_scalar))
`
``
232
`+
if in_scalar.size(self.cx) == out_scalar.size(self.cx) =>
`
``
233
`+
{
`
``
234
`+
let cast_bty = bx.backend_type(cast);
`
``
235
`+
Some(OperandValue::Immediate(
`
``
236
`+
self.transmute_immediate(bx, imm, in_scalar, out_scalar, cast_bty),
`
``
237
`+
))
`
``
238
`+
}
`
``
239
`+
_ => None,
`
``
240
`+
}
`
233
241
`} else {
`
234
242
`None
`
235
243
`}
`
`@@ -892,13 +900,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
`
892
900
`if self.cx.is_backend_immediate(layout) {
`
893
901
`debug_assert!(!self.cx.is_backend_scalar_pair(layout));
`
894
902
`OperandValueKind::Immediate(match layout.abi {
`
895
``
`-
abi::Abi::Scalar(s) => s,
`
896
``
`-
abi::Abi::Vector { element, .. } => element,
`
897
``
`-
x => bug!("Couldn't translate {x:?} as backend immediate"),
`
``
903
`+
abi::Abi::Scalar(s) => ScalarOrZst::Scalar(s),
`
``
904
`+
abi::Abi::Vector { element, .. } => ScalarOrZst::Scalar(element),
`
``
905
`+
_ if layout.is_zst() => ScalarOrZst::Zst,
`
``
906
`+
x => span_bug!(self.mir.span, "Couldn't translate {x:?} as backend immediate"),
`
898
907
`})
`
899
908
`} else if self.cx.is_backend_scalar_pair(layout) {
`
900
909
`let abi::Abi::ScalarPair(s1, s2) = layout.abi else {
`
901
``
`-
bug!("Couldn't translate {:?} as backend scalar pair", layout.abi)
`
``
910
`+
span_bug!(
`
``
911
`+
self.mir.span,
`
``
912
`+
"Couldn't translate {:?} as backend scalar pair",
`
``
913
`+
layout.abi,
`
``
914
`+
);
`
902
915
`};
`
903
916
`OperandValueKind::Pair(s1, s2)
`
904
917
`} else {
`
`@@ -907,9 +920,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
`
907
920
`}
`
908
921
`}
`
909
922
``
``
923
`` +
/// The variants of this match [OperandValue
], giving details about the
``
``
924
`+
/// backend values that will be held in that other type.
`
910
925
`#[derive(Debug, Copy, Clone)]
`
911
926
`enum OperandValueKind {
`
912
927
`Ref,
`
913
``
`-
Immediate(abi::Scalar),
`
``
928
`+
Immediate(ScalarOrZst),
`
914
929
`Pair(abi::Scalar, abi::Scalar),
`
915
930
`}
`
``
931
+
``
932
`+
#[derive(Debug, Copy, Clone)]
`
``
933
`+
enum ScalarOrZst {
`
``
934
`+
Zst,
`
``
935
`+
Scalar(abi::Scalar),
`
``
936
`+
}
`
``
937
+
``
938
`+
impl ScalarOrZst {
`
``
939
`+
pub fn size(self, cx: &impl abi::HasDataLayout) -> abi::Size {
`
``
940
`+
match self {
`
``
941
`+
ScalarOrZst::Zst => abi::Size::ZERO,
`
``
942
`+
ScalarOrZst::Scalar(s) => s.size(cx),
`
``
943
`+
}
`
``
944
`+
}
`
``
945
`+
}
`