https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95801

            Bug ID: 95801
           Summary: Optimiser does not exploit the fact that an integer
                    divisor cannot be zero
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: felix.von.s at posteo dot de
  Target Milestone: ---

int always1(int a, int b) {
    if (a / b)
        return b != 0;
    return 1;
}

The function above should be possible to optimise to a constant 1, as integer
division by zero is undefined. I’m surprised this isn’t caught already; it
seems like very low-hanging fruit.

In case someone wants to claim there is no value to be gained from this, this
is where it came up:

#define SIGNUM(value) ({ \
        __auto_type _value = (value); \
        (__typeof__(_value)) ((_value > 0) - (_value < 0)); \
    })

#define DIV_FLOOR(a, b) ({ \
        __auto_type _a = (a); \
        __auto_type _b = (b); \
        (_a / _b) - ((SIGNUM(_a) != SIGNUM(_b) ? _a % _b : 0) != 0); \
    })

For unsigned types, DIV_FLOOR(a, b) should compile to the same code as
truncating division (a / b), but unless a statement to the effect of (b == 0 ?
__builtin_unreachable() : (void) 0); is inserted before the division, DIV_FLOOR
will generate considerably longer code, at least on x86.

Reply via email to