Skip to content

Commit 4e7319c

Browse files
committed
add unchecked math intrinsics
1 parent d6266a7 commit 4e7319c

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

src/libcore/intrinsics.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,21 @@ extern "rust-intrinsic" {
12401240
/// y < 0 or y >= N, where N is the width of T in bits.
12411241
pub fn unchecked_shr<T>(x: T, y: T) -> T;
12421242

1243+
/// Returns the result of an unchecked addition, resulting in
1244+
/// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`.
1245+
#[cfg(not(stage0))]
1246+
pub fn unchecked_add<T>(x: T, y: T) -> T;
1247+
1248+
/// Returns the result of an unchecked substraction, resulting in
1249+
/// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`.
1250+
#[cfg(not(stage0))]
1251+
pub fn unchecked_sub<T>(x: T, y: T) -> T;
1252+
1253+
/// Returns the result of an unchecked multiplication, resulting in
1254+
/// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`.
1255+
#[cfg(not(stage0))]
1256+
pub fn unchecked_mul<T>(x: T, y: T) -> T;
1257+
12431258
/// Performs rotate left.
12441259
/// The stabilized versions of this intrinsic are available on the integer
12451260
/// primitives via the `rotate_left` method. For example,

src/librustc_codegen_llvm/intrinsic.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
334334
"ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
335335
"bitreverse" | "add_with_overflow" | "sub_with_overflow" |
336336
"mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
337-
"unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" |
337+
"unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" |
338+
"unchecked_add" | "unchecked_sub" | "unchecked_mul" | "exact_div" |
338339
"rotate_left" | "rotate_right" | "saturating_add" | "saturating_sub" => {
339340
let ty = arg_tys[0];
340341
match int_type_width_signed(ty, self) {
@@ -430,6 +431,27 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
430431
} else {
431432
self.lshr(args[0].immediate(), args[1].immediate())
432433
},
434+
"unchecked_add" => {
435+
if signed {
436+
self.unchecked_sadd(args[0].immediate(), args[1].immediate())
437+
} else {
438+
self.unchecked_uadd(args[0].immediate(), args[1].immediate())
439+
}
440+
},
441+
"unchecked_sub" => {
442+
if signed {
443+
self.unchecked_ssub(args[0].immediate(), args[1].immediate())
444+
} else {
445+
self.unchecked_usub(args[0].immediate(), args[1].immediate())
446+
}
447+
},
448+
"unchecked_mul" => {
449+
if signed {
450+
self.unchecked_smul(args[0].immediate(), args[1].immediate())
451+
} else {
452+
self.unchecked_umul(args[0].immediate(), args[1].immediate())
453+
}
454+
},
433455
"rotate_left" | "rotate_right" => {
434456
let is_left = name == "rotate_left";
435457
let val = args[0].immediate();

src/librustc_typeck/check/intrinsic.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,8 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
305305
"unchecked_shl" | "unchecked_shr" |
306306
"rotate_left" | "rotate_right" =>
307307
(1, vec![param(0), param(0)], param(0)),
308-
308+
"unchecked_add" | "unchecked_sub" | "unchecked_mul" =>
309+
(1, vec![param(0), param(0)], param(0)),
309310
"overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
310311
(1, vec![param(0), param(0)], param(0)),
311312
"saturating_add" | "saturating_sub" =>

0 commit comments

Comments
 (0)