I'll be looking into this but I thought that GO_IF_LEGITIMATE_ADDRESS is for branches ?
This is not my case. I've simplified my test case into: struct test { const char *name; /* full name */ char a; /* symbol */ signed char b; unsigned short c; /* creation/c mask value */ }; extern struct test tab[]; /* the master list of tabter types */ void bar(unsigned short); int main(void) { int i; for (i=0;i<128;i++) if(tab[i].b) bar(tab[i].c); } The compiler loads tab[i].b and, to do so, loads up the address of &tab[i].b. Then, when it wants to pass the value of tab[i].c it tries to do a ldhu r5, 1(r10) which is wrong in our case. Because it is loading a HI, the offset must be a multiple of 2. It so happens that currently the problem is arrising when considering this RTX (insn:HI 77 76 124 struct2.c:17 (set (reg:DI 8 r8) (sign_extend:DI (mem:HI (plus:DI (reg:DI 48 r48 [orig:134 ivtmp.19 ] [134]) (const_int 1 [0x1])) [0 S2 A16]))) 61 {extendhidi2_cyc64} (nil)) Am I wrong to think that, in this case, GO_IF_LEGITIMATE_ADDRESS would not help? On my architecture, we actually have a scratch register we can use. I'm thinking of using a define_peephole2 to correct this as a later pass, taking the address and moving it into a register thus getting a 0 offset. I just feel that is so ugly, there should be a way to tell GCC that a mem cannot be defined with: (mem:HI (plus:DI (reg:DI 48 r48 [orig:134 ivtmp.19 ] [134]) (const_int 1 [0x1])) [0 S2 A16]))) 61 {extendhidi2_cyc64} (nil)) in the case of a HI because of the constant (and then same for SI/DI of course). Thanks again for your help, and I will continue looking into this, Jc On Tue, Jun 9, 2009 at 6:36 PM, Dave Korn<dave.korn.cyg...@googlemail.com> wrote: > Jean Christophe Beyler wrote: >> Dear all, >> >> I've moved forward on this issue. Again, the problem is not that the >> data is not aligned but that the compiler tries to generate this >> instruction: >> >> (set (reg:HI 141) (mem/s/j:HI (plus:DI (reg:DI 134 [ ivtmp.23 ]) >> (const_int 1 [0x1])) [0 <variable>.geno+0 S2 A16])) >> >> And, in my target architecture, this is not authorized. I want to >> transform this into: >> >> (set (reg:DI 135) (plus:DI (reg:DI 134 [ ivtmp.23 ]) >> (const_int 1 [0x1])) [0 <variable>.geno+0 S2 A16])) >> (set (reg:HI 141) (mem/s/j:HI (reg:DI 135)) >> >> >> I've tried playing with define_expand, I can detect this problem, I >> can emit my first move and then the second but for some reason, the >> compiler reassembles them back together. >> >> Any ideas why I am getting that? Am I doing anything wrong? After I >> expand this, I use the DONE macro... > > > How about forbidding the form you don't allow in GO_IF_LEGITIMATE_ADDRESS? > > cheers, > DaveK >