arm.c (arm_canonicalize_comparison): Add case to canonicalize left operand from ZERO_...
authorChung-Lin Tang <cltang@codesourcery.com>
Wed, 20 Jul 2011 06:21:36 +0000 (06:21 +0000)
committerChung-Lin Tang <cltang@gcc.gnu.org>
Wed, 20 Jul 2011 06:21:36 +0000 (06:21 +0000)
2011-07-20  Chung-Lin Tang  <cltang@codesourcery.com>

* config/arm/arm.c (arm_canonicalize_comparison): Add case to
canonicalize left operand from ZERO_EXTEND to AND.

testsuite/
* gcc.target/arm/combine-movs.c: New.
* gcc.target/arm/unsigned-extend-2.c: New.

From-SVN: r176495

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/combine-movs.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/unsigned-extend-2.c [new file with mode: 0644]

index 26eb56f7f9653b24040b37da35a81c077faf5960..605729cc946ed96482d6c4e356c329d8aa41f433 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-20  Chung-Lin Tang  <cltang@codesourcery.com>
+
+       * config/arm/arm.c (arm_canonicalize_comparison): Add case to
+       canonicalize left operand from ZERO_EXTEND to AND.
+
 2011-07-20  Anatoly Sokolov  <aesok@post.ru>
 
        * target.def (class_max_nregs): New hook.
index 3e7f0381353f99ea5afea44985f56570f2e33f07..6e2b799fe57aeefba33d7e87289540c4e8282d0c 100644 (file)
@@ -3172,6 +3172,19 @@ arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
       return code;
     }
 
+  /* If *op0 is (zero_extend:SI (subreg:QI (reg:SI) 0)) and comparing
+     with const0_rtx, change it to (and:SI (reg:SI) (const_int 255)),
+     to facilitate possible combining with a cmp into 'ands'.  */
+  if (mode == SImode
+      && GET_CODE (*op0) == ZERO_EXTEND
+      && GET_CODE (XEXP (*op0, 0)) == SUBREG
+      && GET_MODE (XEXP (*op0, 0)) == QImode
+      && GET_MODE (SUBREG_REG (XEXP (*op0, 0))) == SImode
+      && subreg_lowpart_p (XEXP (*op0, 0))
+      && *op1 == const0_rtx)
+    *op0 = gen_rtx_AND (SImode, SUBREG_REG (XEXP (*op0, 0)),
+                       GEN_INT (255));
+
   /* Comparisons smaller than DImode.  Only adjust comparisons against
      an out-of-range constant.  */
   if (GET_CODE (*op1) != CONST_INT
index ea0fc853f18bc9f59fe650bd718621000d269cce..9138237f036dab1a05d11661eff85071b27e9e96 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-20  Chung-Lin Tang  <cltang@codesourcery.com>
+
+       * gcc.target/arm/combine-movs.c: New.
+       * gcc.target/arm/unsigned-extend-2.c: New.
+
 2011-07-19  Jason Merrill  <jason@redhat.com>
 
        PR c++/49785
diff --git a/gcc/testsuite/gcc.target/arm/combine-movs.c b/gcc/testsuite/gcc.target/arm/combine-movs.c
new file mode 100644 (file)
index 0000000..4209a33
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { arm_thumb1 } } */
+/* { dg-options "-O" }  */
+
+void foo (unsigned long r[], unsigned int d)
+{
+  int i, n = d / 32;
+  for (i = 0; i < n; ++i)
+    r[i] = 0;
+}
+
+/* { dg-final { scan-assembler "movs\tr\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/arm/unsigned-extend-2.c b/gcc/testsuite/gcc.target/arm/unsigned-extend-2.c
new file mode 100644 (file)
index 0000000..b610b73
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O" } */
+
+unsigned short foo (unsigned short x)
+{
+  unsigned char i = 0;
+  for (i = 0; i < 8; i++)
+    {
+      x >>= 1;
+      x &= 0x7fff;
+    }
+  return x;
+}
+
+/* { dg-final { scan-assembler "ands" } } */
+/* { dg-final { scan-assembler-not "uxtb" } } */
+/* { dg-final { scan-assembler-not "cmp" } } */