]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/47477 (Sub-optimal mov at end of method)
authorJeff Law <law@redhat.com>
Fri, 13 Feb 2015 20:17:55 +0000 (13:17 -0700)
committerJeff Law <law@gcc.gnu.org>
Fri, 13 Feb 2015 20:17:55 +0000 (13:17 -0700)
PR rtl-optimization/47477
* match.pd (convert (plus/minus (convert @0) (convert @1): New
simplifier to narrow arithmetic.

PR rtl-optimization/47477
* gcc.dg/tree-ssa/pr47477.c: New test.

From-SVN: r220695

gcc/ChangeLog
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr47477.c [new file with mode: 0644]

index 290d3ac6df00b0033cb80d62867f05b67aa55f67..f36e16c1514ae4a0b562c7a4480ad8576a62433c 100644 (file)
@@ -1,3 +1,9 @@
+2015-02-13  Jeff Law  <law@redhat.com>
+
+       PR rtl-optimization/47477
+       * match.pd (convert (plus/minus (convert @0) (convert @1): New
+       simplifier to narrow arithmetic.
+
 2015-02-13  Jan Hubicka  <hubicka@ucw.cz>
 
        PR ipa/65028
index 81c4ee62fd0eb64e2f3fa7ddf73fd529ecca8204..d438179be4f5cf3dc5f155f9234562022fa90365 100644 (file)
@@ -1018,3 +1018,44 @@ along with GCC; see the file COPYING3.  If not see
    (logs (pows @0 @1))
    (mult @1 (logs @0)))))
 
+/* Narrowing of arithmetic and logical operations. 
+
+   These are conceptually similar to the transformations performed for
+   the C/C++ front-ends by shorten_binary_op and shorten_compare.  Long
+   term we want to move all that code out of the front-ends into here.  */
+
+/* If we have a narrowing conversion of an arithmetic operation where
+   both operands are widening conversions from the same type as the outer
+   narrowing conversion.  Then convert the innermost operands to a suitable
+   unsigned type (to avoid introducing undefined behaviour), perform the
+   operation and convert the result to the desired type.  */
+(for op (plus minus)
+  (simplify
+    (convert (op (convert@2 @0) (convert@3 @1)))
+    (if (INTEGRAL_TYPE_P (type)
+        /* We check for type compatibility between @0 and @1 below,
+           so there's no need to check that @1/@3 are integral types.  */
+        && INTEGRAL_TYPE_P (TREE_TYPE (@0))
+        && INTEGRAL_TYPE_P (TREE_TYPE (@2))
+        /* The precision of the type of each operand must match the
+           precision of the mode of each operand, similarly for the
+           result.  */
+        && (TYPE_PRECISION (TREE_TYPE (@0))
+            == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@0))))
+        && (TYPE_PRECISION (TREE_TYPE (@1))
+            == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (@1))))
+        && TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type))
+        /* The inner conversion must be a widening conversion.  */
+        && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
+        && ((GENERIC 
+             && (TYPE_MAIN_VARIANT (TREE_TYPE (@0))
+                 == TYPE_MAIN_VARIANT (TREE_TYPE (@1)))
+             && (TYPE_MAIN_VARIANT (TREE_TYPE (@0))
+                 == TYPE_MAIN_VARIANT (type)))
+            || (GIMPLE
+                && types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1))
+                && types_compatible_p (TREE_TYPE (@0), type))))
+      (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
+       (convert (op @0 @1)))
+      (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
+       (convert (op (convert:utype @0) (convert:utype @1)))))))
index b2d1c11f5863c13cb051f4e3de7e171bea8a5091..2fe9698f34c51156a2c4021460ff476d30ab488e 100644 (file)
@@ -1,3 +1,8 @@
+2015-02-13  Jeff Law  <law@redhat.com>
+
+       PR rtl-optimization/47477
+       * gcc.dg/tree-ssa/pr47477.c: New test.
+
 2015-02-13  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/60211
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr47477.c b/gcc/testsuite/gcc.dg/tree-ssa/pr47477.c
new file mode 100644 (file)
index 0000000..104cb6f
--- /dev/null
@@ -0,0 +1,22 @@
+/* PR tree-optimization/47477 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -w" } */
+/* { dg-require-effective-target ilp32 } */
+
+typedef int int64_t __attribute__ ((__mode__ (__DI__)));
+typedef int * intptr_t;
+
+typedef struct toto_s *toto_t;
+toto_t add (toto_t a, toto_t b) {
+  int64_t tmp = (int64_t)(intptr_t)a + ((int64_t)(intptr_t)b&~1L);
+  return (toto_t)(intptr_t) tmp;
+}
+
+/* For an ILP32 target there'll be 6 casts when we start, but just 4
+   if the match.pd pattern is successfully matched.  */
+/* { dg-final { scan-tree-dump-times "= \\(int\\)" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "= \\(unsigned int\\)" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "= \\(struct toto_s \\*\\)" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
+