optimization/9016: Failure to consistently constant fold "constant" C++ objects

martin@xemacs.org martin@xemacs.org
Thu Dec 19 21:36:00 GMT 2002


>Number:         9016
>Category:       optimization
>Synopsis:       Failure to consistently constant fold "constant" C++ objects
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          pessimizes-code
>Submitter-Id:   net
>Arrival-Date:   Thu Dec 19 21:36:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     martin@xemacs.org
>Release:        gcc-3.2.1
>Organization:
>Environment:
Linux x86
>Description:
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.
>How-To-Repeat:
g++ -Wall -O3 -S -fomit-frame-pointer
and look at the resulting .s file
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-bugs mailing list