text: Red Hat Bugzilla – Bug 77756
  gcc -O generates incorrect comparison code
  Last modified: 2007-04-18 12:48:23 EDT
  From Bugzilla Helper:
  User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.1) Gecko/20021003
  Description of problem:
  /*
  * This program demonstrates an optimizer bug in gcc 2.96/x86 backend.
  * Compile with gcc -O, or any higher optimization.
  *
  * If you look at the generated code (gcc -O -S), the compound
  * if-expression in function foo effectively becomes:
  * if (x == -2 || x < 0) ...
  *
  * Thus, for -1 <= x <= -99 where x != -2, the if-expression
  * would erroneously evaluate to true.
  *
  * The bug does NOT appear if you switch the order of the
  * predicates in the if-expression. For example:
  * if ((((-x)-100) >=0) || (x == -2)) ...
  *
  * The bug also does not appear if you compile without optimization.
  *
  * Summary: To see bad behavior
  * % gcc -O foo.c
  * % ./a.out -3
  *
  * Tested with stock RedHat 7.2 gcc as well as
  * % gcc -v
  * Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
  * gcc version 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.2)
  *
  */
  #include <stdio.h>
  #include <stdlib.h>
  int foo(int x)
  {
  /* Return 1 if x satisfies these conditions */
  if ((x == -2) || (((-x)-100) >=0)) {
  printf("foo: TRUE: (%d == -2) || (%d >= 0)\n", x, ((-x)-100));
  return 1;
  }
  printf("foo: FALSE: (%d == -2) || (%d >= 0)\n", x, ((-x)-100));
  return 0;
  }
  int main(int argc, char *argv[])
  {
  if (argc == 2) {
  int a = atoi(argv[1]);
  printf("main: You entered '%d'\n", a);
  return foo(a);
  }
  printf("Usage: %s integer\n", argv[0]);
  return 1;
  }
  Version-Release number of selected component (if applicable):
  How reproducible:
  Always
  Steps to Reproduce:
  1.Cut-and-paste and compile OPTIMIZED the C-program contained in the
  "Description" field above.
  2.Make sure the backend is x86
  3.run ./a.out -3
  Actual Results: main: You entered '-3'
  foo: TRUE: (-3 == -2) || (-97 >= 0)
  Expected Results: main: You entered '-3'
  foo: FALSE: (-3 == -2) || (-97 >= 0)
  Additional info:
  You can view the erroneous code that is generated with gcc -O -S.
  Remember to compile optimized to show the bug.
  This also occurs with gcc-3.2-10. In both cases, correct code is generated for
  optimization levels other than 1. Yikes.
  Thanks for the update, reproduced with gcc-3.2-14 and gcc CVS head too.
  Debugging.
  Should be fixed in gcc-3.2.1-1.