]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/19775 (sqrt(pow(x,y)) != pow(x,y*0.5) (with -ffast-math))
authorRichard Guenther <rguenth@gcc.gnu.org>
Mon, 7 Feb 2005 13:24:38 +0000 (13:24 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 7 Feb 2005 13:24:38 +0000 (13:24 +0000)
2005-02-07  Richard Guenther  <rguenth@gcc.gnu.org>

PR middle-end/19775
* builtins.c (fold_builtin_sqrt): Transform
sqrt(pow(x,y)) to pow(fabs(x),y*0.5), not
pow(x,y*0.5).

* gcc.dg/torture/builtin-power-1.c: Disable test for
invalid transformation.
* gcc.dg/builtins-10.c: Likewise.  Disable one test we
no longer optimize.
* gcc.dg/builtins-47.c: New testcase.

From-SVN: r94701

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtins-10.c
gcc/testsuite/gcc.dg/builtins-47.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/builtin-power-1.c

index 1418ba196e42e233c9e7ec8fbbd72024519b11c7..dec53756db9ffff6d58eda8e2184d54ca4f06c97 100644 (file)
@@ -1,3 +1,10 @@
+2005-02-07  Richard Guenther  <rguenth@gcc.gnu.org>
+
+       PR middle-end/19775
+       * builtins.c (fold_builtin_sqrt): Transform
+       sqrt(pow(x,y)) to pow(fabs(x),y*0.5), not
+       pow(x,y*0.5).
+
 2005-02-07  Leehod Baruch  <leehod@il.ibm.com>
            Dorit Naishlos  <dorit@il.ibm.com>
 
index dada41ef84897b2a5e6576841d993ba7db61d8ce..09c5b6b795e7e8e1083b0a6adcd88c4640741bca 100644 (file)
@@ -6186,7 +6186,7 @@ fold_builtin_sqrt (tree arglist, tree type)
        }
     }
 
-  /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
+  /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
   if (flag_unsafe_math_optimizations
       && (fcode == BUILT_IN_POW
          || fcode == BUILT_IN_POWF
@@ -6195,8 +6195,11 @@ fold_builtin_sqrt (tree arglist, tree type)
       tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
       tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
       tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
-      tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
-                                build_real (type, dconsthalf)));
+      tree narg1;
+      if (!tree_expr_nonnegative_p (arg0))
+       arg0 = build1 (ABS_EXPR, type, arg0);
+      narg1 = fold (build2 (MULT_EXPR, type, arg1,
+                           build_real (type, dconsthalf)));
       arglist = tree_cons (NULL_TREE, arg0,
                           build_tree_list (NULL_TREE, narg1));
       return build_function_call_expr (powfn, arglist);
index f4fac6f1a6eda2ccbd6fd1cbbe04d913d6c8bb7e..4e93d07fdd0d376d7528d24c962966d2aeed6534 100644 (file)
@@ -1,3 +1,12 @@
+2005-02-07  Richard Guenther  <rguenth@gcc.gnu.org>
+
+       PR middle-end/19775
+       * gcc.dg/torture/builtin-power-1.c: Disable test for
+       invalid transformation.
+       * gcc.dg/builtins-10.c: Likewise.  Disable one test we
+       no longer optimize.
+       * gcc.dg/builtins-47.c: New testcase.
+
 2005-02-07  Leehod Baruch  <leehod@il.ibm.com> 
            Dorit Naishlos  <dorit@il.ibm.com>
        
index 9e5a4583fc3ade7e789b8b2d873edda033e71f24..53158a0f8523071a21ebcfab8182d3d517abe4c5 100644 (file)
@@ -14,11 +14,12 @@ extern double exp(double);
 extern double log(double);
 extern double sqrt(double);
 extern double pow(double,double);
+extern double fabs(double);
 
 void test(double x)
 {
-  if (sqrt(pow(x,4.0)) != x*x)
-    link_error ();
+  /*if (sqrt(pow(x,4.0)) != x*x)
+    link_error (); */
 
   if (pow(sqrt(x),4.0) != x*x)
     link_error ();
@@ -29,7 +30,7 @@ void test(double x)
 
 void test2(double x, double y, double z)
 {
-  if (sqrt(pow(x,y)) != pow(x,y*0.5))
+  if (sqrt(pow(x,y)) != pow(fabs(x),y*0.5))
     link_error ();
 
   if (log(pow(x,y)) != y*log(x))
diff --git a/gcc/testsuite/gcc.dg/builtins-47.c b/gcc/testsuite/gcc.dg/builtins-47.c
new file mode 100644 (file)
index 0000000..19ae973
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-options "-ffast-math -fdump-tree-gimple" } */
+
+extern double sqrt (double);
+extern double pow (double, double);
+extern void abort (void);
+
+int main ()
+{
+  double x = -1.0;
+  if (sqrt (pow (x, 2)) != 1.0)
+    abort();
+  if (sqrt (x*x) != 1.0)
+    abort();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "sqrt" 0 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "pow" 0 "gimple" } } */
+
index 45566118a818de6beba8f983358e78127fa6df64..7cdc00c23fb0eb40db2dad89f7073037822013cc 100644 (file)
@@ -63,7 +63,7 @@ void test(double d1, double d2, double d3,
      || FN##l(powl(ld1,ld2)) != powl(ld1,ld2/N)) \
     link_failure_##FN##_pow()
 
-  ROOT_POW(sqrt,2);
+  /*ROOT_POW(sqrt,2); Invalid. */
   /*ROOT_POW(cbrt,3); Intentionally not implemented.  */
 
   /* Test pow(pow(x,y),z) -> pow(x,y*z).  */