Skip to content

Commit c9782e4

Browse files
committed
Fix saturating sub for 128-bit integers
1 parent d7d84d3 commit c9782e4

File tree

2 files changed

+49
-73
lines changed

2 files changed

+49
-73
lines changed

gcc-test-backend/src/main.rs

Lines changed: 49 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#![feature(const_option)]
22

3-
use std::num::{NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize};
4-
53
fn main() {
64
/*test_float!(f64, f64, f64::INFINITY, f64::NEG_INFINITY, f64::NAN);
75
($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => {*/
@@ -156,67 +154,53 @@ fn main() {
156154
println!();
157155
*/
158156

159-
assert_eq!(NonZeroU8::new(1).unwrap().trailing_zeros(), 0);
160-
assert_eq!(NonZeroI8::new(1).unwrap().trailing_zeros(), 0);
161-
assert_eq!(NonZeroU16::new(1).unwrap().trailing_zeros(), 0);
162-
assert_eq!(NonZeroI16::new(1).unwrap().trailing_zeros(), 0);
163-
assert_eq!(NonZeroU32::new(1).unwrap().trailing_zeros(), 0);
164-
assert_eq!(NonZeroI32::new(1).unwrap().trailing_zeros(), 0);
165-
assert_eq!(NonZeroU64::new(1).unwrap().trailing_zeros(), 0);
166-
assert_eq!(NonZeroI64::new(1).unwrap().trailing_zeros(), 0);
167-
assert_eq!(NonZeroU128::new(1).unwrap().trailing_zeros(), 0);
168-
assert_eq!(NonZeroI128::new(1).unwrap().trailing_zeros(), 0);
169-
assert_eq!(NonZeroUsize::new(1).unwrap().trailing_zeros(), 0);
170-
assert_eq!(NonZeroIsize::new(1).unwrap().trailing_zeros(), 0);
171-
172-
assert_eq!(NonZeroU8::new(1 << 2).unwrap().trailing_zeros(), 2);
173-
assert_eq!(NonZeroI8::new(1 << 2).unwrap().trailing_zeros(), 2);
174-
assert_eq!(NonZeroU16::new(1 << 2).unwrap().trailing_zeros(), 2);
175-
assert_eq!(NonZeroI16::new(1 << 2).unwrap().trailing_zeros(), 2);
176-
assert_eq!(NonZeroU32::new(1 << 2).unwrap().trailing_zeros(), 2);
177-
assert_eq!(NonZeroI32::new(1 << 2).unwrap().trailing_zeros(), 2);
178-
assert_eq!(NonZeroU64::new(1 << 2).unwrap().trailing_zeros(), 2);
179-
assert_eq!(NonZeroI64::new(1 << 2).unwrap().trailing_zeros(), 2);
180-
assert_eq!(NonZeroU128::new(1 << 2).unwrap().trailing_zeros(), 2);
181-
assert_eq!(NonZeroI128::new(1 << 2).unwrap().trailing_zeros(), 2);
182-
assert_eq!(NonZeroUsize::new(1 << 2).unwrap().trailing_zeros(), 2);
183-
assert_eq!(NonZeroIsize::new(1 << 2).unwrap().trailing_zeros(), 2);
184-
185-
assert_eq!(NonZeroU8::new(1 << 7).unwrap().trailing_zeros(), 7);
186-
assert_eq!(NonZeroI8::new(1 << 7).unwrap().trailing_zeros(), 7);
187-
assert_eq!(NonZeroU16::new(1 << 15).unwrap().trailing_zeros(), 15);
188-
assert_eq!(NonZeroI16::new(1 << 15).unwrap().trailing_zeros(), 15);
189-
assert_eq!(NonZeroU32::new(1 << 31).unwrap().trailing_zeros(), 31);
190-
assert_eq!(NonZeroI32::new(1 << 31).unwrap().trailing_zeros(), 31);
191-
assert_eq!(NonZeroU64::new(1 << 63).unwrap().trailing_zeros(), 63);
192-
assert_eq!(NonZeroI64::new(1 << 63).unwrap().trailing_zeros(), 63);
193-
assert_eq!(NonZeroU128::new(1 << 127).unwrap().trailing_zeros(), 127);
194-
assert_eq!(NonZeroI128::new(1 << 127).unwrap().trailing_zeros(), 127);
195-
196-
assert_eq!(
197-
NonZeroUsize::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
198-
usize::BITS - 1
199-
);
200-
assert_eq!(
201-
NonZeroIsize::new(1 << (usize::BITS - 1)).unwrap().trailing_zeros(),
202-
usize::BITS - 1
203-
);
204-
205-
const TRAILING_ZEROS: u32 = NonZeroU16::new(1 << 2).unwrap().trailing_zeros();
206-
assert_eq!(TRAILING_ZEROS, 2);
207-
208-
const A: u128 = 0b0101100;
209-
const B: u128 = 0b0100001;
210-
const C: u128 = 0b1111001;
211-
212-
const _0: u128 = 0;
213-
const _1: u128 = !0;
214-
215-
assert_eq!(u128::from_be(A.to_be()), A);
216-
assert_eq!(u128::from_be(B.to_be()), B);
217-
assert_eq!(u128::from_be(C.to_be()), C);
218-
assert_eq!(u128::from_be(_0), _0);
219-
assert_eq!(u128::from_be(_1), _1);
220-
assert_eq!(_0.to_be(), _0);
221-
assert_eq!(_1.to_be(), _1);
157+
/*let mut r = 2 as i128;
158+
assert_eq!(r.pow(2), 4 as i128);
159+
assert_eq!(r.pow(0), 1 as i128);
160+
assert_eq!(r.wrapping_pow(2), 4 as i128);
161+
assert_eq!(r.wrapping_pow(0), 1 as i128);
162+
assert_eq!(r.checked_pow(2), Some(4 as i128));
163+
assert_eq!(r.checked_pow(0), Some(1 as i128));
164+
assert_eq!(r.overflowing_pow(2), (4 as i128, false));
165+
assert_eq!(r.overflowing_pow(0), (1 as i128, false));
166+
assert_eq!(r.saturating_pow(2), 4 as i128);
167+
assert_eq!(r.saturating_pow(0), 1 as i128);
168+
169+
r = i128::MAX;
170+
// use `^` to represent .pow() with no overflow.
171+
// if itest::MAX == 2^j-1, then itest is a `j` bit int,
172+
// so that `itest::MAX*itest::MAX == 2^(2*j)-2^(j+1)+1`,
173+
// thussaturating_pow the overflowing result is exactly 1.
174+
assert_eq!(r.wrapping_pow(2), 1 as i128);
175+
assert_eq!(r.checked_pow(2), None);
176+
assert_eq!(r.overflowing_pow(2), (1 as i128, true));
177+
assert_eq!(r.saturating_pow(2), i128::MAX);
178+
//test for negative exponent.
179+
r = -2 as i128;
180+
assert_eq!(r.pow(2), 4 as i128);
181+
assert_eq!(r.pow(3), -8 as i128);
182+
assert_eq!(r.pow(0), 1 as i128);
183+
assert_eq!(r.wrapping_pow(2), 4 as i128);
184+
assert_eq!(r.wrapping_pow(3), -8 as i128);
185+
assert_eq!(r.wrapping_pow(0), 1 as i128);
186+
assert_eq!(r.checked_pow(2), Some(4 as i128));
187+
assert_eq!(r.checked_pow(3), Some(-8 as i128));
188+
assert_eq!(r.checked_pow(0), Some(1 as i128));
189+
assert_eq!(r.overflowing_pow(2), (4 as i128, false));
190+
assert_eq!(r.overflowing_pow(3), (-8 as i128, false));
191+
assert_eq!(r.overflowing_pow(0), (1 as i128, false));
192+
assert_eq!(r.saturating_pow(2), 4 as i128);
193+
assert_eq!(r.saturating_pow(3), -8 as i128);
194+
assert_eq!(r.saturating_pow(0), 1 as i128);*/
195+
196+
use std::i128::{MAX, MIN};
197+
assert_eq!((0 as i128).saturating_neg(), 0);
198+
assert_eq!((123 as i128).saturating_neg(), -123);
199+
assert_eq!((-123 as i128).saturating_neg(), 123);
200+
assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
201+
assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
202+
assert_eq!(MAX.saturating_neg(), MIN + 1);
203+
assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
204+
assert_eq!((MIN + 1).saturating_neg(), MAX);
205+
assert_eq!(MIN.saturating_neg(), MAX);
222206
}

src/intrinsic.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,14 +1006,6 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
10061006
let then_block = func.new_block("then");
10071007
let after_block = func.new_block("after");
10081008

1009-
let width =
1010-
// TODO: support 128-bit integers.
1011-
if width == 128 {
1012-
64
1013-
}
1014-
else {
1015-
width
1016-
};
10171009
let unsigned_type = self.context.new_int_type(width as i32 / 8, false);
10181010
let shifted = self.context.new_cast(None, lhs, unsigned_type) >> self.context.new_rvalue_from_int(unsigned_type, width as i32 - 1);
10191011
let uint_max = self.context.new_unary_op(None, UnaryOp::BitwiseNegate, unsigned_type,

0 commit comments

Comments
 (0)