re PR c/24581 (Complex arithmetic on special cases is incorrect.)
PR c/24581 * c-typeck.c (build_binary_op): Handle arithmetic between one real and one complex operand specially. * tree-complex.c (some_nonzerop): Do not identify a real value as zero if flag_signed_zeros. testsuite: * gcc.dg/torture/complex-sign.h: New header. * gcc.dg/torture/complex-sign-add.c, gcc.dg/torture/complex-sign-mixed-add.c, gcc.dg/torture/complex-sign-mixed-div.c, gcc.dg/torture/complex-sign-mixed-mul.c, gcc.dg/torture/complex-sign-mixed-sub.c, gcc.dg/torture/complex-sign-mul.c, gcc.dg/torture/complex-sign-sub.c: New tests. From-SVN: r147281
This commit is contained in:
parent
cb8e4445ef
commit
2ca862e9dd
@ -1,3 +1,11 @@
|
||||
2009-05-08 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/24581
|
||||
* c-typeck.c (build_binary_op): Handle arithmetic between one real
|
||||
and one complex operand specially.
|
||||
* tree-complex.c (some_nonzerop): Do not identify a real value as
|
||||
zero if flag_signed_zeros.
|
||||
|
||||
2009-05-08 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
PR rtl-optimization/33928
|
||||
|
@ -9246,7 +9246,9 @@ build_binary_op (location_t location, enum tree_code code,
|
||||
(code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
|
||||
|| code1 == FIXED_POINT_TYPE || code1 == VECTOR_TYPE))
|
||||
{
|
||||
int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
|
||||
bool first_complex = (code0 == COMPLEX_TYPE);
|
||||
bool second_complex = (code1 == COMPLEX_TYPE);
|
||||
int none_complex = (!first_complex && !second_complex);
|
||||
|
||||
if (shorten || common || short_compare)
|
||||
{
|
||||
@ -9255,6 +9257,89 @@ build_binary_op (location_t location, enum tree_code code,
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (first_complex != second_complex
|
||||
&& (code == PLUS_EXPR
|
||||
|| code == MINUS_EXPR
|
||||
|| code == MULT_EXPR
|
||||
|| (code == TRUNC_DIV_EXPR && first_complex))
|
||||
&& TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
|
||||
&& flag_signed_zeros)
|
||||
{
|
||||
/* An operation on mixed real/complex operands must be
|
||||
handled specially, but the language-independent code can
|
||||
more easily optimize the plain complex arithmetic if
|
||||
-fno-signed-zeros. */
|
||||
tree real_type = TREE_TYPE (result_type);
|
||||
tree real, imag;
|
||||
if (type0 != orig_type0 || type1 != orig_type1)
|
||||
{
|
||||
gcc_assert (may_need_excess_precision && common);
|
||||
real_result_type = c_common_type (orig_type0, orig_type1);
|
||||
}
|
||||
if (first_complex)
|
||||
{
|
||||
if (TREE_TYPE (op0) != result_type)
|
||||
op0 = convert_and_check (result_type, op0);
|
||||
if (TREE_TYPE (op1) != real_type)
|
||||
op1 = convert_and_check (real_type, op1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TREE_TYPE (op0) != real_type)
|
||||
op0 = convert_and_check (real_type, op0);
|
||||
if (TREE_TYPE (op1) != result_type)
|
||||
op1 = convert_and_check (result_type, op1);
|
||||
}
|
||||
if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
|
||||
return error_mark_node;
|
||||
if (first_complex)
|
||||
{
|
||||
op0 = c_save_expr (op0);
|
||||
real = build_unary_op (EXPR_LOCATION (orig_op0), REALPART_EXPR,
|
||||
op0, 1);
|
||||
imag = build_unary_op (EXPR_LOCATION (orig_op0), IMAGPART_EXPR,
|
||||
op0, 1);
|
||||
switch (code)
|
||||
{
|
||||
case MULT_EXPR:
|
||||
case TRUNC_DIV_EXPR:
|
||||
imag = build2 (resultcode, real_type, imag, op1);
|
||||
/* Fall through. */
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
real = build2 (resultcode, real_type, real, op1);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
op1 = c_save_expr (op1);
|
||||
real = build_unary_op (EXPR_LOCATION (orig_op1), REALPART_EXPR,
|
||||
op1, 1);
|
||||
imag = build_unary_op (EXPR_LOCATION (orig_op1), IMAGPART_EXPR,
|
||||
op1, 1);
|
||||
switch (code)
|
||||
{
|
||||
case MULT_EXPR:
|
||||
imag = build2 (resultcode, real_type, op0, imag);
|
||||
/* Fall through. */
|
||||
case PLUS_EXPR:
|
||||
real = build2 (resultcode, real_type, op0, real);
|
||||
break;
|
||||
case MINUS_EXPR:
|
||||
real = build2 (resultcode, real_type, op0, real);
|
||||
imag = build1 (NEGATE_EXPR, real_type, imag);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable();
|
||||
}
|
||||
}
|
||||
ret = build2 (COMPLEX_EXPR, result_type, real, imag);
|
||||
goto return_build_binary_op;
|
||||
}
|
||||
|
||||
/* For certain operations (which identify themselves by shorten != 0)
|
||||
if both args were extended from the same smaller type,
|
||||
do the arithmetic in that type and then extend.
|
||||
|
@ -1,3 +1,15 @@
|
||||
2009-05-08 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/24581
|
||||
* gcc.dg/torture/complex-sign.h: New header.
|
||||
* gcc.dg/torture/complex-sign-add.c,
|
||||
gcc.dg/torture/complex-sign-mixed-add.c,
|
||||
gcc.dg/torture/complex-sign-mixed-div.c,
|
||||
gcc.dg/torture/complex-sign-mixed-mul.c,
|
||||
gcc.dg/torture/complex-sign-mixed-sub.c,
|
||||
gcc.dg/torture/complex-sign-mul.c,
|
||||
gcc.dg/torture/complex-sign-sub.c: New tests.
|
||||
|
||||
2009-05-08 Janus Weil <janus@gcc.gnu.org>
|
||||
|
||||
PR fortran/39876
|
||||
|
53
gcc/testsuite/gcc.dg/torture/complex-sign-add.c
Normal file
53
gcc/testsuite/gcc.dg/torture/complex-sign-add.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* Test complex arithmetic with signed zeros. Pure complex
|
||||
addition. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=gnu99" } */
|
||||
|
||||
#include "complex-sign.h"
|
||||
|
||||
#define CHECK_ADD(TYPE, COPY, ZERO, ZEROI) \
|
||||
do { \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, +, +, +, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, +, +, +, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, +, +, -, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, +, +, -, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, +, -, +, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, +, -, +, -, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, +, -, -, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, +, -, -, -, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, -, +, +, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, -, +, +, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, -, +, -, +, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, -, +, -, -, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, -, -, +, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, -, -, +, -, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, -, -, -, +, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, +, -, -, -, -, -, -); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
check_add_float (void)
|
||||
{
|
||||
CHECK_ADD (float, __builtin_copysignf, 0.0f, 0.0if);
|
||||
}
|
||||
|
||||
void
|
||||
check_add_double (void)
|
||||
{
|
||||
CHECK_ADD (double, __builtin_copysign, 0.0, 0.0i);
|
||||
}
|
||||
|
||||
void
|
||||
check_add_long_double (void)
|
||||
{
|
||||
CHECK_ADD (long double, __builtin_copysignl, 0.0l, 0.0il);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
check_add_float ();
|
||||
check_add_double ();
|
||||
check_add_long_double ();
|
||||
exit (0);
|
||||
}
|
53
gcc/testsuite/gcc.dg/torture/complex-sign-mixed-add.c
Normal file
53
gcc/testsuite/gcc.dg/torture/complex-sign-mixed-add.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* Test complex arithmetic with signed zeros. Mixed real/complex
|
||||
addition. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=gnu99" } */
|
||||
|
||||
#include "complex-sign.h"
|
||||
|
||||
#define CHECK_ADD(TYPE, COPY, ZERO, ZEROI) \
|
||||
do { \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, +, +, +, +, +, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, +, +, +, -, +, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, +, +, -, +, +, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, +, +, -, -, +, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, +, -, +, +, +, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, +, -, +, -, +, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, +, -, -, +, -, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, +, -, -, -, -, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, +, +, +, +, ZERO, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, +, +, +, -, ZERO, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, +, +, -, +, ZERO, +, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, +, +, -, -, ZERO, +, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, +, -, +, +, ZERO, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, +, -, +, -, ZERO, -, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, +, -, -, +, ZERO, +, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, +, -, -, -, ZERO, -, -); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
check_add_float (void)
|
||||
{
|
||||
CHECK_ADD (float, __builtin_copysignf, 0.0f, 0.0if);
|
||||
}
|
||||
|
||||
void
|
||||
check_add_double (void)
|
||||
{
|
||||
CHECK_ADD (double, __builtin_copysign, 0.0, 0.0i);
|
||||
}
|
||||
|
||||
void
|
||||
check_add_long_double (void)
|
||||
{
|
||||
CHECK_ADD (long double, __builtin_copysignl, 0.0l, 0.0il);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
check_add_float ();
|
||||
check_add_double ();
|
||||
check_add_long_double ();
|
||||
exit (0);
|
||||
}
|
45
gcc/testsuite/gcc.dg/torture/complex-sign-mixed-div.c
Normal file
45
gcc/testsuite/gcc.dg/torture/complex-sign-mixed-div.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* Test complex arithmetic with signed zeros. Mixed real/complex
|
||||
division. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=gnu99" } */
|
||||
|
||||
#include "complex-sign.h"
|
||||
|
||||
#define CHECK_DIV(TYPE, COPY, ZERO, ZEROI, ONE) \
|
||||
do { \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, /, +, +, +, ONE, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, /, +, +, -, ONE, -, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, /, +, -, +, ONE, +, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, /, +, -, -, ONE, -, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, /, -, +, +, ONE, -, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, /, -, +, -, ONE, +, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, /, -, -, +, ONE, -, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, /, -, -, -, ONE, +, +); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
check_div_float (void)
|
||||
{
|
||||
CHECK_DIV (float, __builtin_copysignf, 0.0f, 0.0if, 1.0f);
|
||||
}
|
||||
|
||||
void
|
||||
check_div_double (void)
|
||||
{
|
||||
CHECK_DIV (double, __builtin_copysign, 0.0, 0.0i, 1.0);
|
||||
}
|
||||
|
||||
void
|
||||
check_div_long_double (void)
|
||||
{
|
||||
CHECK_DIV (long double, __builtin_copysignl, 0.0l, 0.0il, 1.0l);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
check_div_float ();
|
||||
check_div_double ();
|
||||
check_div_long_double ();
|
||||
exit (0);
|
||||
}
|
53
gcc/testsuite/gcc.dg/torture/complex-sign-mixed-mul.c
Normal file
53
gcc/testsuite/gcc.dg/torture/complex-sign-mixed-mul.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* Test complex arithmetic with signed zeros. Mixed real/complex
|
||||
multiplication. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=gnu99" } */
|
||||
|
||||
#include "complex-sign.h"
|
||||
|
||||
#define CHECK_MUL(TYPE, COPY, ZERO, ZEROI) \
|
||||
do { \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, *, +, +, +, +, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, *, +, +, -, +, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, *, +, -, +, -, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, *, +, -, -, -, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, *, -, +, +, -, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, *, -, +, -, -, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, *, -, -, +, +, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, *, -, -, -, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, *, +, +, +, ZERO, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, *, +, +, -, ZERO, -, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, *, +, -, +, ZERO, +, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, *, +, -, -, ZERO, -, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, *, -, +, +, ZERO, -, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, *, -, +, -, ZERO, +, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, *, -, -, +, ZERO, -, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, *, -, -, -, ZERO, +, +); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
check_mul_float (void)
|
||||
{
|
||||
CHECK_MUL (float, __builtin_copysignf, 0.0f, 0.0if);
|
||||
}
|
||||
|
||||
void
|
||||
check_mul_double (void)
|
||||
{
|
||||
CHECK_MUL (double, __builtin_copysign, 0.0, 0.0i);
|
||||
}
|
||||
|
||||
void
|
||||
check_mul_long_double (void)
|
||||
{
|
||||
CHECK_MUL (long double, __builtin_copysignl, 0.0l, 0.0il);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
check_mul_float ();
|
||||
check_mul_double ();
|
||||
check_mul_long_double ();
|
||||
exit (0);
|
||||
}
|
53
gcc/testsuite/gcc.dg/torture/complex-sign-mixed-sub.c
Normal file
53
gcc/testsuite/gcc.dg/torture/complex-sign-mixed-sub.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* Test complex arithmetic with signed zeros. Mixed real/complex
|
||||
subtraction. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=gnu99" } */
|
||||
|
||||
#include "complex-sign.h"
|
||||
|
||||
#define CHECK_SUB(TYPE, COPY, ZERO, ZEROI) \
|
||||
do { \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, -, +, +, +, +, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, -, +, +, -, +, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, -, +, -, +, +, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, -, +, -, -, +, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, -, -, +, +, -, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, -, -, +, -, -, +); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, -, -, -, +, +, -); \
|
||||
CHECK_ARITH_RC (TYPE, COPY, ZERO, ZEROI, -, -, -, -, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, -, +, +, +, ZERO, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, -, +, +, -, ZERO, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, -, +, -, +, ZERO, +, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, -, +, -, -, ZERO, +, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, -, -, +, +, ZERO, -, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, -, -, +, -, ZERO, +, +); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, -, -, -, +, ZERO, -, -); \
|
||||
CHECK_ARITH_CR (TYPE, COPY, ZERO, ZEROI, -, -, -, -, ZERO, +, -); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
check_sub_float (void)
|
||||
{
|
||||
CHECK_SUB (float, __builtin_copysignf, 0.0f, 0.0if);
|
||||
}
|
||||
|
||||
void
|
||||
check_sub_double (void)
|
||||
{
|
||||
CHECK_SUB (double, __builtin_copysign, 0.0, 0.0i);
|
||||
}
|
||||
|
||||
void
|
||||
check_sub_long_double (void)
|
||||
{
|
||||
CHECK_SUB (long double, __builtin_copysignl, 0.0l, 0.0il);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
check_sub_float ();
|
||||
check_sub_double ();
|
||||
check_sub_long_double ();
|
||||
exit (0);
|
||||
}
|
53
gcc/testsuite/gcc.dg/torture/complex-sign-mul.c
Normal file
53
gcc/testsuite/gcc.dg/torture/complex-sign-mul.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* Test complex arithmetic with signed zeros. Pure complex
|
||||
multiplication. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=gnu99" } */
|
||||
|
||||
#include "complex-sign.h"
|
||||
|
||||
#define CHECK_MUL(TYPE, COPY, ZERO, ZEROI) \
|
||||
do { \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, +, +, +, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, +, +, +, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, +, +, -, +, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, +, +, -, -, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, +, -, +, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, +, -, +, -, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, +, -, -, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, +, -, -, -, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, -, +, +, +, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, -, +, +, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, -, +, -, +, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, -, +, -, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, -, -, +, +, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, -, -, +, -, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, -, -, -, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, *, -, -, -, -, +, +); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
check_mul_float (void)
|
||||
{
|
||||
CHECK_MUL (float, __builtin_copysignf, 0.0f, 0.0if);
|
||||
}
|
||||
|
||||
void
|
||||
check_mul_double (void)
|
||||
{
|
||||
CHECK_MUL (double, __builtin_copysign, 0.0, 0.0i);
|
||||
}
|
||||
|
||||
void
|
||||
check_mul_long_double (void)
|
||||
{
|
||||
CHECK_MUL (long double, __builtin_copysignl, 0.0l, 0.0il);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
check_mul_float ();
|
||||
check_mul_double ();
|
||||
check_mul_long_double ();
|
||||
exit (0);
|
||||
}
|
53
gcc/testsuite/gcc.dg/torture/complex-sign-sub.c
Normal file
53
gcc/testsuite/gcc.dg/torture/complex-sign-sub.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* Test complex arithmetic with signed zeros. Pure complex
|
||||
subtraction. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=gnu99" } */
|
||||
|
||||
#include "complex-sign.h"
|
||||
|
||||
#define CHECK_SUB(TYPE, COPY, ZERO, ZEROI) \
|
||||
do { \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, +, +, +, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, +, +, +, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, +, +, -, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, +, +, -, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, +, -, +, +, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, +, -, +, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, +, -, -, +, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, +, -, -, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, -, +, +, +, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, -, +, +, -, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, -, +, -, +, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, -, +, -, -, +, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, -, -, +, +, -, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, -, -, +, -, -, +); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, -, -, -, +, +, -); \
|
||||
CHECK_ARITH (TYPE, COPY, ZERO, ZEROI, -, -, -, -, -, +, +); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
check_sub_float (void)
|
||||
{
|
||||
CHECK_SUB (float, __builtin_copysignf, 0.0f, 0.0if);
|
||||
}
|
||||
|
||||
void
|
||||
check_sub_double (void)
|
||||
{
|
||||
CHECK_SUB (double, __builtin_copysign, 0.0, 0.0i);
|
||||
}
|
||||
|
||||
void
|
||||
check_sub_long_double (void)
|
||||
{
|
||||
CHECK_SUB (long double, __builtin_copysignl, 0.0l, 0.0il);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
check_sub_float ();
|
||||
check_sub_double ();
|
||||
check_sub_long_double ();
|
||||
exit (0);
|
||||
}
|
74
gcc/testsuite/gcc.dg/torture/complex-sign.h
Normal file
74
gcc/testsuite/gcc.dg/torture/complex-sign.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* Common header for complex arithmetic sign tests. */
|
||||
|
||||
extern void abort (void);
|
||||
extern void exit (int);
|
||||
|
||||
#define CHECK_RES(VALUE, COPY, SIGN_REAL, SIGN_IMAG) \
|
||||
do { \
|
||||
if ((VALUE) != 0 \
|
||||
|| COPY (1.0, __real__ (VALUE)) != SIGN_REAL 1.0 \
|
||||
|| COPY (1.0, __imag__ (VALUE)) != SIGN_IMAG 1.0) \
|
||||
abort (); \
|
||||
} while (0)
|
||||
|
||||
/* This definition is intended to work with or without imaginary
|
||||
types, as long as mixed real/complex arithmetic is handled
|
||||
correctly. */
|
||||
#define ENCODE(ZERO, ZEROI, SA, SB) \
|
||||
(SA 1 == 1 \
|
||||
? SB 1 == 1 ? ZERO + ZEROI : ZERO - ZEROI \
|
||||
: SB 1 == 1 ? -(ZERO - ZEROI) : -(ZERO + ZEROI))
|
||||
|
||||
#define CHECK_ARITH(TYPE, COPY, ZERO, ZEROI, OP, S1, S2, S3, S4, SR, SI) \
|
||||
do { \
|
||||
_Complex TYPE a1, b1, c1; \
|
||||
volatile _Complex TYPE a2, b2, c2; \
|
||||
a1 = ENCODE(ZERO, ZEROI, S1, S2); \
|
||||
CHECK_RES (a1, COPY, S1, S2); \
|
||||
b1 = ENCODE(ZERO, ZEROI, S3, S4); \
|
||||
CHECK_RES (b1, COPY, S3, S4); \
|
||||
c1 = a1 OP b1; \
|
||||
CHECK_RES (c1, COPY, SR, SI); \
|
||||
a2 = ENCODE(ZERO, ZEROI, S1, S2); \
|
||||
CHECK_RES (a2, COPY, S1, S2); \
|
||||
b2 = ENCODE(ZERO, ZEROI, S3, S4); \
|
||||
CHECK_RES (b2, COPY, S3, S4); \
|
||||
c2 = a2 OP b2; \
|
||||
CHECK_RES (c2, COPY, SR, SI); \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_ARITH_RC(TYPE, COPY, ZERO, ZEROI, OP, S1, S3, S4, SR, SI) \
|
||||
do { \
|
||||
TYPE a1; \
|
||||
_Complex TYPE b1, c1; \
|
||||
volatile TYPE a2; \
|
||||
volatile _Complex TYPE b2, c2; \
|
||||
a1 = S1 ZERO; \
|
||||
b1 = ENCODE(ZERO, ZEROI, S3, S4); \
|
||||
CHECK_RES (b1, COPY, S3, S4); \
|
||||
c1 = a1 OP b1; \
|
||||
CHECK_RES (c1, COPY, SR, SI); \
|
||||
a2 = S1 ZERO; \
|
||||
b2 = ENCODE(ZERO, ZEROI, S3, S4); \
|
||||
CHECK_RES (b2, COPY, S3, S4); \
|
||||
c2 = a2 OP b2; \
|
||||
CHECK_RES (c2, COPY, SR, SI); \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_ARITH_CR(TYPE, COPY, ZERO, ZEROI, OP, S1, S2, S3, V3, SR, SI) \
|
||||
do { \
|
||||
_Complex TYPE a1, c1; \
|
||||
TYPE b1; \
|
||||
volatile _Complex TYPE a2, c2; \
|
||||
volatile TYPE b2; \
|
||||
a1 = ENCODE(ZERO, ZEROI, S1, S2); \
|
||||
CHECK_RES (a1, COPY, S1, S2); \
|
||||
b1 = S3 V3; \
|
||||
c1 = a1 OP b1; \
|
||||
CHECK_RES (c1, COPY, SR, SI); \
|
||||
a2 = ENCODE(ZERO, ZEROI, S1, S2); \
|
||||
CHECK_RES (a2, COPY, S1, S2); \
|
||||
b2 = S3 V3; \
|
||||
c2 = a2 OP b2; \
|
||||
CHECK_RES (c2, COPY, SR, SI); \
|
||||
} while (0)
|
@ -99,7 +99,10 @@ some_nonzerop (tree t)
|
||||
{
|
||||
int zerop = false;
|
||||
|
||||
if (TREE_CODE (t) == REAL_CST)
|
||||
/* Operations with real or imaginary part of a complex number zero
|
||||
cannot be treated the same as operations with a real or imaginary
|
||||
operand if we care about the signs of zeros in the result. */
|
||||
if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
|
||||
zerop = REAL_VALUES_IDENTICAL (TREE_REAL_CST (t), dconst0);
|
||||
else if (TREE_CODE (t) == FIXED_CST)
|
||||
zerop = fixed_zerop (t);
|
||||
|
Loading…
x
Reference in New Issue
Block a user