Skip to content

Commit 5f00d80

Browse files
committed
Use a C-safe return type for __rust_[ui]128_* overflowing intrinsics
Combined with [1], this will change the overflowing multiplication operations to return an `extern "C"`-safe type. Link: rust-lang/compiler-builtins#735 [1]
1 parent 8247594 commit 5f00d80

File tree

3 files changed

+28
-36
lines changed

3 files changed

+28
-36
lines changed

compiler/rustc_codegen_cranelift/src/codegen_i128.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,24 @@ pub(crate) fn maybe_codegen_checked<'tcx>(
8282
BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => unreachable!(),
8383
BinOp::Add | BinOp::Sub => None,
8484
BinOp::Mul => {
85-
let out_ty = Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.bool]);
86-
let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty));
85+
let oflow_out_place = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32));
8786
let param_types = vec![
88-
AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn),
8987
AbiParam::new(types::I128),
9088
AbiParam::new(types::I128),
89+
AbiParam::special(fx.pointer_type, ArgumentPurpose::Normal),
9190
];
92-
let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)];
93-
fx.lib_call(
91+
let args =
92+
[lhs.load_scalar(fx), rhs.load_scalar(fx), oflow_out_place.to_ptr().get_addr(fx)];
93+
let ret = fx.lib_call(
9494
if is_signed { "__rust_i128_mulo" } else { "__rust_u128_mulo" },
9595
param_types,
96-
vec![],
96+
vec![AbiParam::new(types::I128)],
9797
&args,
9898
);
99-
Some(out_place.to_cvalue(fx))
99+
let mul = ret[0];
100+
let oflow = oflow_out_place.to_cvalue(fx).load_scalar(fx);
101+
let layout = fx.layout_of(Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.i32]));
102+
Some(CValue::by_val_pair(mul, oflow, layout))
100103
}
101104
BinOp::AddUnchecked | BinOp::SubUnchecked | BinOp::MulUnchecked => unreachable!(),
102105
BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(),

compiler/rustc_codegen_cranelift/src/compiler_builtins.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ builtin_functions! {
4343
fn __divti3(n: i128, d: i128) -> i128;
4444
fn __umodti3(n: u128, d: u128) -> u128;
4545
fn __modti3(n: i128, d: i128) -> i128;
46-
fn __rust_u128_mulo(a: u128, b: u128) -> (u128, bool);
46+
fn __rust_u128_mulo(a: u128, b: u128, oflow: &mut i32) -> u128;
4747

4848
// floats
4949
fn __floattisf(i: i128) -> f32;

compiler/rustc_codegen_gcc/src/int.rs

+17-28
Original file line numberDiff line numberDiff line change
@@ -322,34 +322,23 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
322322
},
323323
}
324324
} else {
325-
match new_kind {
326-
Int(I128) | Uint(U128) => {
327-
let func_name = match oop {
328-
OverflowOp::Add => match new_kind {
329-
Int(I128) => "__rust_i128_addo",
330-
Uint(U128) => "__rust_u128_addo",
331-
_ => unreachable!(),
332-
},
333-
OverflowOp::Sub => match new_kind {
334-
Int(I128) => "__rust_i128_subo",
335-
Uint(U128) => "__rust_u128_subo",
336-
_ => unreachable!(),
337-
},
338-
OverflowOp::Mul => match new_kind {
339-
Int(I128) => "__rust_i128_mulo", // TODO(antoyo): use __muloti4d instead?
340-
Uint(U128) => "__rust_u128_mulo",
341-
_ => unreachable!(),
342-
},
343-
};
344-
return self.operation_with_overflow(func_name, lhs, rhs);
345-
}
346-
_ => match oop {
347-
OverflowOp::Mul => match new_kind {
348-
Int(I32) => "__mulosi4",
349-
Int(I64) => "__mulodi4",
350-
_ => unreachable!(),
351-
},
352-
_ => unimplemented!("overflow operation for {:?}", new_kind),
325+
match oop {
326+
OverflowOp::Add => match new_kind {
327+
Int(I128) => "__rust_i128_addo",
328+
Uint(U128) => "__rust_u128_addo",
329+
_ => unreachable!(),
330+
},
331+
OverflowOp::Sub => match new_kind {
332+
Int(I128) => "__rust_i128_subo",
333+
Uint(U128) => "__rust_u128_subo",
334+
_ => unreachable!(),
335+
},
336+
OverflowOp::Mul => match new_kind {
337+
Int(I32) => "__mulosi4",
338+
Int(I64) => "__mulodi4",
339+
Int(I128) => "__rust_i128_mulo", // TODO(antoyo): use __muloti4d instead?
340+
Uint(U128) => "__rust_u128_mulo",
341+
_ => unreachable!(),
353342
},
354343
}
355344
};

0 commit comments

Comments
 (0)