* [PATCH PR82439][simplify-rtx] Simplify (x | y) == x -> (y & ~x) == 0
@ 2018-01-03 13:57 Sudakshina Das
2018-01-03 14:38 ` Segher Boessenkool
2018-01-04 18:30 ` Jeff Law
0 siblings, 2 replies; 5+ messages in thread
From: Sudakshina Das @ 2018-01-03 13:57 UTC (permalink / raw)
To: gcc-patches; +Cc: nd
Hi
This patch add support for the missing transformation of (x | y) == x ->
(y & ~x) == 0.
The transformation for (x & y) == x case already exists in
simplify-rtx.c since 2014 as of r218503 and this patch only adds a
couple of extra patterns for the IOR case.
Citing the example given in PR82439 :
Simple testcase (f1 should generate the same as f2):
int f1(int x, int y) { return (x | y) == x; }
int f2(int x, int y) { return (y & ~x) == 0; }
f1:
orr w1, w0, w1
cmp w1, w0
cset w0, eq
ret
f2:
bics wzr, w1, w0
cset w0, eq
ret
This benefits targets that have the BICS instruction to generate better
code. Wilco helped me in showing that even in targets that do not have
the BICS instruction, this is no worse and gives out 2 instructions.
For example in x86:
0000000000000000 <f1>:
0: 09 fe or %edi,%esi
2: 31 c0 xor %eax,%eax
4: 39 fe cmp %edi,%esi
6: 0f 94 c0 sete %al
9: c3 retq
0000000000000010 <f2>:
10: f7 d7 not %edi
12: 31 c0 xor %eax,%eax
14: 85 f7 test %esi,%edi
16: 0f 94 c0 sete %al
19: c3 retq
Testing done: Checked for regressions on bootstrapped
aarch64-none-linux-gnu and arm-none-linux-gnueabihf and added new test
cases.
Is this ok for trunk?
Sudi
ChangeLog Entries:
*** gcc/ChangeLog ***
2017-01-03 Sudakshina Das <sudi.das@arm.com>
PR target/82439
* simplify-rtx.c (simplify_relational_operation_1): Add
simplifications of (x|y) == x for BICS pattern.
*** gcc/testsuite/ChangeLog ***
2017-01-03 Sudakshina Das <sudi.das@arm.com>
PR target/82439
* gcc.target/aarch64/bics_5.c: New test.
* gcc.target/arm/bics_5.c: Likewise.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH PR82439][simplify-rtx] Simplify (x | y) == x -> (y & ~x) == 0
2018-01-03 13:57 [PATCH PR82439][simplify-rtx] Simplify (x | y) == x -> (y & ~x) == 0 Sudakshina Das
@ 2018-01-03 14:38 ` Segher Boessenkool
2018-01-03 15:00 ` Sudakshina Das
2018-01-04 18:30 ` Jeff Law
1 sibling, 1 reply; 5+ messages in thread
From: Segher Boessenkool @ 2018-01-03 14:38 UTC (permalink / raw)
To: Sudakshina Das; +Cc: gcc-patches, nd
Hi!
On Wed, Jan 03, 2018 at 01:57:38PM +0000, Sudakshina Das wrote:
> This patch add support for the missing transformation of (x | y) == x ->
> (y & ~x) == 0.
> Testing done: Checked for regressions on bootstrapped
> aarch64-none-linux-gnu and arm-none-linux-gnueabihf and added new test
> cases.
> Is this ok for trunk?
You forgot to include the patch :-)
Segher
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH PR82439][simplify-rtx] Simplify (x | y) == x -> (y & ~x) == 0
2018-01-03 14:38 ` Segher Boessenkool
@ 2018-01-03 15:00 ` Sudakshina Das
0 siblings, 0 replies; 5+ messages in thread
From: Sudakshina Das @ 2018-01-03 15:00 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: gcc-patches, nd
[-- Attachment #1: Type: text/plain, Size: 548 bytes --]
Hi
On 03/01/18 14:38, Segher Boessenkool wrote:
> Hi!
>
> On Wed, Jan 03, 2018 at 01:57:38PM +0000, Sudakshina Das wrote:
>> This patch add support for the missing transformation of (x | y) == x ->
>> (y & ~x) == 0.
>
>> Testing done: Checked for regressions on bootstrapped
>> aarch64-none-linux-gnu and arm-none-linux-gnueabihf and added new test
>> cases.
>> Is this ok for trunk?
>
> You forgot to include the patch :-)
(facepalm) This is the second time this has happened to me!
Sorry about this. Attaching now.
Sudi
>
>
> Segher
>
[-- Attachment #2: pr82439.diff --]
[-- Type: text/x-patch, Size: 5407 bytes --]
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index e5cfd3d..17536d0 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -5032,34 +5032,38 @@ simplify_relational_operation_1 (enum rtx_code code, machine_mode mode,
simplify_gen_binary (XOR, cmp_mode,
XEXP (op0, 1), op1));
- /* (eq/ne (and x y) x) simplifies to (eq/ne (and (not y) x) 0), which
- can be implemented with a BICS instruction on some targets, or
- constant-folded if y is a constant. */
+ /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
+ constant folding if x/y is a constant. */
if ((code == EQ || code == NE)
- && op0code == AND
- && rtx_equal_p (XEXP (op0, 0), op1)
+ && (op0code == AND || op0code == IOR)
&& !side_effects_p (op1)
&& op1 != CONST0_RTX (cmp_mode))
{
- rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1), cmp_mode);
- rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
+ /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
+ (eq/ne (and (not y) x) 0). */
+ if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
+ || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
+ {
+ rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
+ cmp_mode);
+ rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
- return simplify_gen_relational (code, mode, cmp_mode, lhs,
- CONST0_RTX (cmp_mode));
- }
+ return simplify_gen_relational (code, mode, cmp_mode, lhs,
+ CONST0_RTX (cmp_mode));
+ }
- /* Likewise for (eq/ne (and x y) y). */
- if ((code == EQ || code == NE)
- && op0code == AND
- && rtx_equal_p (XEXP (op0, 1), op1)
- && !side_effects_p (op1)
- && op1 != CONST0_RTX (cmp_mode))
- {
- rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0), cmp_mode);
- rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
+ /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
+ (eq/ne (and (not x) y) 0). */
+ if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
+ || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
+ {
+ rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
+ cmp_mode);
+ rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
- return simplify_gen_relational (code, mode, cmp_mode, lhs,
- CONST0_RTX (cmp_mode));
+ return simplify_gen_relational (code, mode, cmp_mode, lhs,
+ CONST0_RTX (cmp_mode));
+ }
}
/* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
diff --git a/gcc/testsuite/gcc.target/aarch64/bics_5.c b/gcc/testsuite/gcc.target/aarch64/bics_5.c
new file mode 100644
index 0000000..b9c2c40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bics_5.c
@@ -0,0 +1,86 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+
+extern void abort (void);
+
+int
+bics_si_test1 (int a, int b, int c)
+{
+ if ((a | b) == a)
+ return a;
+ else
+ return c;
+}
+
+int
+bics_si_test2 (int a, int b, int c)
+{
+ if ((a | b) == b)
+ return b;
+ else
+ return c;
+}
+
+typedef long long s64;
+
+s64
+bics_di_test1 (s64 a, s64 b, s64 c)
+{
+ if ((a | b) == a)
+ return a;
+ else
+ return c;
+}
+
+s64
+bics_di_test2 (s64 a, s64 b, s64 c)
+{
+ if ((a | b) == b)
+ return b;
+ else
+ return c;
+}
+
+int
+main ()
+{
+ int x;
+ s64 y;
+
+ x = bics_si_test1 (0xf00d, 0xf11f, 0);
+ if (x != 0)
+ abort ();
+
+ x = bics_si_test1 (0xf11f, 0xf00d, 0);
+ if (x != 0xf11f)
+ abort ();
+
+ x = bics_si_test2 (0xf00d, 0xf11f, 0);
+ if (x != 0xf11f)
+ abort ();
+
+ x = bics_si_test2 (0xf11f, 0xf00d, 0);
+ if (x != 0)
+ abort ();
+
+ y = bics_di_test1 (0x10001000f00dll, 0x12341000f00dll, 0ll);
+ if (y != 0)
+ abort ();
+
+ y = bics_di_test1 (0x12341000f00dll, 0x10001000f00dll, 0ll);
+ if (y != 0x12341000f00dll)
+ abort ();
+
+ y = bics_di_test2 (0x10001000f00dll, 0x12341000f00dll, 0ll);
+ if (y != 0x12341000f00dll)
+ abort ();
+
+ y = bics_di_test2 (0x12341000f00dll, 0x10001000f00dll, 0ll);
+ if (y != 0)
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "bics\twzr, w\[0-9\]+, w\[0-9\]+" 2 } } */
+/* { dg-final { scan-assembler-times "bics\txzr, x\[0-9\]+, x\[0-9\]+" 2 } } */
diff --git a/gcc/testsuite/gcc.target/arm/bics_5.c b/gcc/testsuite/gcc.target/arm/bics_5.c
new file mode 100644
index 0000000..6f84902
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bics_5.c
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps -fno-inline" } */
+/* { dg-require-effective-target arm32 } */
+extern void abort (void);
+int
+bics_si_test1 (int a, int b, int c)
+{
+ if ((a | b) == a)
+ return a;
+ else
+ return c;
+}
+
+int
+bics_si_test2 (int a, int b, int c)
+{
+ if ((a | b) == b)
+ return b;
+ else
+ return c;
+}
+
+int
+main ()
+{
+ int x;
+ x = bics_si_test1 (0xf00d, 0xf11f, 0);
+ if (x != 0)
+ abort ();
+
+ x = bics_si_test1 (0xf11f, 0xf00d, 0);
+ if (x != 0xf11f)
+ abort ();
+
+ x = bics_si_test2 (0xf00d, 0xf11f, 0);
+ if (x != 0xf11f)
+ abort ();
+
+ x = bics_si_test2 (0xf11f, 0xf00d, 0);
+ if (x != 0)
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" 2 } } */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH PR82439][simplify-rtx] Simplify (x | y) == x -> (y & ~x) == 0
2018-01-03 13:57 [PATCH PR82439][simplify-rtx] Simplify (x | y) == x -> (y & ~x) == 0 Sudakshina Das
2018-01-03 14:38 ` Segher Boessenkool
@ 2018-01-04 18:30 ` Jeff Law
2018-01-05 10:47 ` Sudakshina Das
1 sibling, 1 reply; 5+ messages in thread
From: Jeff Law @ 2018-01-04 18:30 UTC (permalink / raw)
To: Sudakshina Das, gcc-patches; +Cc: nd
On 01/03/2018 06:57 AM, Sudakshina Das wrote:
> Hi
>
> This patch add support for the missing transformation of (x | y) == x ->
> (y & ~x) == 0.
> The transformation for (x & y) == x case already exists in
> simplify-rtx.c since 2014 as of r218503 and this patch only adds a
> couple of extra patterns for the IOR case.
>
> Citing the example given in PR82439 :
>
> Simple testcase (f1 should generate the same as f2):
>
> int f1(int x, int y) { return (x | y) == x; }
> int f2(int x, int y) { return (y & ~x) == 0; }
>
> f1:
>     orr   w1, w0, w1
>     cmp   w1, w0
>     cset   w0, eq
> Â Â Â Â ret
> f2:
>     bics   wzr, w1, w0
>     cset   w0, eq
> Â Â Â Â ret
>
> This benefits targets that have the BICS instruction to generate better
> code. Wilco helped me in showing that even in targets that do not have
> the BICS instruction, this is no worse and gives out 2 instructions.
> For example in x86:
>
> 0000000000000000 <f1>:
>   0:   09 fe                   or    %edi,%esi
>   2:   31 c0                   xor   %eax,%eax
>   4:   39 fe                   cmp   %edi,%esi
>   6:   0f 94 c0                sete  %al
> Â Â 9:Â Â Â c3Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â retq
>
> 0000000000000010 <f2>:
>  10:   f7 d7                   not   %edi
>  12:   31 c0                   xor   %eax,%eax
>  14:   85 f7                   test  %esi,%edi
>  16:   0f 94 c0                sete  %al
> Â 19:Â Â Â c3Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â retq
>
> Testing done: Checked for regressions on bootstrapped
> aarch64-none-linux-gnu and arm-none-linux-gnueabihf and added new test
> cases.
> Is this ok for trunk?
>
> Sudi
>
> ChangeLog Entries:
>
> *** gcc/ChangeLog ***
>
> 2017-01-03 Sudakshina Das <sudi.das@arm.com>
>
> Â Â Â Â PR target/82439
> Â Â Â Â * simplify-rtx.c (simplify_relational_operation_1): Add
> Â Â Â Â simplifications of (x|y) == x for BICS pattern.
>
> *** gcc/testsuite/ChangeLog ***
>
> 2017-01-03 Sudakshina Das <sudi.das@arm.com>
>
> Â Â Â Â PR target/82439
> Â Â Â Â * gcc.target/aarch64/bics_5.c: New test.
> Â Â Â Â * gcc.target/arm/bics_5.c: Likewise.
OK.
jeff
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH PR82439][simplify-rtx] Simplify (x | y) == x -> (y & ~x) == 0
2018-01-04 18:30 ` Jeff Law
@ 2018-01-05 10:47 ` Sudakshina Das
0 siblings, 0 replies; 5+ messages in thread
From: Sudakshina Das @ 2018-01-05 10:47 UTC (permalink / raw)
To: Jeff Law, gcc-patches; +Cc: nd
Hi Jeff
On 04/01/18 18:30, Jeff Law wrote:
> On 01/03/2018 06:57 AM, Sudakshina Das wrote:
>> Hi
>>
>> This patch add support for the missing transformation of (x | y) == x ->
>> (y & ~x) == 0.
>> The transformation for (x & y) == x case already exists in
>> simplify-rtx.c since 2014 as of r218503 and this patch only adds a
>> couple of extra patterns for the IOR case.
>>
>> Citing the example given in PR82439 :
>>
>> Simple testcase (f1 should generate the same as f2):
>>
>> int f1(int x, int y) { return (x | y) == x; }
>> int f2(int x, int y) { return (y & ~x) == 0; }
>>
>> f1:
>>     orr   w1, w0, w1
>>     cmp   w1, w0
>>     cset   w0, eq
>> Â Â Â Â ret
>> f2:
>>     bics   wzr, w1, w0
>>     cset   w0, eq
>> Â Â Â Â ret
>>
>> This benefits targets that have the BICS instruction to generate better
>> code. Wilco helped me in showing that even in targets that do not have
>> the BICS instruction, this is no worse and gives out 2 instructions.
>> For example in x86:
>>
>> 0000000000000000 <f1>:
>>   0:   09 fe                   or    %edi,%esi
>>   2:   31 c0                   xor   %eax,%eax
>>   4:   39 fe                   cmp   %edi,%esi
>>   6:   0f 94 c0                sete  %al
>> Â Â 9:Â Â Â c3Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â retq
>>
>> 0000000000000010 <f2>:
>>  10:   f7 d7                   not   %edi
>>  12:   31 c0                   xor   %eax,%eax
>>  14:   85 f7                   test  %esi,%edi
>>  16:   0f 94 c0                sete  %al
>> Â 19:Â Â Â c3Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â retq
>>
>> Testing done: Checked for regressions on bootstrapped
>> aarch64-none-linux-gnu and arm-none-linux-gnueabihf and added new test
>> cases.
>> Is this ok for trunk?
>>
>> Sudi
>>
>> ChangeLog Entries:
>>
>> *** gcc/ChangeLog ***
>>
>> 2017-01-03 Sudakshina Das <sudi.das@arm.com>
>>
>> Â Â Â Â PR target/82439
>> Â Â Â Â * simplify-rtx.c (simplify_relational_operation_1): Add
>> Â Â Â Â simplifications of (x|y) == x for BICS pattern.
>>
>> *** gcc/testsuite/ChangeLog ***
>>
>> 2017-01-03 Sudakshina Das <sudi.das@arm.com>
>>
>> Â Â Â Â PR target/82439
>> Â Â Â Â * gcc.target/aarch64/bics_5.c: New test.
>> Â Â Â Â * gcc.target/arm/bics_5.c: Likewise.
> OK.
Thanks! Committed as r256275.
Sudi
> jeff
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-01-05 10:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-03 13:57 [PATCH PR82439][simplify-rtx] Simplify (x | y) == x -> (y & ~x) == 0 Sudakshina Das
2018-01-03 14:38 ` Segher Boessenkool
2018-01-03 15:00 ` Sudakshina Das
2018-01-04 18:30 ` Jeff Law
2018-01-05 10:47 ` Sudakshina Das
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).