This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFA][PATCH][PR rtl-optimization/47477] Type narrowing in match.pd
- From: Jeff Law <law at redhat dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 13 Feb 2015 14:02:30 -0700
- Subject: Re: [RFA][PATCH][PR rtl-optimization/47477] Type narrowing in match.pd
- Authentication-results: sourceware.org; auth=none
- References: <54DA7029 dot 4070001 at redhat dot com> <CAFiYyc0Rm9Tyfo+Of1WpEqcQ1O-eY0Gmomo1N1rs9O8_pRi+_g at mail dot gmail dot com> <54DB8BD4 dot 8070808 at redhat dot com> <CAFiYyc0_q81UPQqpe-YXhaWWW3L61uP9_e7Zb2pkT4C-ez9Z+A at mail dot gmail dot com> <54DD35FF dot 3060108 at redhat dot com> <CAFiYyc1op0HEyDRc1ZYfLWTq8-EQnZC0nnUR2Y4TzAR-iq+--g at mail dot gmail dot com>
On 02/13/15 02:09, Richard Biener wrote:
Note that this can happen for GIMPLE as well for
struct X { long long a : 33; } x;
long long b;
b = x.a + x.a;
where you'll see 33bit temporaries from the loads of x.a (because C only
promotes bitfields up to size long).
We already have a related pattern that constrains it with similar ideas and
it IMHO does better by not only requiring a power-of-two precision but
a precision matching the machine mode (thus at RTL expansion we don't
need any extra zero/sign extensions). It's
Thanks. Good to know it can happen for gimple as well. I've pulled
the updated tests out to the toplevel.
I'd been trying to avoid TYPE_MODE since it felt like a bit of letting
RTL-isms sneak in here. But that's probably inevitable.
+ && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type)
+ && INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && INTEGRAL_TYPE_P (TREE_TYPE (@2))
Better the INTEGRAL_TYPE_P checks as the very first thing.
Works for me.
Updated, bootstrapped & regression tested on x86_64-unknown-linux-gnu.
Installed on trunk.
Final patch attached.
commit fff56e577c989e828720cba4992b7379057bf86b
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Fri Feb 13 20:17:55 2015 +0000
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220695 138bc75d-0d04-0410-961f-82ee72b054a4
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 290d3ac..f36e16c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/match.pd b/gcc/match.pd
index 81c4ee6..d438179 100644
--- a/gcc/match.pd
+++ b/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)))))))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b2d1c11..2fe9698 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..104cb6f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr47477.c
@@ -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" } } */
+
+