RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2015-05-12 Thread Thomas Preud'homme
 From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
 ow...@gcc.gnu.org] On Behalf Of Thomas Preud'homme
 
 Based on my understanding of your answer quoted above, I'll commit
 it as is, despite not having been able to come up with a testcase. I'll
 wait tomorrow to do so though in case you changed your mind about it.

Committed.

Best regards,

Thomas




RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2015-05-04 Thread Thomas Preud'homme
 From: Jeff Law [mailto:l...@redhat.com]
 Sent: Tuesday, April 28, 2015 12:27 AM
 OK.  No need for heroics -- give it a shot, but don't burn an insane
 amount of time on it.  If we can't get to a reasonable testcase, then so
 be it.

Ok, I tried but really didn't managed to create a testcase. I did, however,
understand the condition when this patch is helpful. In the function
reg_nonzero_bits_for_combine () in combine.c there is a test to check if
last_set_nonzero_bits for a given register is still valid.

In the case I'm considering, the test evaluates to false because:

(i) the register rX whose nonzero bits are being evaluated was set in a
previous basic block than the one with the instruction using rX (hence
rsp-last_set_label  label_tick)
(ii) the predecessor of the the basic block for that same insn is not the
previous basic block analyzed by combine_instructions (hence
label_tick_ebb_start == label_tick)
(iii) the register rX is set multiple time (hence
REG_N_SETS (REGNO (x)) != 1)

Yet, the block being processed is dominated by the SET for rX so there
is a REG_EQUAL available to narrow down the set of nonzero bits.

Based on my understanding of your answer quoted above, I'll commit
it as is, despite not having been able to come up with a testcase. I'll
wait tomorrow to do so though in case you changed your mind about it.

Best regards,

Thomas




RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2015-04-30 Thread Thomas Preud'homme
 From: Jeff Law [mailto:l...@redhat.com]
 Sent: Tuesday, April 28, 2015 12:27 AM
 To: Thomas Preud'homme; 'Eric Botcazou'
 Cc: gcc-patches@gcc.gnu.org
 Subject: Re: [PATCH, combine] Try REG_EQUAL for nonzero_bits
 
 On 04/27/2015 04:26 AM, Thomas Preud'homme wrote:
  From: Jeff Law [mailto:l...@redhat.com]
  Sent: Saturday, April 25, 2015 3:00 AM
  Do you have a testcase where this change can result in better
 generated
  code.  If so please add that testcase.  It's OK if it's ARM specific.
 
  Hi Jeff,
 
  Last time I tried I couldn't reduce the code to a small testcase but if I
 remember
  well it was mostly due to the problem of finding a good test for creduce
  (zero extension is not unique enough). I'll try again with a more manual
 approach
  and get back to you.
 OK.  No need for heroics -- give it a shot, but don't burn an insane
 amount of time on it.  If we can't get to a reasonable testcase, then so
 be it.

Sadly I couldn't get a testcase. I get almost same sequence of instruction as 
the program we found the problem into but couldn't get exactly the same. In all 
the cases I constructed the nonzero_bits info we already have were enough for 
combine to do its job. I couldn't find what cause this information to be 
inaccurate. I will try to investigate a bit further on Monday as another pass 
might not be doing its job properly. Or maybe there's something that prevent 
information being propagated.

Best regards,

Thomas





RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2015-04-27 Thread Thomas Preud'homme
 From: Jeff Law [mailto:l...@redhat.com]
 Sent: Saturday, April 25, 2015 3:00 AM
 Do you have a testcase where this change can result in better generated
 code.  If so please add that testcase.  It's OK if it's ARM specific.

Hi Jeff,

Last time I tried I couldn't reduce the code to a small testcase but if I 
remember
well it was mostly due to the problem of finding a good test for creduce
(zero extension is not unique enough). I'll try again with a more manual 
approach
and get back to you.

Best regards,

Thomas





Re: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2015-04-27 Thread Jeff Law

On 04/27/2015 04:26 AM, Thomas Preud'homme wrote:

From: Jeff Law [mailto:l...@redhat.com]
Sent: Saturday, April 25, 2015 3:00 AM
Do you have a testcase where this change can result in better generated
code.  If so please add that testcase.  It's OK if it's ARM specific.


Hi Jeff,

Last time I tried I couldn't reduce the code to a small testcase but if I 
remember
well it was mostly due to the problem of finding a good test for creduce
(zero extension is not unique enough). I'll try again with a more manual 
approach
and get back to you.
OK.  No need for heroics -- give it a shot, but don't burn an insane 
amount of time on it.  If we can't get to a reasonable testcase, then so 
be it.


jeff


Re: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2015-04-24 Thread Jeff Law

On 02/09/2015 07:00 PM, Thomas Preud'homme wrote:

And this is part 2.


From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
ow...@gcc.gnu.org] On Behalf Of Eric Botcazou

Once this is done, the same thing needs to be applied to XEXP
(reg_equal, 0)
before it is sent to nonzero_bits.



- /* Don't call nonzero_bits if it cannot change anything.  */
- if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
-   rsp-nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
  num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
  if (rsp-sign_bit_copies == 0

  || rsp-sign_bit_copies  num)

rsp-sign_bit_copies = num;
+
+ /* Don't call nonzero_bits if it cannot change anything.  */
+ if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
+   update_rsp_from_reg_equal (rsp, insn, src, x);


Can't we improve on this?  rsp-sign_bit_copies is modified both here
and in
update_rsp_from_reg_equal, but rsp-nonzero_bits is modified only in
the
latter function.  There is no reason for this discrepancy, so they ought to
be
handled the same way, either entirely here or entirely in the function.


So I moved all the handling inside the new function and also added a check
before calling num_sign_bit_copies about whether it would give any more
information to be consistent with what is done for nonzero_bits.

ChangeLog entry is as follows:

2015-02-09  Thomas Preud'homme  thomas.preudho...@arm.com

 * combine.c i(set_nonzero_bits_and_sign_copies): Split code updating
 rsp-sign_bit_copies and rsp-nonzero_bits into ...
 (update_rsp_from_reg_equal): This.  Also use REG_EQUAL note on src if
 present to get more accurate information about the number of sign bit
 copies and non zero bits.
Do you have a testcase where this change can result in better generated 
code.  If so please add that testcase.  It's OK if it's ARM specific.


OK with a testcase.

jeff



RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2015-02-09 Thread Thomas Preud'homme
And this is part 2.

 From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
 ow...@gcc.gnu.org] On Behalf Of Eric Botcazou
 
 Once this is done, the same thing needs to be applied to XEXP
 (reg_equal, 0)
 before it is sent to nonzero_bits.
 
 
  - /* Don't call nonzero_bits if it cannot change anything.  */
  - if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
  -   rsp-nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
if (rsp-sign_bit_copies == 0
 
|| rsp-sign_bit_copies  num)
 
  rsp-sign_bit_copies = num;
  +
  + /* Don't call nonzero_bits if it cannot change anything.  */
  + if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
  +   update_rsp_from_reg_equal (rsp, insn, src, x);
 
 Can't we improve on this?  rsp-sign_bit_copies is modified both here
 and in
 update_rsp_from_reg_equal, but rsp-nonzero_bits is modified only in
 the
 latter function.  There is no reason for this discrepancy, so they ought to
 be
 handled the same way, either entirely here or entirely in the function.

So I moved all the handling inside the new function and also added a check
before calling num_sign_bit_copies about whether it would give any more
information to be consistent with what is done for nonzero_bits.

ChangeLog entry is as follows:

2015-02-09  Thomas Preud'homme  thomas.preudho...@arm.com

* combine.c i(set_nonzero_bits_and_sign_copies): Split code updating
rsp-sign_bit_copies and rsp-nonzero_bits into ...
(update_rsp_from_reg_equal): This.  Also use REG_EQUAL note on src if
present to get more accurate information about the number of sign bit
copies and non zero bits.

diff --git a/gcc/combine.c b/gcc/combine.c
index f2b26c2..622279e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1660,6 +1660,51 @@ sign_extend_short_imm (rtx src, machine_mode mode, 
unsigned int prec)
 }
 #endif
 
+/* Update RSP for pseudo-register X from INSN's REG_EQUAL note (if one exists)
+   and SET.  */
+
+static void
+update_rsp_from_reg_equal (reg_stat_type *rsp, rtx_insn *insn, const_rtx set,
+  rtx x)
+{
+  rtx reg_equal_note = insn ? find_reg_equal_equiv_note (insn) : NULL_RTX;
+  unsigned HOST_WIDE_INT bits = 0;
+  rtx reg_equal = NULL, src = SET_SRC (set);
+  unsigned int num = 0;
+
+  if (reg_equal_note)
+reg_equal = XEXP (reg_equal_note, 0);
+
+#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
+  src = sign_extend_short_imm (src, GET_MODE (x), BITS_PER_WORD);
+  if (reg_equal)
+reg_equal = sign_extend_short_imm (reg_equal, GET_MODE (x), BITS_PER_WORD);
+#endif
+
+  /* Don't call nonzero_bits if it cannot change anything.  */
+  if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
+{
+  bits = nonzero_bits (src, nonzero_bits_mode);
+  if (reg_equal  bits)
+   bits = nonzero_bits (reg_equal, nonzero_bits_mode);
+  rsp-nonzero_bits |= bits;
+}
+
+  /* Don't call num_sign_bit_copies if it cannot change anything.  */
+  if (rsp-sign_bit_copies != 1)
+{
+  num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
+  if (reg_equal  num != GET_MODE_PRECISION (GET_MODE (x)))
+   {
+ unsigned int numeq = num_sign_bit_copies (reg_equal, GET_MODE (x));
+ if (num == 0 || numeq  num)
+   num = numeq;
+   }
+  if (rsp-sign_bit_copies == 0 || num  rsp-sign_bit_copies)
+   rsp-sign_bit_copies = num;
+}
+}
+
 /* Called via note_stores.  If X is a pseudo that is narrower than
HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero.
 
@@ -1675,7 +1720,6 @@ static void
 set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
 {
   rtx_insn *insn = (rtx_insn *) data;
-  unsigned int num;
 
   if (REG_P (x)
REGNO (x) = FIRST_PSEUDO_REGISTER
@@ -1735,21 +1779,7 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, 
void *data)
   if (SET_DEST (set) == x
  || (paradoxical_subreg_p (SET_DEST (set))
   SUBREG_REG (SET_DEST (set)) == x))
-   {
- rtx src = SET_SRC (set);
-
-#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
- src = sign_extend_short_imm (src, GET_MODE (x), BITS_PER_WORD);
-#endif
-
- /* Don't call nonzero_bits if it cannot change anything.  */
- if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
-   rsp-nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
- num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
- if (rsp-sign_bit_copies == 0
- || rsp-sign_bit_copies  num)
-   rsp-sign_bit_copies = num;
-   }
+   update_rsp_from_reg_equal (rsp, insn, set, x);
   else
{
  rsp-nonzero_bits = GET_MODE_MASK (GET_MODE (x));

Is this ok for stage 1?

Best regards,

Thomas 






Re: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2014-12-15 Thread Eric Botcazou
 Thanks for the comments. Patch is updated.
 
 diff --git a/gcc/combine.c b/gcc/combine.c
 index 1808f97..2e865d7 100644
 --- a/gcc/combine.c
 +++ b/gcc/combine.c
 @@ -1603,6 +1603,28 @@ setup_incoming_promotions (rtx_insn *first)
  }
  }
 
 +/* Update RSP from INSN's REG_EQUAL note and SRC.  */
 +
 +static void
 +update_rsp_from_reg_equal (reg_stat_type *rsp, rtx_insn *insn, rtx src, rtx
 x)
 +{
 +  rtx reg_equal = insn ? find_reg_equal_equiv_note (insn) : NULL_RTX;
 +  unsigned HOST_WIDE_INT bits = nonzero_bits (src, nonzero_bits_mode);

Note that src has taken the SHORT_IMMEDIATES_SIGN_EXTEND path here.

 +  if (reg_equal)
 +{
 +  unsigned int num = num_sign_bit_copies (XEXP (reg_equal, 0),
 +   GET_MODE (x));
 +  bits = nonzero_bits (XEXP (reg_equal, 0), nonzero_bits_mode);

But XEXP (reg_equal, 0) hasn't here.  If we want to treat the datum of the 
REG_EQUAL or REG_EQUIV note as equivalent to the SET_SRC (set), and I think we 
should (see for example combine.c:9650), there is a problem.

So I think we should create a new function, something along of:

/* If MODE has a precision lower than PREC and SRC is a non-negative constant
   that would appear negative in MODE, sign-extend SRC for use in nonzero_bits
   because some machines (maybe most) will actually do the sign-extension and
   this is the conservative approach.

   ??? For 2.5, try to tighten up the MD files in this regard
   instead of this kludge.  */

rtx
sign_extend_short_imm (rtx src, machine_mode mode, unsigned int prec)
{
  if (GET_MODE_PRECISION (mode)  prec
 CONST_INT_P (src)
 INTVAL (src)  0
 val_signbit_known_set_p (mode, INTVAL (src)))
src = GEN_INT (INTVAL (src) | ~GET_MODE_MASK (mode));

  return src;
}

and calls it from combine.c:1702

#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
  src = sign_extend_short_imm (src, GET_MODE (x), BITS_PER_WORD);
#endif

and from combine.c:9650

#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
  tem = sign_extend_short_imm (tem, GET_MODE (x), GET_MODE_PRECISION (mode));
#endif

Once this is done, the same thing needs to be applied to XEXP (reg_equal, 0) 
before it is sent to nonzero_bits.


 -   /* Don't call nonzero_bits if it cannot change anything.  */
 -   if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
 - rsp-nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
 num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
 if (rsp-sign_bit_copies == 0
 
 || rsp-sign_bit_copies  num)
 
   rsp-sign_bit_copies = num;
 +
 +   /* Don't call nonzero_bits if it cannot change anything.  */
 +   if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
 + update_rsp_from_reg_equal (rsp, insn, src, x);

Can't we improve on this?  rsp-sign_bit_copies is modified both here and in 
update_rsp_from_reg_equal, but rsp-nonzero_bits is modified only in the 
latter function.  There is no reason for this discrepancy, so they ought to be 
handled the same way, either entirely here or entirely in the function.

-- 
Eric Botcazou


RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2014-12-12 Thread Zhenqiang Chen

 -Original Message-
 From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
 ow...@gcc.gnu.org] On Behalf Of Eric Botcazou
 Sent: Monday, November 24, 2014 5:41 PM
 To: Zhenqiang Chen
 Cc: gcc-patches@gcc.gnu.org
 Subject: Re: [PATCH, combine] Try REG_EQUAL for nonzero_bits
 
  Thanks for the comments. I will compare the two nonzero_bits from src
  and REG_EQUAL. Then select the smaller one.
 
 They are masks so you can simply AND them before ORing the result.
 
  Do you know why it use  SET_SRC (set) other than src for
  num_sign_bit_copies?
 
  If it is src, I should do the same for num_sign_bit_copies with 
  REG_EQUAL info.
 
 Probably historical reasons, let's not try to change that now.  You can
apply
 the same treatment to num_sign_bit_copies (you will need a comparison
 here) while preserving the src vs SET_SRC (set) discrepancy.

Thanks for the comments. Patch is updated.

diff --git a/gcc/combine.c b/gcc/combine.c
index 1808f97..2e865d7 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1603,6 +1603,28 @@ setup_incoming_promotions (rtx_insn *first)
 }
 }
 
+/* Update RSP from INSN's REG_EQUAL note and SRC.  */
+
+static void
+update_rsp_from_reg_equal (reg_stat_type *rsp, rtx_insn *insn, rtx src, rtx
x)
+{
+  rtx reg_equal = insn ? find_reg_equal_equiv_note (insn) : NULL_RTX;
+  unsigned HOST_WIDE_INT bits = nonzero_bits (src, nonzero_bits_mode);
+
+  if (reg_equal)
+{
+  unsigned int num = num_sign_bit_copies (XEXP (reg_equal, 0),
+ GET_MODE (x));
+  bits = nonzero_bits (XEXP (reg_equal, 0), nonzero_bits_mode);
+  rsp-nonzero_bits |= bits;
+
+  if (rsp-sign_bit_copies  num)
+   rsp-sign_bit_copies = num;
+}
+  else
+rsp-nonzero_bits |= bits;
+}
+
 /* Called via note_stores.  If X is a pseudo that is narrower than
HOST_BITS_PER_WIDE_INT and is being set, record what bits are known
zero.
 
@@ -1698,13 +1720,14 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx
set, void *data)
src = GEN_INT (INTVAL (src) | ~GET_MODE_MASK (GET_MODE (x)));
 #endif
 
- /* Don't call nonzero_bits if it cannot change anything.  */
- if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
-   rsp-nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
  num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
  if (rsp-sign_bit_copies == 0
  || rsp-sign_bit_copies  num)
rsp-sign_bit_copies = num;
+
+ /* Don't call nonzero_bits if it cannot change anything.  */
+ if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
+   update_rsp_from_reg_equal (rsp, insn, src, x);
}
   else
{





RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2014-11-24 Thread Zhenqiang Chen


 -Original Message-
 From: Eric Botcazou [mailto:ebotca...@adacore.com]
 Sent: Saturday, November 22, 2014 6:15 PM
 To: Zhenqiang Chen
 Cc: gcc-patches@gcc.gnu.org
 Subject: Re: [PATCH, combine] Try REG_EQUAL for nonzero_bits
 
  The patch tries to use REG_EQUAL to get more precise info for
  nonzero_bits, which helps to remove unnecessary zero_extend.
 
  Here is an example when compiling Coremark, we have rtx like,
 
  (insn 1244 386 388 47 (set (reg:SI 263 [ D.5767 ])
  (reg:SI 384 [ D.5767 ])) 786 {*thumb2_movsi_insn}
   (expr_list:REG_EQUAL (zero_extend:SI (mem:QI (reg/v/f:SI 271 [
  memblock
  ]) [0 *memblock_13(D)+0 S1 A8]))
  (nil)))
 
  from reg:SI 384, we can only know it is a 32-bit value. But from
  REG_EQUAL, we can know it is an 8-bit value. Then for the following
  rtx seq,
 
  (insn 409 407 410 50 (set (reg:SI 308)
  (plus:SI (reg:SI 263 [ D.5767 ])
  (const_int -48 [0xffd0]))) core_state.c:170 4
  {*arm_addsi3}
   (nil))
  (insn 410 409 411 50 (set (reg:SI 309)
  (zero_extend:SI (subreg:QI (reg:SI 308) 0))) core_state.c:170
  812 {thumb2_zero_extendqisi2_v6}
   (expr_list:REG_DEAD (reg:SI 308)
  (nil)))
 
  the zero_extend for r309 can be optimized by combine pass.
 
 This sounds like a good idea.
 
  2014-11-21  Zhenqiang Chen  zhenqiang.c...@arm.com
 
  * combine.c (set_nonzero_bits_and_sign_copies): Try REG_EQUAL
 note.
 
  diff --git a/gcc/combine.c b/gcc/combine.c index 6a7d16b..68a883b
  100644
  --- a/gcc/combine.c
  +++ b/gcc/combine.c
  @@ -1713,7 +1713,15 @@ set_nonzero_bits_and_sign_copies (rtx x,
  const_rtx set, void *data)
 
/* Don't call nonzero_bits if it cannot change anything.  */
if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
  -   rsp-nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
  +   {
  + rtx reg_equal = insn ? find_reg_note (insn, REG_EQUAL,
  NULL_RTX)
  +: NULL_RTX;
  + if (reg_equal)
  +   rsp-nonzero_bits |= nonzero_bits (XEXP (reg_equal, 0),
  +  nonzero_bits_mode);
  + else
  +   rsp-nonzero_bits |= nonzero_bits (src,
 nonzero_bits_mode);
  +   }
num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
if (rsp-sign_bit_copies == 0
 
|| rsp-sign_bit_copies  num)
 
 Use find_reg_equal_equiv_note instead.  Are you sure that this won't yield
 inferior results in very peculiar cases?  IOW, why not use both sources?

Thanks for the comments. I will compare the two nonzero_bits from src and
REG_EQUAL. Then select the smaller one.
 
 Note that 'src' is massaged just above if SHORT_IMMEDIATES_SIGN_EXTEND
 is defined so we should probably do it for the note datum too, for example
 by factoring the code into a function and invoking it.
 
 Why not do the same for num_sign_bit_copies?

Do you know why it use  SET_SRC (set) other than src for
num_sign_bit_copies?

If it is src, I should do the same for num_sign_bit_copies with REG_EQUAL
info.

Thanks!
-Zhenqiang






Re: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2014-11-24 Thread Eric Botcazou
 Thanks for the comments. I will compare the two nonzero_bits from src and
 REG_EQUAL. Then select the smaller one.

They are masks so you can simply AND them before ORing the result.

 Do you know why it use  SET_SRC (set) other than src for
 num_sign_bit_copies?
 
 If it is src, I should do the same for num_sign_bit_copies with REG_EQUAL
 info.

Probably historical reasons, let's not try to change that now.  You can apply 
the same treatment to num_sign_bit_copies (you will need a comparison here) 
while preserving the src vs SET_SRC (set) discrepancy.

-- 
Eric Botcazou


Re: [PATCH, combine] Try REG_EQUAL for nonzero_bits

2014-11-22 Thread Eric Botcazou
 The patch tries to use REG_EQUAL to get more precise info for nonzero_bits,
 which helps to remove unnecessary zero_extend.
 
 Here is an example when compiling Coremark, we have rtx like,
 
 (insn 1244 386 388 47 (set (reg:SI 263 [ D.5767 ])
 (reg:SI 384 [ D.5767 ])) 786 {*thumb2_movsi_insn}
  (expr_list:REG_EQUAL (zero_extend:SI (mem:QI (reg/v/f:SI 271 [ memblock
 ]) [0 *memblock_13(D)+0 S1 A8]))
 (nil)))
 
 from reg:SI 384, we can only know it is a 32-bit value. But from
 REG_EQUAL, we can know it is an 8-bit value. Then for the following rtx seq,
 
 (insn 409 407 410 50 (set (reg:SI 308)
 (plus:SI (reg:SI 263 [ D.5767 ])
 (const_int -48 [0xffd0]))) core_state.c:170 4
 {*arm_addsi3}
  (nil))
 (insn 410 409 411 50 (set (reg:SI 309)
 (zero_extend:SI (subreg:QI (reg:SI 308) 0))) core_state.c:170 812
 {thumb2_zero_extendqisi2_v6}
  (expr_list:REG_DEAD (reg:SI 308)
 (nil)))
 
 the zero_extend for r309 can be optimized by combine pass.

This sounds like a good idea.

 2014-11-21  Zhenqiang Chen  zhenqiang.c...@arm.com
 
   * combine.c (set_nonzero_bits_and_sign_copies): Try REG_EQUAL note.
 
 diff --git a/gcc/combine.c b/gcc/combine.c
 index 6a7d16b..68a883b 100644
 --- a/gcc/combine.c
 +++ b/gcc/combine.c
 @@ -1713,7 +1713,15 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx
 set, void *data)
 
 /* Don't call nonzero_bits if it cannot change anything.  */
 if (rsp-nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
 - rsp-nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
 + {
 +   rtx reg_equal = insn ? find_reg_note (insn, REG_EQUAL,
 NULL_RTX)
 +  : NULL_RTX;
 +   if (reg_equal)
 + rsp-nonzero_bits |= nonzero_bits (XEXP (reg_equal, 0),
 +nonzero_bits_mode);
 +   else
 + rsp-nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
 + }
 num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
 if (rsp-sign_bit_copies == 0
 
 || rsp-sign_bit_copies  num)

Use find_reg_equal_equiv_note instead.  Are you sure that this won't yield 
inferior results in very peculiar cases?  IOW, why not use both sources?

Note that 'src' is massaged just above if SHORT_IMMEDIATES_SIGN_EXTEND is 
defined so we should probably do it for the note datum too, for example by 
factoring the code into a function and invoking it.

Why not do the same for num_sign_bit_copies?

-- 
Eric Botcazou