Bug 576 - gcc performs invalid optimization with float operations when different rounding mode.
Summary: gcc performs invalid optimization with float operations when different roundi...
Status: SUSPENDED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 2.95.2
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks: 16989
  Show dependency treegraph
 
Reported: 2000-09-28 06:56 UTC by goualard
Modified: 2023-11-21 18:36 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-12-28 06:35:21


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description goualard 2000-09-28 06:56:01 UTC
gcc performs optimizations that are invalid for some
floating-point computations when the rounding direction
is set towards +infinity or -infinity. As shown in
the code example, trivial identities do no longer hold.

Release:
gcc version 2.95.2 19991024 (release)

Environment:
Red Hat Linux release 6.2 (Zoot)
Kernel 2.2.14-12 on an i686

Environment variables have their default values under this
O.S.

How-To-Repeat:
#include <stdio.h>

const double MAXDOUBLE=1.797693134862315708e+308;
static unsigned int _up = 0x1a3f;

inline  void 
roundUpward()
{
  asm  ("fldcw _up");
}

int
main()
{
  roundUpward();
  
  double a=MAXDOUBLE;
  double b=(-a)*a;
 
  printf("%g %g\n",(-a)*a, b);
  
  printf("%g %g\n", -((-a)*a), -b);
}
Comment 1 Joseph S. Myers 2000-09-28 16:33:45 UTC
From: "Joseph S. Myers" <jsm28@cam.ac.uk>
To: goualard@cwi.nl
Cc: gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org
Subject: Re: optimization/576: gcc performs invalid optimization with float
 operations.
Date: Thu, 28 Sep 2000 16:33:45 +0100 (BST)

 On 28 Sep 2000 goualard@cwi.nl wrote:
 
 > gcc performs optimizations that are invalid for some
 > floating-point computations when the rounding direction
 > is set towards +infinity or -infinity. As shown in
 > the code example, trivial identities do no longer hold.
 
 For this to work properly, according to the C99 standard you must use
 "#pragma STDC FENV_ACCESS ON".  GCC does not yet support the C99 standard
 pragmas, but hopefully it will do so in future.  (Note also that using the
 <fenv.h> function fesetround() is more portable than using an asm.)  This
 should for now be considered a missing feature in GCC (documented as
 missing at http://gcc.gnu.org/c99status.html).  See
 http://gcc.gnu.org/contribute.html and
 http://gcc.gnu.org/contributewhy.html if you want to contribute an
 implementation; I don't know if anyone is working on this.
 
 -- 
 Joseph S. Myers
 jsm28@cam.ac.uk
 
Comment 2 Richard Henderson 2001-01-16 07:17:24 UTC
State-Changed-From-To: open->suspended
State-Changed-Why: As Joseph mentioned, unimplemented C99 features are required.
Comment 3 Richard Henderson 2001-01-16 15:17:24 UTC
From: rth@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org, goualard@cwi.nl, nobody@gcc.gnu.org
Cc:  
Subject: Re: optimization/576
Date: 16 Jan 2001 15:17:24 -0000

 Synopsis: gcc performs invalid optimization with float operations.
 
 State-Changed-From-To: open->suspended
 State-Changed-By: rth
 State-Changed-When: Tue Jan 16 07:17:24 2001
 State-Changed-Why:
     As Joseph mentioned, unimplemented C99 features are required.
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=576&database=gcc
Comment 4 GCC Commits 2005-01-21 17:54:36 UTC
Subject: Bug 576

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	sayle@gcc.gnu.org	2005-01-21 17:54:27

Modified files:
	gcc            : ChangeLog real.c real.h fold-const.c 
	                 simplify-rtx.c 

Log message:
	PR rtl-optimization/576
	* real.c (real_arithmetic): Change return type from void to bool
	to return an indication that the result may be inexact.
	* real.h (real_arithmeric): Update prototype.
	* fold-const.c (const_binop):  Don't constant fold floating
	point expressions when the user specifies -frounding-math and
	the result may depend upon the run-time rounding mode.
	(fold_convert_const_real_from_real): Clean-up.
	(fold_initializer): Ignore flag_rounding_math for initializers.
	* simplify-rtx.c (simplify_binary_operation): Likewise, don't
	constant fold FP operations with flag_rounding_math if the
	result may depend upon the run-time rounding mode.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.7220&r2=2.7221
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/real.c.diff?cvsroot=gcc&r1=1.149&r2=1.150
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/real.h.diff?cvsroot=gcc&r1=1.79&r2=1.80
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fold-const.c.diff?cvsroot=gcc&r1=1.495&r2=1.496
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/simplify-rtx.c.diff?cvsroot=gcc&r1=1.222&r2=1.223

Comment 5 Vincent Lefèvre 2023-11-21 18:03:51 UTC
The -frounding-math option should solve the issue on this particular example. But on my machine, ld gives an "undefined reference to `_up'" error.

For a more general bug, see PR34678.
Comment 6 Andrew Pinski 2023-11-21 18:09:27 UTC
(In reply to Vincent Lefèvre from comment #5)
> The -frounding-math option should solve the issue on this particular
> example. But on my machine, ld gives an "undefined reference to `_up'" error.

That is because the code is GNU C90 and not C++ .
Comment 7 Vincent Lefèvre 2023-11-21 18:36:38 UTC
(In reply to Andrew Pinski from comment #6)
> That is because the code is GNU C90 and not C++ .

I've used gcc, not g++. But this fails even with -std=gnu90.