Skip to content

Checked range of variables is forgotten after a slightly non-trivial condition #151078

@kornelski

Description

@kornelski
#include <assert.h>

int choose(int v[], int len, int a, int b, int cond) {
    if (a >= len || b >= len) {
        return 0;
    }

    int res = v[a] > cond || v[b] > cond ? a : b;
    assert(res < len);
    return res;
}

I would expect assert to be optimized out, because the only possible values for res are either a or b, and both had their range checked at the beginning of the function.

What is really weird about this is that changing || to | makes this optimization work (int res = v[a] > cond | v[b] > cond ? a : b). I originally thought it was related to reading two different memory locations, but in this minimized example it seems to be caused by having an extra branch in the short-circuiting condition.

https://gcc.godbolt.org/z/jx8zje6v8

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions