symbol_ref constants
My port have insns like add symbol_ref, r1 We emit relocation entries for symbol_ref. Now CSE (-O2) combines insns like below mov symbol_ref, r0 add const_int, r0 add r0, r1 to add symbol_ref + const_int, r1 The relocation entry generated for this insn look like symbol + addend. The resultant value is beoyond the relocation size, and results into relocation overflow. But the code works fine with -O0, since the relocation generated for symbol is within the limits. I guess CSE will not do this if I exclude constants like symobol_ref + const_int from the insn pattern. Currently I allow "nonmemory_operand" for this insn. Thanks for any help on this. Regards --Sanjiv __ Do you Yahoo!? Yahoo! Small Business - Try our new resources site! http://smallbusiness.yahoo.com/resources/
Re: symbol_ref constants
--- Nathan Sidwell <[EMAIL PROTECTED]> wrote: > Sanjiv Kumar Gupta wrote: > > > add symbol_ref + const_int, r1 > > > > The relocation entry generated for this insn look > like > > symbol + addend. > > > > The resultant value is beoyond the relocation > size, > > and results into relocation overflow. > > > I guess CSE will not do this if I exclude > constants > > like symobol_ref + const_int from the insn > pattern. > > Currently I allow "nonmemory_operand" for this > insn. > > If your add instructions cannot take symbol refs, > then > you need a different predicate -- const_int_operand > would > probably be correct. > > nathan > Thanks for a prompt reply, Nathan. The add insn can take a symbol_ref, which is converted to const_int during relocation. But I don't want to allow expressions like (const:SI (plus:SI symbol_ref:SI) (const_int)) in the insn. How should I do that, do I need to implement LEGITIMATE_CONST_P () accordingly? thanks. __ Do you Yahoo!? Yahoo! Small Business - Try our new resources site! http://smallbusiness.yahoo.com/resources/
Re: symbol_ref constants
--- Nathan Sidwell <[EMAIL PROTECTED]> wrote: > Sanjiv Kumar Gupta wrote: > > > > > Thanks for a prompt reply, Nathan. > > The add insn can take a symbol_ref, which is > converted > > to const_int during relocation. But I don't want > to > > allow expressions like (const:SI (plus:SI > > symbol_ref:SI) (const_int)) in the insn. > > How should I do that, do I need to implement > > LEGITIMATE_CONST_P () accordingly? > > you could do that, but I don't understand why > symref+const > is not allowed. After all, you could have a > different plain symref whose > value was the original symbol+const. > > I.e. why is > add r1,foo+10 > not allowed, but > add r1,baz > allowed. When linking baz could be defined as > 'foo+10'. so what's going > on? > > nathan consider the second operand as an 8-bit offset calculated by linker. Now add r1, foo add r1, 10 add r1, -10 are okay but add r1, foo + 10 add r1, -10 are not, since (foo + 10) may overflow during relocation, so the value (foo + 10) && 0xff inserted by linker is not correct. Let me know if I am still not able to explain it. Regards --Sanjiv. __ Do you Yahoo!? Yahoo! Small Business - Try our new resources site! http://smallbusiness.yahoo.com/resources/
Re: symbol_ref constants
Nathan Sidwell wrote: Sanjiv Kumar Gupta wrote: calculated by linker. Now add r1, foo add r1, 10 add r1, -10 are okay but add r1, foo + 10 add r1, -10 are not, since (foo + 10) may overflow during relocation, so the value (foo + 10) && 0xff inserted by linker is not correct. What is stopping the value of 'foo' itself being > 255? nathan Programmer will get an overflow error for that during linking. But the problem here is that with foo = 255, the code works without -O2, but not with -O2, which looks strange. Since -O2 (CSE) combines add r1, foo add r1, 10 to add r1, foo + 10 Thanks. --Sanjiv
RE: symbol_ref constants
> Sanjiv Kumar Gupta wrote: > > > > What is stopping the value of 'foo' itself being > > 255? > > Programmer will get an overflow error for that > during linking. > > For my curiosity, what's the background here? Do you > really only have 256 > bytes of storage on this system? > That was just an example. We have an "segment_base+offset" insn with 16-bit offset. > If you've got eight bit registers in a larger > address space then I'd expect > you'd want to address data outside the first 256 > bytes, e.g. you'd actually > want > > add r1, lowpart_offset(foo) > add r2, highpart_offset(foo) > > in which case > > add r1, lowpart_offset(foo + 10) > add r2, highpart_offset(foo + 10) > > would make sense. > > On the other hand, if you actually do only have 256 > bytes storage then you'd > want to the link to fail anyway because the hardware > won't cope - so the > overflow error is as good as anything else, isn't > it? > > Rup. > The problem at my hand is that the code like j = 10; // global main () { int i; i = a[j - 10]; } doesn't work with -O2 but it works without -O2. -O2 generates like add1 r1, segment_base, (a - 40) add2 r1, 40 Since 'a' is at the boundary of segment so 'a - 40' causes relocation overflow. But the same code works without -O2, because that generates code like add1 r1, segment_base, a add2 r1, -40 add2 r1, 40 So, all I want to do is don't allow 'a - 40' in 'add1' so that -O2 doesn't seem to be broken. thanks --Sanjiv > > > __ Do you Yahoo!? Yahoo! Small Business - Try our new resources site! http://smallbusiness.yahoo.com/resources/
RE: symbol_ref constants
> add1 r1, segment_base, (a - 40) > add2 r1, 40 read this as add2 r1, the value of j > > Since 'a' is at the boundary of segment so 'a - 40' > causes relocation overflow. > > But the same code works without -O2, because that > generates code like > add1 r1, segment_base, a > add2 r1, -40 > add2 r1, 40 ditto here. thanks __ Do you Yahoo!? Yahoo! Small Business - Try our new resources site! http://smallbusiness.yahoo.com/resources/
Re: symbol_ref constants
--- James E Wilson <[EMAIL PROTECTED]> wrote: > Sanjiv Kumar Gupta wrote: > > But I don't want to > > allow expressions like (const:SI (plus:SI > > symbol_ref:SI) (const_int)) in the insn. > > How should I do that, do I need to implement > > LEGITIMATE_CONST_P () accordingly? > > Try making CONSTANT_ADDRESS_P reject the value. > > Though it still isn't clear why you are getting > relocation errors. If > addresses wrap around at segment boundaries, then > this should just work > fine. a-40 gets converted into a very large > positive segment offset > that then wraps around back to a when 40 is added to > it. Perhaps the > assembler/linker need some work to handle this > correctly. > -- > Jim Wilson, GNU Tools Support, > http://www.SpecifixInc.com > Thank Jim, for your help. I have fixed the problem by disallowing such operands for the insn. It was actually a signed offset, and the sign bit of large negative offset was getting lost during relocation. So adding the same constant wouldn't restore it back. Thanks again. Regards --Sanjiv __ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
GCC 3.3.1 -O2 problem with sqrt.c
I am using gcc 3.3.1 release as my port, and looks like I have hit a problem with greg. The source program is the sqrt.c math function __ieee754_sqrt. ( I am pasting the relevent part here) typedef union { double value; struct { unsigned int lsw; unsigned int msw; } parts; } ieee_double_shape_type; double __ieee754_sqrt (double x) { double z; int sign = (int) 0x8000; unsigned int r, t1, s1, ix1, q1; int ix0, s0, q, m, t, i; .. .. if ((q & 1) == 1) ix1 |= sign; ix0 += (m << 20); do { ieee_double_shape_type iw_u; iw_u.parts.msw = (ix0); // line 140 iw_u.parts.lsw = (ix1);// line 141 (z) = iw_u.value; // line 142 } } The dump of corresponding BBs of .23.lreg is as (insn 419 516 420 38 0x1002f450 (set (reg/v:SI 77) (ior:SI (reg/v:SI 77) (const_int -2147483648 [0x8000]))) 26 {iorsi3} (nil) (nil)) ;; End of basic block 38, registers live: 20 [r20] 21 [r21] 30 [r30] 64 [ap] 77 79 82 153 ;; Start of basic block 39, registers live: 20 [r20] 21 [r21] 30 [r30] 64 [ap] 7 7 79 82 153 (code_label 420 419 517 39 43 "" [1 uses]) (note 517 420 421 39 [bb 39] NOTE_INSN_BASIC_BLOCK) (note 421 517 422 39 ("sqrt.c") 136) (insn 422 421 423 39 0x1002f450 (set (reg/v:SI 82) (ashift:SI (reg/v:SI 82) (const_int 20 [0x14]))) 22 {ashlsi3} (nil) (nil)) (note 423 422 427 39 NOTE_INSN_DELETED) (note 427 423 428 39 ("sqrt.c") 139) (note 428 427 429 39 ("sqrt.c") 140) (insn 429 428 430 39 0x1002f420 (set (subreg:SI (reg/v:DI 153) 4) (plus:SI (reg/v:SI 79) (reg/v:SI 82))) 12 {addsi3} (insn_list 422 (nil)) (expr_list:REG_DEAD (reg/v:SI 82) (expr_list:REG_DEAD (reg/v:SI 79) (nil (note 430 429 431 39 ("sqrt.c") 141) (insn 431 430 432 39 0x1002f420 (set (subreg:SI (reg/v:DI 153) 0) (reg/v:SI 77)) 6 {*movsi} (insn_list 429 (nil)) (expr_list:REG_DEAD (reg/v:SI 77) (nil))) (note 432 431 433 39 ("sqrt.c") 142) (insn 433 432 436 39 0x1002f420 (set (reg:DF 70) (subreg:DF (reg/v:DI 153) 0)) 10 {*movdf} (insn_list 431 (nil)) (expr_list:REG_DEAD (reg/v:DI 153) (nil))) And the dump of .24.greg pass is as: (insn 419 516 420 38 0x1002f450 (set (reg/v:SI 12 r12 [77]) (ior:SI (reg/v:SI 12 r12 [77]) (const_int -2147483648 [0x8000]))) 26 {iorsi3} (nil) (nil)) ;; End of basic block 38, registers live: 20 [r20] 21 [r21] 30 [r30] 64 [ap] 77 79 82 153 ;; Start of basic block 39, registers live: 20 [r20] 21 [r21] 30 [r30] 77 79 82 153 (code_label 420 419 517 39 43 "" [1 uses]) (note 517 420 421 39 [bb 39] NOTE_INSN_BASIC_BLOCK) (note 421 517 422 39 ("sqrt.c") 136) (insn 422 421 423 39 0x1002f450 (set (reg/v:SI 4 r4 [82]) (ashift:SI (reg/v:SI 4 r4 [82]) (const_int 20 [0x14]))) 22 {ashlsi3} (nil) (nil)) (note 423 422 427 39 NOTE_INSN_DELETED) (note 427 423 428 39 ("sqrt.c") 139) (note 428 427 429 39 ("sqrt.c") 140) (insn 429 428 618 39 0x1002f420 (set (reg/v:SI 4 r4 [82]) (plus:SI (reg/v:SI 4 r4 [82]) (reg/v:SI 3 r3 [79]))) 12 {addsi3} (insn_list 422 (nil)) (nil)) (insn 618 429 619 39 0x0 (set (reg:SI 0 r0) (reg/v:SI 4 r4 [82])) 6 {*movsi} (nil) (nil)) (insn 619 618 430 39 0x0 (set (mem:SI (plus:SI (reg/f:SI 21 r21) (const_int -4 [0xfffc])) [3 iw_u S4 A32]) (reg:SI 0 r0)) 6 {*movsi} (nil) (nil)) (note 430 619 431 39 ("sqrt.c") 141) (insn 431 430 620 39 0x1002f420 (set (reg:SI 0 r0) (reg/v:SI 12 r12 [77])) 6 {*movsi} (insn_list 429 (nil)) (nil)) (insn 620 431 621 39 0x0 (set (reg:DI 2 r2) (reg:DI 0 r0)) 7 {*movdi} (nil) (nil)) (insn 621 620 432 39 0x0 (set (mem:DI (plus:SI (reg/f:SI 21 r21) (const_int -8 [0xfff8])) [3 iw_u S8 A32]) (reg:DI 2 r2)) 7 {*movdi} (nil) (nil)) (note 432 621 433 39 ("sqrt.c") 142) (insn 433 432 436 39 0x1002f420 (set (reg:DF 14 r14 [70]) (reg:DF 0 r0)) 10 {*movdf} (insn_list 431 (nil)) (nil)) I couldn't understand why the insns 620 and 621 are being generated here as DI moves. This is creating problem since insn 621 gets splitted after reload into two SI moves,i.e. @(r21, -8) and @(r21, -4). This renders insns 619 as dead and hence insns 618 and insn 429 as dead, which are eliminated by flow2. I could not analyze beyond this and need your help to move further. Thanks in advance. Sanjiv __ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
Re: GCC 3.3.1 -O2 problem with sqrt.c
Ian Lance Taylor wrote: Sanjiv Kumar Gupta <[EMAIL PROTECTED]> writes: I am using gcc 3.3.1 release as my port, and looks like I have hit a problem with greg. You neglected to mention what target you are using. Ian, the port is for a 32-bit RISC and not complete yet, hence still not contributed. This probably makes difficult for you to suggest any fix, but I still asked in case I could get any pointers for investigation. I couldn't understand why the insns 620 and 621 are being generated here as DI moves. I'm not sure specifically why it got a DI move here, but it doesn't look wrong. It's treating the struct named parts as DImode. This is creating problem since insn 621 gets splitted after reload into two SI moves,i.e. @(r21, -8) and @(r21, -4). This renders insns 619 as dead and hence insns 618 and insn 429 as dead, which are eliminated by flow2. It does look rather suspicious, but it's hard to know whether it is wrong without seeing the value in r1. r1 looks unrelated to struct members, and is being used by the ifcvt pass to expand some comparison insns. Does the behaviour change if you use -fno-strict-aliasing? (I can't remember what the default was in 3.3.1). Ian The behaviour doesn't changes with -fno-strict-aliasing or -fstrict-aliasing. Thanks Sanjiv
Re: GCC 3.3.1 -O2 problem with sqrt.c
. I don't know whether gcc mail server accepts attachments or not, Oh. It does. --- Ian Lance Taylor wrote: Sanjiv Kumar Gupta <[EMAIL PROTECTED]> writes: I am using gcc 3.3.1 release as my port, and looks like I have hit a problem with greg. You neglected to mention what target you are using. I couldn't understand why the insns 620 and 621 are being generated here as DI moves. I'm not sure specifically why it got a DI move here, but it doesn't look wrong. It's treating the struct named parts as DImode. This is creating problem since insn 621 gets splitted after reload into two SI moves,i.e. @(r21, -8) and @(r21, -4). This renders insns 619 as dead and hence insns 618 and insn 429 as dead, which are eliminated by flow2. It does look rather suspicious, but it's hard to know whether it is wrong without seeing the value in r1. Does the behaviour change if you use -fno-strict-aliasing? (I can't remember what the default was in 3.3.1). Ian __ Yahoo! Mail Stay connected, organized, and protected. Take the tour: http://tour.mail.yahoo.com/mailtour.html
Re: GCC 3.3.1 -O2 problem with sqrt.c
--- Ian Lance Taylor wrote: > Sanjiv Kumar Gupta <[EMAIL PROTECTED]> writes: > > > >>I couldn't understand why the insns 620 and 621 > are > > >>being generated here as DI moves. > > > I'm not sure specifically why it got a DI move > here, but it doesn't > > > look wrong. It's treating the struct named > parts as DImode. > > > > > >>This is creating problem since insn 621 gets > splitted > > >>after reload into two SI moves,i.e. @(r21, -8) > and > > >>@(r21, -4). > > >>This renders insns 619 as dead and hence insns > 618 and > > >>insn 429 as dead, which are eliminated by flow2. > > > It does look rather suspicious, but it's hard to > know whether it is > > > wrong without seeing the value in r1. > > > > > r1 looks unrelated to struct members, and is being > used by the > > ifcvt pass to expand some comparison insns. > > In your .23 file, this is insn 431: > > (insn 431 430 432 39 0x1002f420 (set (subreg:SI > (reg/v:DI 153) 0) > (reg/v:SI 77)) 6 {*movsi} (insn_list 429 > (nil)) > (expr_list:REG_DEAD (reg/v:SI 77) > (nil))) > > So it is setting the first SI subreg of a DI value. > reload decides to > do an output reload for register 153. Since > register 153 is DImode, > it does a DImode reload. > > It winds up copying the DImode value to r2, and then > writing r2 to > memory. The double move is because there is a > secondary reload > involved. That implies that > SECONDARY_OUTPUT_RELOAD_CLASS is defined > and is returning something other than NO_REGS for > this case. > > I see that insn 429 is setting the high part of > register 153. Insn > 429 looks like this: > > (insn 429 428 430 39 0x1002f420 (set (subreg:SI > (reg/v:DI 153) 4) > (plus:SI (reg/v:SI 79) > (reg/v:SI 82))) 12 {addsi3} (insn_list > 422 (nil)) > (expr_list:REG_DEAD (reg/v:SI 82) > (expr_list:REG_DEAD (reg/v:SI 79) > (nil > > But note that a set to a subreg is explicitly > defined to set the other > parts of the register to garbage. Therefore the > value set by insn 429 > is destroyed by insn 431. > > I would guess that you need a strict_low_part in > insns 429 and 431. > See the RTL documentation. > > Ian > Thanks Ian for your inputs. The problem got solved. There was no intermediate reg needed for this reload. But I still feel that a strict_low_part would be needed as you suggested. Thanks again. Sanjiv __ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com