builtins.c (fold_builtin_cabs): Fold cabs(x+xi) into fabs(x)*sqrt(2).
* builtins.c (fold_builtin_cabs): Fold cabs(x+xi) into fabs(x)*sqrt(2). * fold-const.c (fold_binary): Fix comment typos. Fold complex (x,0)-(0,y) into (x,-y). Likewise (0,y)-(x,0) into (-x,y). testsuite: * gcc.dg/builtins-54.c: Add more cases. From-SVN: r121542
This commit is contained in:
parent
36f7dcae09
commit
d1ad84c204
@ -1,3 +1,10 @@
|
||||
2007-02-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* builtins.c (fold_builtin_cabs): Fold cabs(x+xi) into
|
||||
fabs(x)*sqrt(2).
|
||||
* fold-const.c (fold_binary): Fix comment typos. Fold complex
|
||||
(x,0)-(0,y) into (x,-y). Likewise (0,y)-(x,0) into (-x,y).
|
||||
|
||||
2007-02-02 Mike Stump <mrs@apple.com>
|
||||
|
||||
* config/darwin9.h (DARWIN_LINKER_GENERATES_ISLANDS): Add.
|
||||
|
@ -7143,13 +7143,30 @@ fold_builtin_cabs (tree arglist, tree type, tree fndecl)
|
||||
type, mpfr_hypot)))
|
||||
return res;
|
||||
|
||||
/* If either part is zero, cabs is fabs of the other. */
|
||||
if (TREE_CODE (arg) == COMPLEX_EXPR
|
||||
&& real_zerop (TREE_OPERAND (arg, 0)))
|
||||
return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
|
||||
if (TREE_CODE (arg) == COMPLEX_EXPR
|
||||
&& real_zerop (TREE_OPERAND (arg, 1)))
|
||||
return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
|
||||
if (TREE_CODE (arg) == COMPLEX_EXPR)
|
||||
{
|
||||
tree real = TREE_OPERAND (arg, 0);
|
||||
tree imag = TREE_OPERAND (arg, 1);
|
||||
|
||||
/* If either part is zero, cabs is fabs of the other. */
|
||||
if (real_zerop (real))
|
||||
return fold_build1 (ABS_EXPR, type, imag);
|
||||
if (real_zerop (imag))
|
||||
return fold_build1 (ABS_EXPR, type, real);
|
||||
|
||||
/* cabs(x+xi) -> fabs(x)*sqrt(2). */
|
||||
if (flag_unsafe_math_optimizations
|
||||
&& operand_equal_p (real, imag, OEP_PURE_SAME))
|
||||
{
|
||||
REAL_VALUE_TYPE sqrt2;
|
||||
|
||||
real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
|
||||
STRIP_NOPS (real);
|
||||
return fold_build2 (MULT_EXPR, type,
|
||||
fold_build1 (ABS_EXPR, type, real),
|
||||
build_real (type, sqrt2));
|
||||
}
|
||||
}
|
||||
|
||||
/* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
|
||||
if (TREE_CODE (arg) == NEGATE_EXPR
|
||||
|
@ -8923,7 +8923,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
|
||||
/* Fold __complex__ ( x, 0 ) + __complex__ ( 0, y )
|
||||
to __complex__ ( x, y ). This is not the same for SNaNs or
|
||||
if singed zeros are involved. */
|
||||
if signed zeros are involved. */
|
||||
if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
|
||||
&& !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
|
||||
&& COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0)))
|
||||
@ -9231,6 +9231,43 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
else if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
|
||||
return negate_expr (fold_convert (type, arg1));
|
||||
|
||||
/* Fold __complex__ ( x, 0 ) - __complex__ ( 0, y ) to
|
||||
__complex__ ( x, -y ). This is not the same for SNaNs or if
|
||||
signed zeros are involved. */
|
||||
if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
|
||||
&& !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
|
||||
&& COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0)))
|
||||
{
|
||||
tree rtype = TREE_TYPE (TREE_TYPE (arg0));
|
||||
tree arg0r = fold_unary (REALPART_EXPR, rtype, arg0);
|
||||
tree arg0i = fold_unary (IMAGPART_EXPR, rtype, arg0);
|
||||
bool arg0rz = false, arg0iz = false;
|
||||
if ((arg0r && (arg0rz = real_zerop (arg0r)))
|
||||
|| (arg0i && (arg0iz = real_zerop (arg0i))))
|
||||
{
|
||||
tree arg1r = fold_unary (REALPART_EXPR, rtype, arg1);
|
||||
tree arg1i = fold_unary (IMAGPART_EXPR, rtype, arg1);
|
||||
if (arg0rz && arg1i && real_zerop (arg1i))
|
||||
{
|
||||
tree rp = fold_build1 (NEGATE_EXPR, rtype,
|
||||
arg1r ? arg1r
|
||||
: build1 (REALPART_EXPR, rtype, arg1));
|
||||
tree ip = arg0i ? arg0i
|
||||
: build1 (IMAGPART_EXPR, rtype, arg0);
|
||||
return fold_build2 (COMPLEX_EXPR, type, rp, ip);
|
||||
}
|
||||
else if (arg0iz && arg1r && real_zerop (arg1r))
|
||||
{
|
||||
tree rp = arg0r ? arg0r
|
||||
: build1 (REALPART_EXPR, rtype, arg0);
|
||||
tree ip = fold_build1 (NEGATE_EXPR, rtype,
|
||||
arg1i ? arg1i
|
||||
: build1 (IMAGPART_EXPR, rtype, arg1));
|
||||
return fold_build2 (COMPLEX_EXPR, type, rp, ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fold &x - &x. This can happen from &x.foo - &x.
|
||||
This is unsafe for certain floats even in non-IEEE formats.
|
||||
In IEEE, it is unsafe because it does wrong for NaNs.
|
||||
@ -9410,7 +9447,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
}
|
||||
|
||||
/* Fold z * +-I to __complex__ (-+__imag z, +-__real z).
|
||||
This is not the same for NaNs or if singed zeros are
|
||||
This is not the same for NaNs or if signed zeros are
|
||||
involved. */
|
||||
if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
|
||||
&& !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
|
||||
|
@ -1,3 +1,7 @@
|
||||
2007-02-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* gcc.dg/builtins-54.c: Add more cases.
|
||||
|
||||
2007-02-03 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/30514
|
||||
|
@ -1,44 +1,146 @@
|
||||
/* { dg-do link } */
|
||||
/* { dg-options "-O2 -ffast-math" } */
|
||||
|
||||
double fabs(double);
|
||||
float fabsf(float);
|
||||
long double fabsl(long double);
|
||||
double cabs(__complex__ double);
|
||||
float cabsf(__complex__ float);
|
||||
long double cabsl(__complex__ long double);
|
||||
|
||||
void link_error (void);
|
||||
|
||||
void test(__complex__ double x)
|
||||
void test(__complex__ double x, double a, double b)
|
||||
{
|
||||
if (cabs(x) != cabs(-x))
|
||||
link_error();
|
||||
|
||||
if (cabs(x) != cabs(~x))
|
||||
link_error();
|
||||
|
||||
if (fabs(a) * __builtin_sqrt(2) != cabs (a+a*1i))
|
||||
link_error();
|
||||
|
||||
if (fabs(a) * __builtin_sqrt(2) != cabs (a*1i+a))
|
||||
link_error();
|
||||
|
||||
if (fabs(a) * __builtin_sqrt(2) != cabs (-a+a*-1i))
|
||||
link_error();
|
||||
|
||||
if (fabs(a) * __builtin_sqrt(2) != cabs (-a+-a*1i))
|
||||
link_error();
|
||||
|
||||
if (fabs(a) * __builtin_sqrt(2) != cabs (-a-a*1i))
|
||||
link_error();
|
||||
|
||||
if (fabs(a) * __builtin_sqrt(2) != cabs (a*-1i-a))
|
||||
link_error();
|
||||
|
||||
if (fabs(a) * __builtin_sqrt(2) != cabs (-a*1i-a))
|
||||
link_error();
|
||||
|
||||
if (fabs(a) * __builtin_sqrt(2) != cabs (a*-1i+-a))
|
||||
link_error();
|
||||
|
||||
if (fabs(a) * __builtin_sqrt(2) != cabs (-a*1i+-a))
|
||||
link_error();
|
||||
|
||||
if (fabs(a*b) * __builtin_sqrt(2) != cabs (a*b-(-b*a*1i)))
|
||||
link_error();
|
||||
|
||||
if (fabs(a*b) * __builtin_sqrt(2) != cabs (a*b*1i-a*-b))
|
||||
link_error();
|
||||
}
|
||||
|
||||
void testf(__complex__ float x)
|
||||
void testf(__complex__ float x, float a, float b)
|
||||
{
|
||||
if (cabsf(x) != cabsf(-x))
|
||||
link_error();
|
||||
|
||||
if (cabsf(x) != cabsf(~x))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a) * __builtin_sqrtf(2) != cabsf (a+a*1i))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a) * __builtin_sqrtf(2) != cabsf (a*1i+a))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a) * __builtin_sqrtf(2) != cabsf (-a+a*-1i))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a) * __builtin_sqrtf(2) != cabsf (-a+-a*1i))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a) * __builtin_sqrtf(2) != cabsf (-a-a*1i))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a) * __builtin_sqrtf(2) != cabsf (a*-1i-a))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a) * __builtin_sqrtf(2) != cabsf (-a*1i-a))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a) * __builtin_sqrtf(2) != cabsf (a*-1i+-a))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a) * __builtin_sqrtf(2) != cabsf (-a*1i+-a))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a*b) * __builtin_sqrtf(2) != cabsf (a*b-(-b*a*1i)))
|
||||
link_error();
|
||||
|
||||
if (fabsf(a*b) * __builtin_sqrtf(2) != cabsf (a*b*1i-a*-b))
|
||||
link_error();
|
||||
}
|
||||
|
||||
void testl(__complex__ long double x)
|
||||
void testl(__complex__ long double x, long double a, long double b)
|
||||
{
|
||||
if (cabsl(x) != cabsl(-x))
|
||||
link_error();
|
||||
|
||||
if (cabsl(x) != cabsl(~x))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a) * __builtin_sqrtl(2) != cabsl (a+a*1i))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a) * __builtin_sqrtl(2) != cabsl (a*1i+a))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a) * __builtin_sqrtl(2) != cabsl (-a+a*-1i))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a) * __builtin_sqrtl(2) != cabsl (-a+-a*1i))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a) * __builtin_sqrtl(2) != cabsl (-a-a*1i))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a) * __builtin_sqrtl(2) != cabsl (a*-1i-a))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a) * __builtin_sqrtl(2) != cabsl (-a*1i-a))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a) * __builtin_sqrtl(2) != cabsl (a*-1i+-a))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a) * __builtin_sqrtl(2) != cabsl (-a*1i+-a))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a*b) * __builtin_sqrtl(2) != cabsl (a*b-(-b*a*1i)))
|
||||
link_error();
|
||||
|
||||
if (fabsl(a*b) * __builtin_sqrtl(2) != cabsl (a*b*1i-a*-b))
|
||||
link_error();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test(0.0);
|
||||
testf(0.0);
|
||||
testl(0.0);
|
||||
test(0, 0, 0);
|
||||
testf(0, 0, 0);
|
||||
testl(0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user