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:
parent
d05022766b
commit
be1448389a
@ -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
|
||||
|
41
gcc/match.pd
41
gcc/match.pd
@ -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)))))))
|
||||
|
@ -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
|
||||
|
22
gcc/testsuite/gcc.dg/tree-ssa/pr47477.c
Normal file
22
gcc/testsuite/gcc.dg/tree-ssa/pr47477.c
Normal 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" } } */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user