aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2017-11-03 17:23:57 +0100
committerMarc Glisse <glisse@gcc.gnu.org>2017-11-03 16:23:57 +0000
commit63626547937ea54b251ad9480b306d9f8e793a0c (patch)
tree1692ab4ed30efaec1e493cbcb059766808ce286a
parente641ee437f4134131e1d81a5f0e9415f3737d78b (diff)
downloadgcc-63626547937ea54b251ad9480b306d9f8e793a0c.zip
gcc-63626547937ea54b251ad9480b306d9f8e793a0c.tar.gz
gcc-63626547937ea54b251ad9480b306d9f8e793a0c.tar.bz2
Generalize -(-X) a little
2017-11-03 Marc Glisse <marc.glisse@inria.fr> 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
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/match.pd27
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/negneg-1.c24
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/negneg-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/negneg-3.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/negneg-4.c18
7 files changed, 102 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c8c1576..83dbaaa 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2017-11-03 Marc Glisse <marc.glisse@inria.fr>
+
+ * match.pd (-(-A)): Rewrite.
+
2017-11-03 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/rs60000-protos.h (rs6000_emit_sISEL): Delete.
diff --git a/gcc/match.pd b/gcc/match.pd
index f2c4373..f22286e 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 ef5b107..3b7276e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2017-11-03 Marc Glisse <marc.glisse@inria.fr>
+
+ * 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 <hubicka@ucw.cz>
* 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 0000000..9c6c369
--- /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 0000000..bd6198e
--- /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 0000000..9deb9f6
--- /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 0000000..e1131d0
--- /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();
+}