This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
LOAD_EXTEND_OP crippled
- From: Daniel Jacobowitz <drow at false dot org>
- To: Roger Sayle <roger at eyesopen dot com>, gcc at gcc dot gnu dot org
- Date: Mon, 14 Jun 2004 16:05:15 -0400
- Subject: 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