cgccclangassumption

How to tell the compiler a function argument will never be zero?


Imagine I have a dummy C function like this:

void Dummy(uint64* dest, const size_t count)
{
  for (size_t ii = 0; ii < count; ii += 8) {
    *dest++ = (uint64)dest;
  }
}

If you look at what the compiler creates, the first instruction will check that the value of count is not zero.

Dummy(unsigned long*, unsigned long):
        cbz     x1, .LBB0_7
        ...
.LBB0_7:
        ret

Is there an attribute I can place on count to indicate that this value is guaranteed to never be zero and this unnecessary comparison can be omitted? Is there another coding-style that I could deploy?

Changing the for loop to a while loop and other forms doesn't seem to matter. Compilers are clever!

And, yes, I do care about this single tiny little instruction.


Solution

  • GCC has attribute assume for that:

    void Dummy(uint64_t* dest, const size_t count)
    {
        __attribute__((assume(count != 0)));
        for (size_t ii = 0; ii < count; ii += 8) 
        {
            *dest++ = (uint64_t)dest;
        }
    }
    

    And the check disappears.