diff mbox

[1/4] match.pd: Add x + (x & 1) -> (x + 1) & ~1 pattern

Message ID 1421837394-7619-2-git-send-email-rv@rasmusvillemoes.dk
State New
Headers show

Commit Message

Rasmus Villemoes Jan. 21, 2015, 10:49 a.m. UTC
gcc.dg/20150120-1.c: New test

Rounding an integer to the next even integer is sometimes written x +=
x & 1. The equivalent x = (x+1)&~1 usually uses one less register, and
in practical cases only the new value of x will be used (making it
unlikely that the subexpression x&1 has any uses).

Signed-off-by: Rasmus Villemoes <rv@rasmusvillemoes.dk>
---
 gcc/match.pd                      |  6 +++++
 gcc/testsuite/gcc.dg/20150120-1.c | 51 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/20150120-1.c

Comments

Richard Biener April 30, 2015, 9:23 a.m. UTC | #1
On Wed, Jan 21, 2015 at 11:49 AM, Rasmus Villemoes
<rv@rasmusvillemoes.dk> wrote:
> gcc.dg/20150120-1.c: New test
>
> Rounding an integer to the next even integer is sometimes written x +=
> x & 1. The equivalent x = (x+1)&~1 usually uses one less register, and
> in practical cases only the new value of x will be used (making it
> unlikely that the subexpression x&1 has any uses).

Now that we are in stage1 again

You are missig a ChangeLog entry and fail to state how you tested the patch.

Otherwise the patch looks ok.

Thanks,
Richard.

> Signed-off-by: Rasmus Villemoes <rv@rasmusvillemoes.dk>
> ---
>  gcc/match.pd                      |  6 +++++
>  gcc/testsuite/gcc.dg/20150120-1.c | 51 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 57 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/20150120-1.c
>
> diff --git gcc/match.pd gcc/match.pd
> index 81c4ee6..ecefcfb 100644
> --- gcc/match.pd
> +++ gcc/match.pd
> @@ -255,6 +255,12 @@ along with GCC; see the file COPYING3.  If not see
>    (bitop @0 @0)
>    (non_lvalue @0)))
>
> +/* x + (x & 1) -> (x + 1) & ~1 */
> +(simplify
> + (plus:c @0 (bit_and@2 @0 integer_onep@1))
> + (if (TREE_CODE (@2) != SSA_NAME || has_single_use (@2))
> +  (bit_and (plus @0 @1) (bit_not @1))))
> +
>  (simplify
>   (abs (negate @0))
>   (abs @0))
> diff --git gcc/testsuite/gcc.dg/20150120-1.c gcc/testsuite/gcc.dg/20150120-1.c
> new file mode 100644
> index 0000000..18906c4
> --- /dev/null
> +++ gcc/testsuite/gcc.dg/20150120-1.c
> @@ -0,0 +1,51 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-original" } */
> +
> +/* x + (x & 1) -> (x + 1) & ~1 */
> +int
> +fn1 (int x)
> +{
> +       return x + (x & 1);
> +}
> +int
> +fn2 (int x)
> +{
> +       return (x & 1) + x;
> +}
> +int
> +fn3 (int x)
> +{
> +       return x + (1 & x);
> +}
> +int
> +fn4 (int x)
> +{
> +       return (1 & x) + x;
> +}
> +unsigned int
> +fn5 (unsigned int x)
> +{
> +       return x + (x & 1);
> +}
> +unsigned int
> +fn6 (unsigned int x)
> +{
> +       return (x & 1) + x;
> +}
> +unsigned int
> +fn7 (unsigned int x)
> +{
> +       return x + (x % 2);
> +}
> +unsigned int
> +fn8 (unsigned int x)
> +{
> +       return (x % 2) + x;
> +}
> +unsigned int
> +fn9 (unsigned int x)
> +{
> +       return (1LL & x) + x;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "x \\+ 1" 9 "original" } } */
> --
> 2.1.3
>
Jeff Law May 1, 2015, 6:26 p.m. UTC | #2
On 01/21/2015 03:49 AM, Rasmus Villemoes wrote:
> gcc.dg/20150120-1.c: New test
>
> Rounding an integer to the next even integer is sometimes written x +=
> x & 1. The equivalent x = (x+1)&~1 usually uses one less register, and
> in practical cases only the new value of x will be used (making it
> unlikely that the subexpression x&1 has any uses).

I bootstrapped and regression tested this on x86_64-linux-gnu, created 
the appropriate ChangeLogs and installed the patch on the trunk.

Jeff
diff mbox

Patch

diff --git gcc/match.pd gcc/match.pd
index 81c4ee6..ecefcfb 100644
--- gcc/match.pd
+++ gcc/match.pd
@@ -255,6 +255,12 @@  along with GCC; see the file COPYING3.  If not see
   (bitop @0 @0)
   (non_lvalue @0)))
 
+/* x + (x & 1) -> (x + 1) & ~1 */
+(simplify
+ (plus:c @0 (bit_and@2 @0 integer_onep@1))
+ (if (TREE_CODE (@2) != SSA_NAME || has_single_use (@2))
+  (bit_and (plus @0 @1) (bit_not @1))))
+
 (simplify
  (abs (negate @0))
  (abs @0))
diff --git gcc/testsuite/gcc.dg/20150120-1.c gcc/testsuite/gcc.dg/20150120-1.c
new file mode 100644
index 0000000..18906c4
--- /dev/null
+++ gcc/testsuite/gcc.dg/20150120-1.c
@@ -0,0 +1,51 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+
+/* x + (x & 1) -> (x + 1) & ~1 */
+int
+fn1 (int x)
+{
+	return x + (x & 1);
+}
+int
+fn2 (int x)
+{
+	return (x & 1) + x;
+}
+int
+fn3 (int x)
+{
+	return x + (1 & x);
+}
+int
+fn4 (int x)
+{
+	return (1 & x) + x;
+}
+unsigned int
+fn5 (unsigned int x)
+{
+	return x + (x & 1);
+}
+unsigned int
+fn6 (unsigned int x)
+{
+	return (x & 1) + x;
+}
+unsigned int
+fn7 (unsigned int x)
+{
+	return x + (x % 2);
+}
+unsigned int
+fn8 (unsigned int x)
+{
+	return (x % 2) + x;
+}
+unsigned int
+fn9 (unsigned int x)
+{
+	return (1LL & x) + x;
+}
+
+/* { dg-final { scan-tree-dump-times "x \\+ 1" 9 "original" } } */