From: Marc Glisse Date: Fri, 3 Nov 2017 16:23:57 +0000 (+0100) Subject: Generalize -(-X) a little X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=63626547937ea54b251ad9480b306d9f8e793a0c;p=gcc.git Generalize -(-X) a little 2017-11-03 Marc Glisse gcc/ * match.pd (-(-A)): Rewrite. gcc/testsuite/ * gcc.dg/tree-ssa/negneg-1.c: New file. * gcc.dg/tree-ssa/negneg-2.c: Likewise. * gcc.dg/tree-ssa/negneg-3.c: Likewise. * gcc.dg/tree-ssa/negneg-4.c: Likewise. From-SVN: r254382 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8c1576aae3..83dbaaaa8bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2017-11-03 Marc Glisse + + * match.pd (-(-A)): Rewrite. + 2017-11-03 Segher Boessenkool * config/rs6000/rs60000-protos.h (rs6000_emit_sISEL): Delete. diff --git a/gcc/match.pd b/gcc/match.pd index f2c43737b80..f22286e0c2e 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1503,12 +1503,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) t1 = TYPE_OVERFLOW_WRAPS (type) ? type : TREE_TYPE (@1); } (convert (plus (convert:t1 @0) (convert:t1 @1)))))) - /* -(-A) -> A */ + /* -(T)(-A) -> (T)A + Sign-extension is ok except for INT_MIN, which thankfully cannot + happen without overflow. */ (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 (convert negate_expr_p@1)) + (if (SCALAR_FLOAT_TYPE_P (type) + && ((DECIMAL_FLOAT_TYPE_P (type) + == DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@1)) + && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (@1))) + || !HONOR_SIGN_DEPENDENT_ROUNDING (type))) + (convert (negate @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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ef5b1071384..3b7276e9cdb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2017-11-03 Marc Glisse + + * gcc.dg/tree-ssa/negneg-1.c: New file. + * gcc.dg/tree-ssa/negneg-2.c: Likewise. + * gcc.dg/tree-ssa/negneg-3.c: Likewise. + * gcc.dg/tree-ssa/negneg-4.c: Likewise. + 2017-11-03 Jan Hubicka * gcc.dg/no-strict-overflow-3.c (foo): Update magic diff --git a/gcc/testsuite/gcc.dg/tree-ssa/negneg-1.c b/gcc/testsuite/gcc.dg/tree-ssa/negneg-1.c new file mode 100644 index 00000000000..9c6c36998e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/negneg-1.c @@ -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) + +typedef int vec __attribute__((vector_size(4*sizeof(int)))); +typedef unsigned uvec __attribute__((vector_size(4*sizeof(int)))); +void h(vec*p,uvec*q){ + vec a = -*p; + *q = -(uvec)a; +} + +/* { dg-final { scan-tree-dump-not "negate_expr" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/negneg-2.c b/gcc/testsuite/gcc.dg/tree-ssa/negneg-2.c new file mode 100644 index 00000000000..bd6198e633b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/negneg-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fno-rounding-math -fdump-tree-optimized-raw" } */ + +#define DEF(num, T1, T2) T2 f##num(T1 x) { \ + T1 y = -x; \ + T2 z = (T2)y; \ + return -z; \ +} +DEF(0, double, float) + +/* { dg-final { scan-tree-dump-not "negate_expr" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/negneg-3.c b/gcc/testsuite/gcc.dg/tree-ssa/negneg-3.c new file mode 100644 index 00000000000..9deb9f6f320 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/negneg-3.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -frounding-math -fdump-tree-optimized-raw" } */ + +// This assumes that long long is strictly larger than int + +#define DEF(num, T1, T2) T2 f##num(T1 x) { \ + T1 y = -x; \ + T2 z = (T2)y; \ + return -z; \ +} +DEF(0, unsigned, long long) +DEF(1, unsigned, unsigned long long) +DEF(2, double, float) + +/* { dg-final { scan-tree-dump-times "negate_expr" 6 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/negneg-4.c b/gcc/testsuite/gcc.dg/tree-ssa/negneg-4.c new file mode 100644 index 00000000000..e1131d06f64 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/negneg-4.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-O -fwrapv" } */ + +#define DEF(num, T1, T2) T2 f##num(T1 x) { \ + T1 y = -x; \ + T2 z = (T2)y; \ + return -z; \ +} +DEF(0, int, long long) + +int main(){ + volatile int a = -1 - __INT_MAX__; + volatile long long b = f0 (a); + volatile long long c = a; + volatile long long d = -c; + if (b != d) + __builtin_abort(); +}