[PATCH] Don't fold 1.0/0.0 at compile-time (take 2)

Roger Sayle roger@eyesopen.com
Mon Jul 14 03:49:00 GMT 2003


The attached patch is my second attempt to prevent constant folding
divisions by zero at compile-time.  As with my first attempt, disabling
compile time evaluation of division by zero is easy, the difficult
bit is forcing these trapping evaluations to be performed when
initializing static and/or global variables in C.

My solution here is to introduce a new function fold_initializer
that performs constant folding like fold, but without having to
preserve run-time exceptions and traps that fold must honor.  It
does this by temporarily clearing the signaling_nans, trapping_math
and trapv flags before invoking fold and restoring their values
afterwards.  Finally, a "one-line" fix in c-typeck's build_binary_op
calls fold_initializer instead of fold, if we're currently parsing
an initializer, which is a simple check whether the "initializer_stack"
variable (which fortunately is local to c-typeck.c) is non-NULL.

Unfortunately, initializer_stack is declared after build_binary_op
in c-typeck.c, and so isn't in scope.  My solution was simply to
move the function "build_binary_op" to the bottom of the file.
Alas, moving these 732 lines throws diff into chaos, turning
a two line diff into a nearly 400K patch.  You'll have to take my
word that the only change after moving build_binary_op was to
change

	folded = fold (result);

into

	folded = initializer_stack ? fold_initializer (result)
				   : fold (result);


One nice aspect of this patch is that, unlike the first, it didn't
require any changes to the testsuite.  The "double dnan = 1.0/0.0 -
1.0/0.0;" idioms in the gcc.c-torture/execute/ieee/ work fine.

Richard, could you check whether this version still triggers the
libm-test.c failure you were seeing in glibc?  That might be an
unrelated latent bug, that I'm happy to track down if I can find
out more about it.

The attached patch has been tested on i686-pc-linux-gnu with a
complete "make bootstrap", all languages except treelang, and
regression tested with a top-level "make -k check" with no new
failures.

[My apologies this is my first gzipped attachment to gcc-patches]

Ok for mainline?


2003-07-13  Roger Sayle  <roger@eyesopen.com>

	* fold-const.c (const_binop): Avoid performing the FP operation at
	compile-time, if either operand is NaN and we honor signaling NaNs,
	or if we're dividing by zero and either flag_trapping_math is set
	or the desired mode doesn't support infinities.
	(fold_initializer): New function to fold an expression ignoring any
	potential run-time exceptions or traps.
	* tree.h (fold_initializer): Prototype here.
	* c-typeck.c (build_binary_op): Move to the end of the file so
	that intializer_stack is in scope.  If constructing an initializer,
	i.e. when initializer_stack is not NULL, use fold_initializer to
	fold expressions.
	* simplify-rtx.c (simplify_binary_operation): Likewise, avoid
	performing FP operations at compile-time, if they would raise an
	exception at run-time.

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patchp2.txt.gz
Type: application/octet-stream
Size: 75699 bytes
Desc: 
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20030714/f59e2c2c/attachment.obj>


More information about the Gcc-patches mailing list