2010-12-08 Richard Earnshaw <rearnsha@arm.com>
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Dec 2010 16:38:10 +0000 (16:38 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Dec 2010 16:38:10 +0000 (16:38 +0000)
PR target/46631
* arm.c (thumb2_reorg): Also try to reduce <commutative_op> Rd, Rn, Rd
into a 16-bit instruction.

2010-12-08  Wei Guozhi  <carrot@google.com>

PR target/46631
* gcc.target/arm/pr46631: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167595 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr46631.c [new file with mode: 0644]

index 6428570..7f039b1 100644 (file)
@@ -1,3 +1,9 @@
+2010-12-08  Richard Earnshaw  <rearnsha@arm.com>
+
+       PR target/46631
+       * arm.c (thumb2_reorg): Also try to reduce <commutative_op> Rd, Rn, Rd
+       into a 16-bit instruction.
+
 2010-12-08  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR middle-end/42694
index 88c43e3..9d2c6dd 100644 (file)
@@ -12183,6 +12183,7 @@ thumb2_reorg (void)
   FOR_EACH_BB (bb)
     {
       rtx insn;
+
       COPY_REG_SET (&live, DF_LR_OUT (bb));
       df_simulate_initialize_backwards (bb, &live);
       FOR_BB_INSNS_REVERSE (bb, insn)
@@ -12200,21 +12201,43 @@ thumb2_reorg (void)
                  rtx dst = XEXP (pat, 0);
                  rtx src = XEXP (pat, 1);
                  rtx op0 = XEXP (src, 0);
+                 rtx op1 = (GET_RTX_CLASS (GET_CODE (src)) == RTX_COMM_ARITH
+                            ? XEXP (src, 1) : NULL);
+
                  if (rtx_equal_p (dst, op0)
                      || GET_CODE (src) == PLUS || GET_CODE (src) == MINUS)
                    {
                      rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM);
                      rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg);
                      rtvec vec = gen_rtvec (2, pat, clobber);
+
+                     PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
+                     INSN_CODE (insn) = -1;
+                   }
+                 /* We can also handle a commutative operation where the
+                    second operand matches the destination.  */
+                 else if (op1 && rtx_equal_p (dst, op1))
+                   {
+                     rtx ccreg = gen_rtx_REG (CCmode, CC_REGNUM);
+                     rtx clobber = gen_rtx_CLOBBER (VOIDmode, ccreg);
+                     rtvec vec;
+
+                     src = copy_rtx (src);
+                     XEXP (src, 0) = op1;
+                     XEXP (src, 1) = op0;
+                     pat = gen_rtx_SET (VOIDmode, dst, src);
+                     vec = gen_rtvec (2, pat, clobber);
                      PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec);
                      INSN_CODE (insn) = -1;
                    }
                }
            }
+
          if (NONDEBUG_INSN_P (insn))
            df_simulate_one_insn_backwards (bb, insn, &live);
        }
     }
+
   CLEAR_REG_SET (&live);
 }
 
index 7a7f3be..313af80 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-08  Wei Guozhi  <carrot@google.com>
+
+       PR target/46631
+       * gcc.target/arm/pr46631: New testcase.
+
 2010-12-08  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR middle-end/42694
diff --git a/gcc/testsuite/gcc.target/arm/pr46631.c b/gcc/testsuite/gcc.target/arm/pr46631.c
new file mode 100644 (file)
index 0000000..6f6dc4e
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-options "-mthumb -Os" } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-final { scan-assembler "ands" } } */
+
+struct S {
+      int bi_buf;
+      int bi_valid;
+};
+
+int tz (struct S* p, int bits, int value)
+{
+     if (p == 0) return 1;
+      p->bi_valid = bits;
+      p->bi_buf = value & ((1 << bits) - 1);
+      return 0;
+}