This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

LOAD_EXTEND_OP crippled


Hi Roger,

I'm trying to understand your patch from:
  http://gcc.gnu.org/ml/gcc-patches/2002-07/msg00383.html

You wrote:
 The bug is that simplify_comparison believes that (subreg (reg ...))
 has undefined upper bits, but the two functions nonzero_bits and
 num_sign_bit_copies believe (subreg (reg ...)) is extended according
 to LOAD_EXTEND_OP.  The fix below is to tighten the extension tests
 in these two functions to check "GET_CODE (SUBREG_REG (x)) == MEM".

I don't think that's what the code was doing.  It's not believing that it
will be extended in some particular way, but rather that its high bits are
not rendered undefined by a move - whatever we already knew about them. 
This fits with the definition of WORD_REGISTER_OPERATIONS.

The reason I'm looking at this patch is a port I'm working on which defines
both LOAD_EXTEND_OP (to ZERO_EXTEND) and WORD_REGISTER_OPERATIONS.  I have
this simple RTL:

(insn 21 20 22 0 0x403ae0c0 (set (reg:SI 30)
        (mem/s:SI (reg/f:DI 28) [2 <variable> S4 A32])) 1 {*movsi_insn} (insn_list 19 (nil))
    (expr_list:REG_DEAD (reg/f:DI 28)
        (nil)))

(insn 23 22 24 0 0x403ae0c0 (set (reg:DI 32)
        (zero_extend:DI (reg:SI 30))) 6 {zero_extendsidi2} (insn_list 21 (nil))
    (nil))

We can't combine these, but we should be able to.  We transform the
zero_extend into:
  (and:DI (subreg:DI (reg:SI 30) 0)
          (const_int 4294967295 [0xffffffff]))

When we call nonzero_bits1 on the subreg, it recursively calls nonzero_bits
on the register; finds out that the SImode register can not have any of the
high 32 bits set; but then sees that it is a subreg of a REG rather than a
MEM and declares all the upper bits as undefined.

Having read the discussion from 2002, I don't really understand the problem
you were solving with your change, so I can't offer an alternative that
won't rebreak it.  You posted the v850 RTL for the shifts which got
combined, but I think the problem was earlier, where you just said:

  Which seems very broken to me.  Tracing the problem further
  it's because num_sign_bit_copies believes that the top 25 bits
  of "(subreg:SI (reg:QI 46))" are always the same, because the
  v850 backend defines WORD_REGISTER_OPERATIONS and LOAD_EXTEND_OP
  as always SIGN_EXTEND.

If the upper 25 bits of (reg:QI 46) were really the same, the shifts would
be no-ops.  If reg:QI was set by a load which sign-extended, this would be
true, so presumably something other than a load set it, and presumably
that's where the problem was.

Any comments?

-- 
Daniel Jacobowitz


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]