RFA: Fix pow (0, -INT)

Daniel Jacobowitz drow@false.org
Thu Oct 2 13:07:00 GMT 2008


The patch below fixes two errors from glibc's test-double test:

testing double (without inline functions)
Failure: pow (0, -11) == inf plus division by zero exception:
Exception "Divide by zero" not set
Failure: pow (0, -2) == inf plus division by zero exception: Exception
"Divide by zero" not set

Test suite completed:
  2985 test cases plus 2609 tests for exception flags executed.
  2 errors occurred.

GCC is eliding any call to pow (0, -INTEGER).  If IEEE exceptions or
errno are in use, we should not do this for negative powers.  Tested
on x86_64 with no change in the test results; tested with test-double
on x86_64 and ARM with the expected improvements.  OK to commit?

The code I'm patching has been there since 2003 and the glibc
test-double test fails without the patch (confirmed on x86_64 and ARM,
various glibc versions and gcc versions).  And people have updated the
glibc ulps list in that interval, so clearly not everyone has been
ignoring this test.  So why has no one else noticed this problem?
I feel like I'm missing something...

Also, does anyone else think that we should not fold calls to pow at
-O0?

-- 
Daniel Jacobowitz
CodeSourcery

2008-10-02  Daniel Jacobowitz  <dan@codesourcery.com>

	* builtins.c (fold_builtin_pow): Check for 0 ** NEGATIVE.

Index: builtins.c
===================================================================
--- builtins.c	(revision 140816)
+++ builtins.c	(working copy)
@@ -8459,9 +8459,13 @@ fold_builtin_pow (tree fndecl, tree arg0
       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
       if (real_identical (&c, &cint))
 	{
-	  /* Attempt to evaluate pow at compile-time.  */
+	  /* Attempt to evaluate pow at compile-time, unless this should
+	     raise an exception.  */
 	  if (TREE_CODE (arg0) == REAL_CST
-	      && !TREE_OVERFLOW (arg0))
+	      && !TREE_OVERFLOW (arg0)
+	      && (n > 0
+		  || (!flag_trapping_math && !flag_errno_math)
+		  || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
 	    {
 	      REAL_VALUE_TYPE x;
 	      bool inexact;



More information about the Gcc-patches mailing list