diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 64285702a357c4ad972e0caaea94ed924fc2ec15..7f039b16c289d067870b7e84c2d4be91f829f8dd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 88c43e3c3a9cc59992d4125556a00711d38ae91f..9d2c6dd1273b1ef8e6ceb691702e68910127fb58 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7a7f3be27ccef0d5ffba0fe5b3e1fdaa76028f57..313af808f8436de0b807b6bbcf13965fd514281c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000000000000000000000000000000000000..6f6dc4e85de03c7e418173f359d89c0a34f7dafa --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr46631.c @@ -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; +}