Checked range of variables is forgotten after a slightly non-trivial condition (original) (raw)
#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.