Bug 77756

Summary: gcc -O generates incorrect comparison code
Product: [Retired] Red Hat Linux Reporter: Joe Chung <joechung>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED RAWHIDE QA Contact: Brian Brock <bbrock>
Severity: high Docs Contact:
Priority: medium    
Version: 7.2CC: bill
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2002-11-18 19:57:13 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Joe Chung 2002-11-13 02:29:42 UTC
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 15:20:27 UTC
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 15:59:59 UTC
Thanks for the update, reproduced with gcc-3.2-14 and gcc CVS head too.
Debugging.

Comment 4 Jakub Jelinek 2002-12-04 16:38:15 UTC
Should be fixed in gcc-3.2.1-1.