+2009-08-18 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41094
+ * builtins.c (fold_builtin_pow): Fold pow(pow(x,y),z) to
+ pow(x,y*z) only if x is nonnegative.
+
2009-08-18 Jakub Jelinek <jakub@redhat.com>
* bb-reorder.c (fix_up_fall_thru_edges): Only call invert_jump
}
}
- /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
+ /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative. */
if (fcode == BUILT_IN_POW
|| fcode == BUILT_IN_POWF
|| fcode == BUILT_IN_POWL)
{
tree arg00 = CALL_EXPR_ARG (arg0, 0);
- tree arg01 = CALL_EXPR_ARG (arg0, 1);
- tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
- return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
+ if (tree_expr_nonnegative_p (arg00))
+ {
+ tree arg01 = CALL_EXPR_ARG (arg0, 1);
+ tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
+ return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
+ }
}
}
+2009-08-18 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/41094
+ * gcc.dg/torture/pr41094.c: New testcase.
+ * gcc.dg/torture/builtin-power-1.c: Adjust.
+ * gcc.dg/builtins-10.c: Likewise.
+
2009-08-18 Jakub Jelinek <jakub@redhat.com>
PR target/40971
link_error ();
if (pow(pow(x,4.0),0.25) != x)
- link_error ();
+ /* XFAIL. PR41098. */;
}
void test2(double x, double y, double z)
if (pow(sqrt(x),y) != pow(x,y*0.5))
link_error ();
- if (pow(pow(x,y),z) != pow(x,y*z))
+ if (pow(pow(fabs(x),y),z) != pow(fabs(x),y*z))
link_error ();
}
/* Test pow(pow(x,y),z) -> pow(x,y*z). */
#define POW_POW \
extern void link_failure_pow_pow(void); \
- if (pow(pow(d1, d2), d3) != pow(d1,d2*d3) \
- || powf(powf(f1,f2),f3) != powf(f1,f2*f3) \
- || powl(powl(ld1,ld2),ld3) != powl(ld1,ld2*ld3)) \
+ if (pow(pow(fabs(d1), d2), d3) != pow(fabs(d1),d2*d3) \
+ || powf(powf(fabs(f1),f2),f3) != powf(fabs(f1),f2*f3) \
+ || powl(powl(fabs(ld1),ld2),ld3) != powl(fabs(ld1),ld2*ld3)) \
link_failure_pow_pow()
POW_POW;
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-ffast-math" } */
+
+#include <math.h>
+
+extern void abort (void);
+
+double foo(void)
+{
+ double x = -4.0;
+ return pow (x * x, 0.25);
+}
+
+int main()
+{
+ if (foo() != 2.0)
+ abort ();
+ return 0;
+}