Bug 77756 - gcc -O generates incorrect comparison code
gcc -O generates incorrect comparison code
Status: CLOSED RAWHIDE
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
7.2
i386 Linux
medium Severity high
: ---
: ---
Assigned To: Jakub Jelinek
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2002-11-12 21:29 EST by Joe Chung
Modified: 2007-04-18 12:48 EDT (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2002-11-18 14:57:13 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Joe Chung 2002-11-12 21:29:42 EST
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.
Comment 1 Bill Rugolsky, Jr. 2002-11-18 10:20:27 EST
This also occurs with gcc-3.2-10.  In both cases, correct code is generated for
optimization levels other than 1. Yikes.
Comment 2 Jakub Jelinek 2002-11-18 10:59:59 EST
Thanks for the update, reproduced with gcc-3.2-14 and gcc CVS head too.
Debugging.
Comment 4 Jakub Jelinek 2002-12-04 11:38:15 EST
Should be fixed in gcc-3.2.1-1.

Note You need to log in before you can comment on or make changes to this bug.