re PR rtl-optimization/47477 (Sub-optimal mov at end of method)

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
This commit is contained in:
Jeff Law 2015-02-13 13:17:55 -07:00 committed by Jeff Law
parent d05022766b
commit be1448389a
4 changed files with 74 additions and 0 deletions

View 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

View 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)))))))

View 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

View File

@ -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" } } */