This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Generalize -(-X) a little
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 1 Nov 2017 12:47:42 +0100 (CET)
- Subject: Generalize -(-X) a little
- Authentication-results: sourceware.org; auth=none
Hello,
just a little tweak to that transformation. There is some overlap between
the 2 versions, but it seemed easier to handle the NOP case (including the
case without convert and the vector case) separately from the
narrowing / sign-extending scalar integer case.
At some point it would be good to have fold_negate_expr call
generic_simplify so we could remove some transformations from
fold-const.c.
Bootstrap+regtest on powerpc64le-unknown-linux-gnu.
2017-11-01 Marc Glisse <marc.glisse@inria.fr>
gcc/
* match.pd (-(-A)): Rewrite.
gcc/testsuite/
* gcc.dg/negneg.c: New file.
--
Marc Glisse
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 254289)
+++ gcc/match.pd (working copy)
@@ -1498,24 +1498,33 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(with
{
tree t1 = type;
if (INTEGRAL_TYPE_P (type)
&& TYPE_OVERFLOW_WRAPS (type) != TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
t1 = TYPE_OVERFLOW_WRAPS (type) ? type : TREE_TYPE (@1);
}
(convert (plus (convert:t1 @0) (convert:t1 @1))))))
/* -(-A) -> A */
(simplify
- (negate (convert? (negate @1)))
- (if (tree_nop_conversion_p (type, TREE_TYPE (@1))
- && !TYPE_OVERFLOW_SANITIZED (type))
+ (negate (convert (negate @1)))
+ (if (INTEGRAL_TYPE_P (type)
+ && (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@1))
+ || (!TYPE_UNSIGNED (TREE_TYPE (@1))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@1))))
+ && !TYPE_OVERFLOW_SANITIZED (type)
+ && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@1)))
(convert @1)))
+ (simplify
+ (negate (nop_convert (negate @1)))
+ (if (!TYPE_OVERFLOW_SANITIZED (type)
+ && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@1)))
+ (view_convert @1)))
/* We can't reassociate floating-point unless -fassociative-math
or fixed-point plus or minus because of saturation to +-Inf. */
(if ((!FLOAT_TYPE_P (type) || flag_associative_math)
&& !FIXED_POINT_TYPE_P (type))
/* Match patterns that allow contracting a plus-minus pair
irrespective of overflow issues. */
/* (A +- B) - A -> +- B */
/* (A +- B) -+ B -> A */
Index: gcc/testsuite/gcc.dg/negneg.c
===================================================================
--- gcc/testsuite/gcc.dg/negneg.c (nonexistent)
+++ gcc/testsuite/gcc.dg/negneg.c (working copy)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O -frounding-math -fdump-tree-optimized-raw -Wno-psabi" } */
+
+#define DEF(num, T1, T2) T2 f##num(T1 x) { \
+ T1 y = -x; \
+ T2 z = (T2)y; \
+ return -z; \
+}
+DEF(0, int, long long)
+DEF(1, int, unsigned long long)
+DEF(2, long long, int)
+DEF(3, unsigned long long, int)
+DEF(4, long long, unsigned)
+DEF(5, unsigned long long, unsigned)
+//DEF(6, float, double)
+double f6(float x){return -(double)(-x);}
+
+typedef int vec __attribute__((vector_size(4*sizeof(int))));
+typedef unsigned uvec __attribute__((vector_size(4*sizeof(int))));
+void h(vec*p,uvec*q){
+ *q=-(uvec)(-*p);
+}
+
+/* { dg-final { scan-tree-dump-not "negate_expr" "optimized"} } */