fix const align_offset
implementation
This commit is contained in:
parent
8717455b9d
commit
9e5d497b67
2 changed files with 61 additions and 36 deletions
|
@ -278,9 +278,8 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
|
||||||
return u64::MAX;
|
return u64::MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
let byte_offset = align - addr_mod_align;
|
|
||||||
|
|
||||||
if align % stride == 0 {
|
if align % stride == 0 {
|
||||||
|
let byte_offset = align - addr_mod_align;
|
||||||
if byte_offset % stride == 0 {
|
if byte_offset % stride == 0 {
|
||||||
return byte_offset / stride;
|
return byte_offset / stride;
|
||||||
} else {
|
} else {
|
||||||
|
@ -296,8 +295,11 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
|
||||||
return u64::MAX;
|
return u64::MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Instead of `(addr + offset * stride) % align == 0`, we solve
|
||||||
|
// `((addr + offset * stride) / gcd) % (align / gcd) == 0`.
|
||||||
|
let addr2 = addr / gcd;
|
||||||
let align2 = align / gcd;
|
let align2 = align / gcd;
|
||||||
let stride2 = (stride / gcd) % align2;
|
let stride2 = stride / gcd;
|
||||||
|
|
||||||
let mut stride_inv = 1u64;
|
let mut stride_inv = 1u64;
|
||||||
let mut mod_gate = 2u64;
|
let mut mod_gate = 2u64;
|
||||||
|
@ -308,6 +310,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
|
||||||
(mod_gate, overflow) = mod_gate.overflowing_mul(mod_gate);
|
(mod_gate, overflow) = mod_gate.overflowing_mul(mod_gate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let byte_offset = align2 - addr2 % align2;
|
||||||
byte_offset.wrapping_mul(stride_inv) % align2
|
byte_offset.wrapping_mul(stride_inv) % align2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -510,12 +510,14 @@ fn align_offset_various_strides_const() {
|
||||||
assert!(got == expected);
|
assert!(got == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
// For pointers of stride != 1, we verify the algorithm against the naivest possible
|
// For pointers of stride != 1, we verify the algorithm against the naivest possible
|
||||||
// implementation
|
// implementation
|
||||||
let mut align = 1;
|
let mut align = 1;
|
||||||
let limit = 1024;
|
let limit = 32;
|
||||||
while align < limit {
|
while align < limit {
|
||||||
for ptr in 1usize..4 * align {
|
let mut ptr = 1;
|
||||||
|
while ptr < 4 * align {
|
||||||
unsafe {
|
unsafe {
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
struct A3(u16, u8);
|
struct A3(u16, u8);
|
||||||
|
@ -551,10 +553,12 @@ fn align_offset_various_strides_const() {
|
||||||
test_stride::<u32>(ptr::invalid::<u32>(ptr), ptr, align);
|
test_stride::<u32>(ptr::invalid::<u32>(ptr), ptr, align);
|
||||||
test_stride::<u128>(ptr::invalid::<u128>(ptr), ptr, align);
|
test_stride::<u128>(ptr::invalid::<u128>(ptr), ptr, align);
|
||||||
}
|
}
|
||||||
|
ptr += 1;
|
||||||
}
|
}
|
||||||
align = (align + 1).next_power_of_two();
|
align = (align + 1).next_power_of_two();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(bootstrap))]
|
#[cfg(not(bootstrap))]
|
||||||
|
@ -632,6 +636,24 @@ fn align_offset_issue_103361() {
|
||||||
let _ = (SIZE as *const HugeSize).align_offset(SIZE);
|
let _ = (SIZE as *const HugeSize).align_offset(SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
fn align_offset_issue_103361_const() {
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
const SIZE: usize = 1 << 47;
|
||||||
|
#[cfg(target_pointer_width = "32")]
|
||||||
|
const SIZE: usize = 1 << 30;
|
||||||
|
#[cfg(target_pointer_width = "16")]
|
||||||
|
const SIZE: usize = 1 << 13;
|
||||||
|
struct HugeSize([u8; SIZE - 1]);
|
||||||
|
|
||||||
|
const {
|
||||||
|
assert!(ptr::invalid::<HugeSize>(SIZE - 1).align_offset(SIZE) == SIZE - 1);
|
||||||
|
assert!(ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE) == 0);
|
||||||
|
assert!(ptr::invalid::<HugeSize>(SIZE + 1).align_offset(SIZE) == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_aligned() {
|
fn is_aligned() {
|
||||||
let data = 42;
|
let data = 42;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue