#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
I would expect
assertto be optimized out, because the only possible values forresare eitheraorb, 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