Bug 9016 - [3.2 regression] Failure to consistently constant fold "constant" C++ objects
[3.2 regression] Failure to consistently constant fold "constant" C++ objects
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: rtl-optimization
3.2.1
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
: missed-optimization
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2002-12-19 21:36 UTC by martin
Modified: 2003-07-25 17:33 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description martin 2002-12-19 21:36:01 UTC
Let's look at some code, a simple wrapper around "double"

static struct X {} x;
static struct Y {} y;

struct Double
{
  double d_;
  Double (double d) : d_ (d) {}
  Double (const X&) : d_ (1.2) {}
  Double (const Y&) : d_ (3.4) {}
  operator double () { return d_; }
  inline friend Double operator/ (Double d1, Double d2)
  { return Double (double (d1) / double (d2)); }
};

double f1 () { return Double (1.2) / Double (3.4); }
double f2 () { return Double (1.2) / Double (y  ); }
double f3 () { return Double (x  ) / Double (3.4); }
double f4 () { return Double (x  ) / Double (y  ); }


It's obvious that all the Double objects above are
compile-time constant objects, and thus can be 
constant-folded.

All the functions f1 f2 f3 f4 return the same constant value.

Of course, g++ can optimize f1 to

	fldl	.LC2
	ret

f2 and f3 are optimized to the only slightly inferior

	subl	$12, %esp
	fldl	.LC5
	addl	$12, %esp
	ret

This shows that g++ "knows" that Double (x) and Double (y)
are both compile-time constants, else they could not be
folded.  Then why can g++ not optimize f4 as well?

	subl	$20, %esp
	movl	$858993459, (%esp)
	movl	$1074475827, 4(%esp)
	fldl	(%esp)
	movl	$858993459, 8(%esp)
	movl	$1072902963, 12(%esp)
	fdivrl	8(%esp)
	addl	$20, %esp
	ret

f4 compiles to a run-time division.
Even at the assembly language level it is relatively
easy to do constant folding of the division here.

What confuses me about this is that g++ can clearly
constant fold Double (x) and Double (y), but only when combined with an "even more constant" Double (1.2),
not with each other.

Release:
gcc-3.2.1

Environment:
Linux x86

How-To-Repeat:
g++ -Wall -O3 -S -fomit-frame-pointer
and look at the resulting .s file
Comment 1 martin 2002-12-19 21:36:01 UTC
Fix:
Fixed in GCC 3.3, GCC 3.4 with:

  http://gcc.gnu.org/ml/gcc-patches/2003-03/msg01345.html
Comment 2 Wolfgang Bangerth 2002-12-21 10:47:43 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed. This is actually a regression: up to gcc3.0.4,
    all four functions were compiled just as f1(), i.e. in
    an optimal way. Starting with 3.2, f2-f4 show the behavior
    Martin demonstrated. Not good :-(
Comment 3 Mark Mitchell 2003-03-16 20:13:37 UTC
From: mmitchel@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: optimization/9016
Date: 16 Mar 2003 20:13:37 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Changes by:	mmitchel@gcc.gnu.org	2003-03-16 20:13:37
 
 Modified files:
 	gcc            : ChangeLog 
 	gcc/config/i386: i386.c 
 
 Log message:
 	PR optimization/9016
 	* config/i386/i386.c (ix86_expand_move): Force more CONST_DOUBLEs
 	into the constant pool.
 
 Patches:
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=1.17103&r2=1.17104
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/i386/i386.c.diff?cvsroot=gcc&r1=1.548&r2=1.549
 

Comment 4 Mark Mitchell 2003-03-16 20:15:04 UTC
From: mmitchel@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: optimization/9016
Date: 16 Mar 2003 20:15:04 -0000

 CVSROOT:	/cvs/gcc
 Module name:	gcc
 Branch: 	gcc-3_3-branch
 Changes by:	mmitchel@gcc.gnu.org	2003-03-16 20:15:04
 
 Modified files:
 	gcc            : ChangeLog 
 	gcc/config/i386: i386.c 
 
 Log message:
 	PR optimization/9016
 	* config/i386/i386.c (ix86_expand_move): Force more CONST_DOUBLEs
 	into the constant pool.
 
 Patches:
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.16114.2.309&r2=1.16114.2.310
 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/i386/i386.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.495.2.18&r2=1.495.2.19
 
Comment 5 Joe Buck 2003-04-25 20:17:14 UTC
State-Changed-From-To: analyzed->closed
State-Changed-Why: Fixed for 3.3.