This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: (subreg:SF (reg:SC)) question - 20020227-1.c failure
- From: Geoff Keating <geoffk at geoffk dot org>
- To: Ulrich Weigand <weigand at immd1 dot informatik dot uni-erlangen dot de>
- Cc: gcc at gcc dot gnu dot org
- Date: 03 May 2003 11:06:21 -0700
- Subject: Re: (subreg:SF (reg:SC)) question - 20020227-1.c failure
- References: <200305031652.SAA12161@faui11.informatik.uni-erlangen.de>
Ulrich Weigand <weigand@immd1.informatik.uni-erlangen.de> writes:
> Hello,
>
> (set (subreg:M1 (reg:M2)) (...)) can have two meanings
>
> - Set one register of a multi-reg (reg:M2) to a value,
> leaving the other component registers unchanged, or
>
> - Set the whole (reg:M2), where the one subreg gets a
> defined value and the rest is undefined
>
> The question is, into which of these cases does
> (set (subreg:SF (reg:SC)) ...)
> fall?
The actual rule is:
Storing in a non-paradoxical `subreg' has undefined results for
bits belonging to the same word as the `subreg'. This laxity makes
it easier to generate efficient code for such instructions. To
represent an instruction that preserves all the bits outside of
those in the `subreg', use `strict_low_part' around the `subreg'.
so it depends on your word size.
> The test case 20020207-1.c generates initially this RTX:
>
> (insn 10 9 11 (nil) (clobber (reg:SC 42)) -1 (nil)
> (nil))
>
> (insn 11 10 12 (nil) (set (subreg:SF (reg:SC 42) 0)
> (mem/u/f:SF (reg/f:DI 40) [2 S4 A32])) -1 (nil)
> (nil))
>
> (insn 12 11 13 (nil) (set (subreg:SF (reg:SC 42) 4)
> (mem/u/f:SF (plus:DI (reg/f:DI 40)
> (const_int 4 [0x4])) [2 S4 A32])) -1 (nil)
> (nil))
>
> Which clearly is correct only if the subreg is interpreted
> as the multi-reg case. However, mark_used_regs (flow.c)
> has this piece of code:
>
> if (GET_CODE (testreg) == SUBREG
> && !((REG_BYTES (SUBREG_REG (testreg))
> + UNITS_PER_WORD - 1) / UNITS_PER_WORD
> > (REG_BYTES (testreg)
> + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
>
> which classifies the subreg as the single-reg case on
> 64-bit platforms (as both SFmode and SCmode fit into
> UNITS_PER_WORD).
>
> This causes insn 11 above to be classified as dead,
> and the test case fails.
>
> What's the right way to handle this?
Fix whatever's generating the RTL above to use strict_low_part when
necessary.
--
- Geoffrey Keating <geoffk@geoffk.org>