Need help with boolean type condition

As usual, one should write whatever's most readable in the vast majority of cases.

That said, && and || are short-circuiting, as you know. That's essential in lots of cases -- x != 0 && foo(z / x) and similar -- and a good default for anything non-trivial on the RHS.

But it's control flow, so for a sufficiently trivial RHS it can make it easier on the optimizer to not write short-circuiting, so it knows that it's allowed to just run it and that's ok, without needing to prove it safe to run. (After all, if it's not short-circuiting it's going to run always.)

It looks like LLVM's gotten smarter so my go-to example is now fully optimized either way (https://rust.godbolt.org/z/TnvKdqPfb, at least in x64).

But if you use a compiler from three years ago, then https://rust.godbolt.org/z/EfdzWjn16

pub struct Demo(u16, u16, u16, u16);

#[no_mangle]
pub fn obvious_eq(x: &Demo, y: &Demo) -> bool {
    x.0 == y.0 && x.1 == y.1 && x.2 == y.2 && x.3 == y.3
}

#[no_mangle]
pub fn no_short_circuit_eq(x: &Demo, y: &Demo) -> bool {
    (x.0 == y.0) & (x.1 == y.1) & (x.2 == y.2) & (x.3 == y.3)
}

compiled to

obvious_eq:
        movzx   ecx, word ptr [rdi]
        xor     eax, eax
        cmp     cx, word ptr [rsi]
        jne     .LBB0_5
        movzx   ecx, word ptr [rsi + 2]
        cmp     word ptr [rdi + 2], cx
        jne     .LBB0_5
        movzx   eax, word ptr [rdi + 4]
        cmp     ax, word ptr [rsi + 4]
        jne     .LBB0_3
        movzx   eax, word ptr [rdi + 6]
        cmp     ax, word ptr [rsi + 6]
        sete    al
.LBB0_5:
        ret
.LBB0_3:
        xor     eax, eax
        ret

no_short_circuit_eq:
        mov     rax, qword ptr [rdi]
        cmp     rax, qword ptr [rsi]
        sete    al
        ret

So someone who was micro-optimizing a bit of code like that might have chosen to change the normal && implementation to & in order to get an optimization like that, if it was done at a time when LLVM's optimizer wasn't yet capable of doing it automatically.

4 Likes