This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Optimize certain end of loop conditions into min/max operation
- From: Michael Collison <michael dot collison at linaro dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Biener <richard dot guenther at gmail dot com>, marc dot glisse at inria dot fr, Jeff Law <law at redhat dot com>
- Date: Wed, 30 Sep 2015 22:40:20 -0700
- Subject: Re: [PATCH] Optimize certain end of loop conditions into min/max operation
- Authentication-results: sourceware.org; auth=none
- References: <55B5A884 dot 4060105 at linaro dot org> <CAFiYyc1ObfTFaChzLiAezxEzVziVFnDzCTBhvS0v975-xXRosw at mail dot gmail dot com> <55B65A4B dot 3050705 at redhat dot com> <CAFiYyc2J8zo6cVVSj-06+DHoELacugJTeTz1ezqgva2cD44hYA at mail dot gmail dot com> <55BBA052 dot 2060900 at redhat dot com> <55BBBBE6 dot 2070207 at linaro dot org> <55BBBE2E dot 1020408 at redhat dot com> <55FBAFD1 dot 9080300 at linaro dot org> <alpine dot DEB dot 2 dot 20 dot 1509180850360 dot 1946 at laptop-mg dot saclay dot inria dot fr> <alpine dot DEB dot 2 dot 20 dot 1509180931340 dot 1946 at laptop-mg dot saclay dot inria dot fr> <CAFiYyc3Y1LJqQDfK12BuHNLU=QAb1fjZCfNRmG9L_fpvfPtt6g at mail dot gmail dot com> <560B8F51 dot 6030108 at linaro dot org> <CAFiYyc2XfPQk7gRB9QTX2r=R2FaL5O4+YNqQTXEyQnudsBzrbA at mail dot gmail dot com> <560C0D65 dot 2010300 at linaro dot org> <alpine dot DEB dot 2 dot 20 dot 1509302122240 dot 1747 at laptop-mg dot saclay dot inria dot fr>
Richard and Marc,
Latest patch attached which incorporates all comments.
2015-09-30 Michael Collison <michael.collison@linaro.org>
Andrew Pinski <andrew.pinski@caviumnetworks.com>
* match.pd ((x < y) && (x < z) -> x < min (y,z),
(x > y) and (x > z) -> x > max (y,z))
* testsuite/gcc.dg/tree-ssa/minmax-loopend.c: New test.
On 09/30/2015 12:30 PM, Marc Glisse wrote:
On Fri, 18 Sep 2015, Marc Glisse wrote:
+(bit_and:c (op @0 @1) (op @0 @2))
:c seems useless here. On the other hand, it might make sense to
use op:s
since this is mostly useful if it removes the 2 original
comparisons.
As I was saying, :c is useless.
(x:c y z)
is replaced by two copies of the transformation, one with
(x y z)
and the other with
(x z y)
In your transformation, both versions would be equivalent, so the second
one is redundant.
Also, if you have:
a=x<y;
b=x<z;
c=a&b;
reuse(a);
reuse(b);
(i.e. the comparison results are used for more than just this bit_and)
then your transformation may make the code more expensive. To avoid
this, you can write op:s, meaning that the result of op is used only
once.
--
Michael Collison
Linaro Toolchain Working Group
michael.collison@linaro.org
diff --git a/gcc/match.pd b/gcc/match.pd
index bd5c267..ef2e025 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2311,3 +2311,13 @@ along with GCC; see the file COPYING3. If not see
(with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
(convert (bit_and (op (convert:utype @0) (convert:utype @1))
(convert:utype @4))))))))
+
+/* Transform (@0 < @1 and @0 < @2) to use min,
+ (@0 > @1 and @0 > @2) to use max */
+(for op (lt le gt ge)
+ ext (min min max max)
+(simplify
+(bit_and (op:s @0 @1) (op:s @0 @2))
+(if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+(op @0 (ext @1 @2)))))
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-loopend.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-loopend.c
new file mode 100644
index 0000000..dfe6120
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-loopend.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int min_test(long a, long b, long c) {
+ int cmp1 = a < b;
+ int cmp2 = a < c;
+ return cmp1 & cmp2;
+}
+
+int max_test (long a, long b, long c) {
+ int cmp1 = a > b;
+ int cmp2 = a > c;
+ return cmp1 & cmp2;
+}
+
+/* { dg-final { scan-tree-dump "MIN_EXPR" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump "MAX_EXPR" 1 "optimized" } } */
--
1.9.1