The following:
#include <cstdlib>
int main()
{
const bool a =(rand() % 20) > 5;
const bool b =(rand() & 1) == 1;
int x = rand() % 5, y = rand() % 2, z = rand() % 3, c = rand() % 4, d =
rand() % 5;
if (a & b) d = y * c;
else if (a & !b) c = 2 * d;
else if (!a & b) y = c / z;
else z = c / d * 5;
return x * c * d * y * z;
}
Results in 3 branch instructions at -O0, as one would expect, but 6
branch instructions at -O2 (x86-64, gcc 10), which I wouldn't expect. It
appears to mimick the same code using && instead of & at -O2.
I would expect this to be a pessimisation due to the increased number of
branch instructions, it may've been trying to reduce the overall number
of potential evaluations of conditions, but missed the fact that those
conditions are const variables not (for example) function calls. Clang
keeps this at 3 branches at -O2.
Further into the 'can we do better-than/as-good-as clang' territory, the
same code above but using && instead of &, resolves to 5 branches in
clang (12) and 6 in gcc (10.3), at -O2 (x86-64).
Cheers,
matt Bentley