On 16/09/16 12:12, Kyrill Tkachov wrote:


On 16/09/16 11:45, Bernd Schmidt wrote:
On 09/16/2016 10:40 AM, Kyrill Tkachov wrote:

2016-09-16  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>

    * simplify-rtx.c (simplify_relational_operation_1): Add transformation
    (GTU (PLUS a C) (C - 1)) --> (LTU a -C).

2016-09-16  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>

    * gcc.target/aarch64/gtu_to_ltu_cmp_1.c: New test.

Ok. Don't know if you want to add more variants of the input code to the 
testcase to make sure they're all covered.


Thanks.
I'm having trouble writing testcases for variations of the original testcase as 
GCC really really wants to convert
everything to a comparison against 1 at RTL level, so only the x == -2 || x == 
-1 condition seems to trigger this.
However, testcases of the form:
unsigned int
foo (unsigned int a, unsigned int b)
{
  return (a + 10) > 9;
}

seem to trigger it, so I can add some of this form. However, these will be 
optimised by a match.pd version
of this transformation that I'm working on.

Here's the patch with that test added as well.  The simplify-rtx transformation 
catches it, but if we end up
adding the match.pd form, it will get caught earlier at the GIMPLE level. The 
test will pass regardless of
where this transformation is done.

Ok?

Thanks,
Kyrill

2016-09-16  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>

    * simplify-rtx.c (simplify_relational_operation_1): Add transformation
    (GTU (PLUS a C) (C - 1)) --> (LTU a -C).

2016-09-16  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>

    * gcc.target/aarch64/gtu_to_ltu_cmp_1.c: New test.
    * gcc.target/aarch64/gtu_to_ltu_cmp_2.c: New test.

diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 054c0f9d41664f8a4d11765dfb501647cfbc728f..63e864a237a05d250e3d8a3510775585fe8002db 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -4663,6 +4663,19 @@ simplify_relational_operation_1 (enum rtx_code code, machine_mode mode,
 				      cmp_mode, XEXP (op0, 0), new_cmp);
     }
 
+  /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
+     transformed into (LTU a -C).  */
+  if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
+      && CONST_INT_P (XEXP (op0, 1))
+      && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
+      && XEXP (op0, 1) != const0_rtx)
+    {
+      rtx new_cmp
+	= simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
+      return simplify_gen_relational (LTU, mode, cmp_mode,
+				       XEXP (op0, 0), new_cmp);
+    }
+
   /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a).  */
   if ((code == LTU || code == GEU)
       && GET_CODE (op0) == PLUS
diff --git a/gcc/testsuite/gcc.target/aarch64/gtu_to_ltu_cmp_1.c b/gcc/testsuite/gcc.target/aarch64/gtu_to_ltu_cmp_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..81c536c90afe38932c48ed0af24f55e73eeff80e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gtu_to_ltu_cmp_1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+f1 (int x, int t)
+{
+  if (x == -1 || x == -2)
+    t = 1;
+
+  return t;
+}
+
+/* { dg-final { scan-assembler-times "cmn\\tw\[0-9\]+, #2" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/gtu_to_ltu_cmp_2.c b/gcc/testsuite/gcc.target/aarch64/gtu_to_ltu_cmp_2.c
new file mode 100644
index 0000000000000000000000000000000000000000..e0e999f9df39c29bb79d8a8f7d9a17f213bd115b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gtu_to_ltu_cmp_2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned int
+foo (unsigned int a, unsigned int b)
+{
+  return (a + 10) > 9;
+}
+
+/* { dg-final { scan-assembler-times "cmn\\tw\[0-9\]+" 1 } } */
+/* { dg-final { scan-assembler-not "add\\tw\[0-9\]+" } } */

Reply via email to