Why doesn't rustc optimize using this pointer UB?

I was messing around with some pointer stuff and found a weird difference in how rustc optimizes pointer operations:

For this code:

pub unsafe fn ptr_check1(p: *const u32) -> bool {
    let _ = core::hint::black_box(unsafe { p.read() });
    (p as usize) % 4 == 0
}

pub unsafe fn ptr_check2(p: *const u32) -> bool {
    let _ = core::hint::black_box(unsafe { p.read() });
    p as usize == 0
}

Compiler Explorer shows that rustc gives this output:

example::ptr_check1::h0178ece7423bdb32:
        mov     eax, dword ptr [rdi]
        mov     dword ptr [rsp - 4], eax
        lea     rax, [rsp - 4]
        test    dil, 3
        sete    al
        ret

example::ptr_check2::h626ab988a586498e:
        mov     eax, dword ptr [rdi]
        mov     dword ptr [rsp - 4], eax
        lea     rax, [rsp - 4]
        xor     eax, eax
        ret

For ptr_check2, it uses the fact that the pointer has been read to assume that it can't have been null, so the method always returns false. This makes sense to me as an optimization that I would want it to do.

On the other hand, ptr_check1 looks to me like it should have a similar level of guarantee, since pointer::read also requires that the pointer it's reading be aligned. However, rustc doesn't optimize this function to always return true.

Am I missing some reason why optimizing ptr_check1 to always return true wouldn't be a valid transformation? Or is this just an optimization that could be done but rustc misses?

1 Like

For the first version llvm doesn't manage to infer nocapture readonly for the function argument, while it does for the second.
I assume that's because it thinks the % 4 leaks address bits from the pointer. If it could propagate the align 4 from the load and then derive that the modulo doesn't actually leak information then yeah, it should work. I guess it just doesn't do that analysis at the moment.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.