Is it possible to make MSVC's __assume(0) aka std::unreachable() actually optimize?

168 views Asked by At

Compiling the following code with MSVC

#include <mmintrin.h>
#include <utility>

static auto bit_width(unsigned long x) {
    unsigned long i;
    _BitScanReverse(&i, x);
    ++i;
    if (x == 0) { i = 0; }
    return i;
}

auto foo(unsigned long x) {
    __assume(x > 0);
    return bit_width(x);
}

auto bar(unsigned long x) {
    if (x > 0) {
        return bit_width(x);
    } else {
        std::unreachable();  // implemented as __assume(0) in MSVC
    }
}

generates the following, where foo got optimized and bar didn't (compiling to the same asm as the general-case function that checks for zero).

bit_width(unsigned long)
        bsr     eax, ecx
        xor     edx, edx
        inc     eax
        test    ecx, ecx
        cmovne  edx, eax
        mov     eax, edx
        ret     0

foo(unsigned long) PROC
        bsr     eax, ecx
        inc     eax
        ret     0

bar(unsigned long) PROC
        bsr     eax, ecx
        xor     edx, edx
        inc     eax
        test    ecx, ecx
        cmovne  edx, eax
        mov     eax, edx
        ret     0

MSVC's documentation suggests that __assume(0) as an "unreachable" assertion should help with optimization, but I can't actually make it do this.

Is it possible to use std::unexpected() to optimize code such as the above on MSVC? If so, how?


__assume(x>0) works but isn't portable; Clang has an equivalent __builtin_assume. These are different from GNU C __builtin_expect(x>0, 1) which would only hint the compiler that's usually the case, like [[likely]], not a promise which can affect correctness.

0

There are 0 answers