This is the mail archive of the gcc-patches@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]

Re: Ping: [patch] -m128bit-long-double asserts



On 01/04/2005, at 12:58 AM, Stuart Hastings wrote:



On Mar 31, 2005, at 3:30 PM, Geoffrey Keating wrote:



Hi Stuart,


If you look at subreg_offset_representable_p, you'll see that indeed
it does not work properly if the assert does not hold.  For instance,
suppose

ymode == SImode  (size 4)
xmode == XCmode  (size 32)
nregs_xmode == 6
nregs_ymode == 1
offset == 3 + 12

so

y_offset = 3
mode_multiple = 8
nregs_multiple = 6

You'll see that in fact this is not representable, because there is no
register which actually holds that word, but

[if Stuart deletes the troublesome assert]


the routine will
incorrectly return true, saying that it is representable.  I expect
that subreg_regno_offset will fail for many cases where the offset
actually is representable.

(Forgive my insertion; your statement seemed a bit ambiguous to me, so I inferred the meaning shown above.)

Yes.


If I understood what you suggested, well, O.K., but it would assert the same way if invoked with a /valid/ offset. The failing assert fires due to dis-alignment of modes and hard register multiples, and is not affected by the value of the 'offset' parameter.

Yes. This is because it cannot tell which offsets are valid.


In memory, an XCmode constant (in this case, 1.0 + 2.0i) looks like:

.data
        .align 4
_foo:
        .long   0
        .long   -2147483648
        .long   16383
        .long   0
        .long   0
        .long   -2147483648
        .long   16384
        .long   0

That is, it is not two 80-bit values followed by two words of padding, it is an 80-bit value, a word of padding, another 80-bit value, and another word of padding. Thus, there are holes 'in the middle' of the value. Since the holes don't exist when the values are in integer registers, this routine has to know where the holes are so it can say which offsets can be converted into integer register numbers and which can't (and that sounds hard to me).

This takes me to the second patch, which seems correct as far as it
goes, but needs the corresponding change to XCmode, to prevent exactly
the case above.

O.K., but I don't understand how this fixes your (contrived, but excellent) example. I tried the GDB equivalent of "(subreg:SI (reg:XC) 15)", and it asserts on the previous line ("gcc_assert ((offset % GET_MODE_SIZE (ymode)) == 0);").

I may have gotten the offset wrong; try 12 instead. Silly little-endian architectures :-). It's a precondition of this routine that the offset is actually the offset of some aligned YMODE value inside XMODE.


I'd be grateful if you could explain why it's better to pretend that an 80-bit XFmode datum that is allocated 128 bits of memory should be accorded four hard SImode registers. There are really only three (2.5?) SImode datums there; telling subreg_offset_representable_p there's a fourth seems like misrepresentation to me (?).

If you change HARD_REGNO_NREGS, there will be a fourth. It'll be padding, but it will exist, which is the important thing.


I don't know where you came up with your XCmode example; perhaps you noticed the XCmode datum in the testcase.

Actually, I noticed the bug in your second patch first, and that made me think about how XCmode could possibly work.


That's good, but the original failure was due to something like (recalling from weak memory) "(subreg:SI (reg:XF) 12)". The XCmode in the testcase seems to be necessary to recreate the problem, but only distantly; when the assert fires, XCmode is not evident.

You'll notice that "(subreg:SI (reg:XF) 12)" *also* doesn't exist; there is no register for it at present.


To insure we're talking about the same patch, here's what I thought you suggested:

<i386.h.diffs.txt>

2005-04-01 Stuart Hastings <stuart@apple.com>

* config/i386/i386.h(HARD_REGNO_NREGS): Aware of -m128bit-long-double.

(This version hasn't been bootstrapped yet...)

Yes, that looks right. I think it's the most reasonable thing. Of course, it may cause other problems (does x86 even have 8 32-bit registers?) so it'll need a full dejagnu run.

Attachment: smime.p7s
Description: S/MIME cryptographic signature


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