The optimizer wasn't perfect in eliminating redundant comparisons in gcc-2 (who's perfect anyway? :-) - but it seems to have become worse with gcc-3.0... Release: gcc-3.0, x86 Environment: linux (but this doesn't matter) How-To-Repeat: take a look at the assembler output of this code: #define compi2(x, y) \ ( \ ((x) < (y))? -1 : \ (((x) > (y))? 1 : 0 ) \ ) int testcomp(void) { int r = 0; for (int x = 0; x < 10; x++) { for (int y = 0; y < 10; y++) { if (1 == compi(x,y)) { r++; } } } return r; } You'll find that the resulting assmbler code of the inner if-clause contains a redundant jump when using gcc-2.x (with -O3 and any other great optimizer switch I tried :-) e.g.: cmpl %edx,%ecx jl .L1137 jle .L1137 incl %ebx .L1137 With gcc-3.0 the same case becomes even worse, now there's an addition redundant comparison: cmpl %edx, %ecx jl .L13 cmpl %edx, %ecx jle .L13 incl %eax .L13 When using an inline function like this inline int compi(const int x, const int y) { if (x < y) return -1; if (x > y) return 1; return 0; } instead of the macro, the code gets even worse. This is somehow a tragedy as it forbids us to just implement one comparison function instead of operator<, operator> etc. for each class...
State-Changed-From-To: open->analyzed State-Changed-Why: In gcc 3.1, the regression from gcc 2 is gone, i.e. we once again get jl .L8 jle .L8 incl %eax .L8: However, I'm not closing the PR since we really should have eliminated one of the branches.
State-Changed-From-To: analyzed->closed State-Changed-Why: This problem has now been fixed on mainline CVS by the combination of the following two patches. We now generate only a single branch in the GNATS testcase. 2002-07-01 Roger Sayle <roger@eyesopen.com> PR opt/4046 * fold-const.c (fold) [COND_EXPR]: Simplify A ? 0 : 1 to !A, A ? B : 0 to A && B and A ? B : 1 into !A || B if both A and B are truth values. 2002-06-15 Roger Sayle <roger@eyesopen.com> * fold-const.c (comparison_to_compcode): New function to convert an comparison TREE CODE into a bit-based representation. (compcode_to_comparison): New function to convert from this bit based representation back to a comparison TREE CODE. (fold_truthop): Simplify (x<y) && (x==y) and related composite comparisons.