aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1993-12-25 08:52:25 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1993-12-25 08:52:25 -0500
commit95aa28ae18da65f97b45e1fe45dadff7fd352179 (patch)
tree7e3ef663770f85f9df9337a041d729d6b0f44d3d
parent75326e8c5ab20d07c24cee21e00e7124b7bb136a (diff)
downloadgcc-95aa28ae18da65f97b45e1fe45dadff7fd352179.zip
gcc-95aa28ae18da65f97b45e1fe45dadff7fd352179.tar.gz
gcc-95aa28ae18da65f97b45e1fe45dadff7fd352179.tar.bz2
(fold...
(fold, case EQ_EXPR, NE_EXPR): If COMPLEX_TYPE and at least one arg is a COMPLEX_EXPR, split into a logical operation on the real and imaginary parts. From-SVN: r6313
-rw-r--r--gcc/fold-const.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 6821c06..6424737 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -4479,6 +4479,28 @@ fold (expr)
return t1 ? t1 : t;
}
+ /* If this is a comparison of complex values and either or both
+ sizes are a COMPLEX_EXPR, it is best to split up the comparisons
+ and join them with a TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR. This
+ may prevent needless evaluations. */
+ if ((code == EQ_EXPR || code == NE_EXPR)
+ && TREE_CODE (TREE_TYPE (arg0)) == COMPLEX_TYPE
+ && (TREE_CODE (arg0) == COMPLEX_EXPR
+ || TREE_CODE (arg1) == COMPLEX_EXPR))
+ {
+ tree subtype = TREE_TYPE (TREE_TYPE (arg0));
+ tree real0 = fold (build1 (REALPART_EXPR, subtype, arg0));
+ tree imag0 = fold (build1 (IMAGPART_EXPR, subtype, arg0));
+ tree real1 = fold (build1 (REALPART_EXPR, subtype, arg1));
+ tree imag1 = fold (build1 (IMAGPART_EXPR, subtype, arg1));
+
+ return fold (build ((code == EQ_EXPR ? TRUTH_ANDIF_EXPR
+ : TRUTH_ORIF_EXPR),
+ type,
+ fold (build (code, type, real0, real1)),
+ fold (build (code, type, imag0, imag1))));
+ }
+
/* From here on, the only cases we handle are when the result is
known to be a constant.