From b0e43da8fb5cef8036f19e4ca75d6862d64cdd22 Mon Sep 17 00:00:00 2001 From: Chung-Lin Tang Date: Wed, 20 Jul 2011 06:21:36 +0000 Subject: [PATCH] arm.c (arm_canonicalize_comparison): Add case to canonicalize left operand from ZERO_EXTEND to AND. 2011-07-20 Chung-Lin Tang * 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 | 5 +++++ gcc/config/arm/arm.c | 13 +++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/arm/combine-movs.c | 12 ++++++++++++ .../gcc.target/arm/unsigned-extend-2.c | 18 ++++++++++++++++++ 5 files changed, 53 insertions(+) create mode 100644 gcc/testsuite/gcc.target/arm/combine-movs.c create mode 100644 gcc/testsuite/gcc.target/arm/unsigned-extend-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 26eb56f7f96..605729cc946 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2011-07-20 Chung-Lin Tang + + * config/arm/arm.c (arm_canonicalize_comparison): Add case to + canonicalize left operand from ZERO_EXTEND to AND. + 2011-07-20 Anatoly Sokolov * target.def (class_max_nregs): New hook. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 3e7f0381353..6e2b799fe57 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ea0fc853f18..9138237f036 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-07-20 Chung-Lin Tang + + * gcc.target/arm/combine-movs.c: New. + * gcc.target/arm/unsigned-extend-2.c: New. + 2011-07-19 Jason Merrill 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 index 00000000000..4209a331427 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/combine-movs.c @@ -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 index 00000000000..b610b73617d --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/unsigned-extend-2.c @@ -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" } } */ -- 2.30.2