This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][GCC] Simplification of 1U << (31 - x)
- From: Sudi Das <Sudi dot Das at arm dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: Marcus Shawcroft <Marcus dot Shawcroft at arm dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>, James Greenhalgh <James dot Greenhalgh at arm dot com>, nd <nd at arm dot com>
- Date: Wed, 12 Apr 2017 09:29:55 +0000
- Subject: [PATCH][GCC] Simplification of 1U << (31 - x)
- Authentication-results: sourceware.org; auth=none
- Authentication-results: arm.com; dkim=none (message not signed) header.d=none;arm.com; dmarc=none action=none header.from=arm.com;
- Nodisclaimer: True
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
Hi all
This is a fix for PR 80131
Currently the code A << (B - C) is not simplified.
However at least a more specific case of 1U << (C -x) where C = precision(type) - 1 can be simplified to (1 << C) >> x.
This is done by adding a new simplification rule in match.pd
So for a test case :
unsigned int f1(unsigned int i)
{
return 1U << (31 - i);
}
We see a gimple dump of
f1 (unsigned int i)
{
unsigned int D.3121;
D.3121 = 2147483648 >> i;
return D.3121;
}
instead of
f1 (unsigned int i)
{
unsigned int D.3121;
_1 = 31 - i;
D.3121 = 1 << _1;
return D.3121;
}
Add a new test case and checked for regressions on bootstrapped aarch64-none-linux-gnu.
Ok for stage 1?
Thanks
Sudi
2017-03-23 Sudakshina Das <sudi.das@arm.com>
PR middle-end/80131
* match.pd: Simplify 1 << (C - x) where C = precision (type) - 1.
2017-03-23 Sudakshina Das <sudi.das@arm.com>
PR middle-end/80131
* testsuite/gcc.dg/pr80131-1.c: New Test.
diff --git a/gcc/match.pd b/gcc/match.pd
index 7b96800..be20fb7 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -508,6 +508,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& tree_nop_conversion_p (type, TREE_TYPE (@1)))
(lshift @0 @2)))
+/* Fold (1 << (C - x)) where C = precision(type) - 1
+ into ((1 << C) >> x). */
+(simplify
+ (lshift integer_onep@0 (minus INTEGER_CST@1 @2))
+ (if (INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) <= HOST_BITS_PER_WIDE_INT
+ && tree_to_uhwi (@1) == (unsigned)(TYPE_PRECISION (type) - 1))
+ (if (TYPE_UNSIGNED(type))
+ (rshift (lshift @0 @1) @2)
+ (with
+ { tree utype = unsigned_type_for (type); }
+ (convert:type (rshift (lshift (convert:utype @0) @1) @2))))))
+
/* Fold (C1/X)*C2 into (C1*C2)/X. */
(simplify
(mult (rdiv@3 REAL_CST@0 @1) REAL_CST@2)
diff --git a/gcc/testsuite/gcc.dg/pr80131-1.c b/gcc/testsuite/gcc.dg/pr80131-1.c
new file mode 100644
index 0000000..2bb6ff3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr80131-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-gimple" } */
+
+/* Checks the simplification of:
+ 1 << (C - x) to (1 << C) >> x, where C = precision (type) - 1
+ f1 is not simplified but f2, f3 and f4 are. */
+
+__INT64_TYPE__ f1 (__INT64_TYPE__ i)
+{
+ return (__INT64_TYPE__)1 << (31 - i);
+}
+
+__INT64_TYPE__ f2 (__INT64_TYPE__ i)
+{
+ return (__INT64_TYPE__)1 << (63 - i);
+}
+
+__UINT64_TYPE__ f3 (__INT64_TYPE__ i)
+{
+ return (__UINT64_TYPE__)1 << (63 - i);
+}
+
+__INT32_TYPE__ f4 (__INT32_TYPE__ i)
+{
+ return (__INT32_TYPE__)1 << (31 - i);
+}
+
+/* { dg-final { scan-tree-dump-times "= 31 -" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "9223372036854775808 >>" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump "2147483648 >>" "gimple" } } */