>> (insn 5559 5558 5560 694 pp_pack.c:2144 (set (reg:SI 1421) >> (plus:SI (subreg:SI (reg:QI 1420) 0) >> (const_int -32 [0xffffffe0]))) 121 {*addsi3_5200} (insn_list >> 5558 (nil)) >> (nil)) > >So register 1420 is being assigned to a data register. The >constraints for addsi3_5200 permit the following alternatives: > mem += datareg > addrreg = addrreg + reg|constant > addrreg = reg|constant + addrreg > reg += mem|reg|constant >There is no alternative which permits adding a data register and a >constant and putting the result in an address register. So reload >picks the alternative "addrreg = addrreg + reg|constant", and decides >to reload register 1420 into an address register. But that fails >because reload can't find an address register which can accept a >QImode value.
Would it help to rearrange the constraints to have reg += mem|reg|constant before the addreg += ... ? >Looking at the dump a little more, it's far from clear why register >1421 is being put into an address register. I see that insn 5560 >wants to compare a byte value which it finds there, so it doesn't seem >like a good fit to put 1421 into an address register. > > >I don't know where else register 1421 is being used, so my tentative >guess would be that gcc is picking an address register based on the >constraints in addsi3_5200. Perhaps you need to change "?a" to "*a". >After all, you probably don't want to encourage pseudos to go into the >address registers merely because you add values to them. 1421 is only used in 5559 and 5560. from the lreg dump: Register 1421 used 2 times across 2 insns in block 694; set 1 time; pref DATA_REGS. >But it is also possible that register 1421 is being put into an >address register merely because all the data registers are taken and >there is nothing which forces 1421 to be in a data register. In the function S_unpack_rec, there are 190 registers to allocate, so I'd guess everything will be in use. >Or, you might permit an alternative "a a*r rJK" in addsi3_5200. You >can implement that using a two instruction sequence--copy the data >register to the address register, and then add. This is obviously not >ideal, but it's more or less what reload would be doing anyhow. > > >In general, though, I'm not sure that prohibiting QImode values in >address registers is going to be a useful approach. After all, the >values do fit there, and while we want to discourage it, it's not >obvious that we want to completely prohibit it. The problem in PR >18421 is that reload decided that it had to reload a QImode value from >memory into an address register, but it couldn't. That is more or >less easy to handle by defining SECONDARY_RELOAD_CLASS to indicate >that a data register is required to move QImode values between the >address registers and memory, and by defining reload_inqi and >reload_outqi to do the moves. The problem is that there is no valid QImode instruction that can move values in/out of an address register.... This has been an ongoing problem for more than a year, and each "fix" treats the particular bug/problem at hand. rth is the one who recommended punting QImode out of address registers: http://gcc.gnu.org/ml/gcc/2003-07/msg00743.html Looking over the code, I see that PREFERRED_RELOAD_CLASS is: #define PREFERRED_RELOAD_CLASS(X,CLASS) \ ((GET_CODE (X) == CONST_INT \ && (unsigned) (INTVAL (X) + 0x80) < 0x100 \ && (CLASS) != ADDR_REGS) \ ? DATA_REGS \ : (GET_MODE (X) == QImode && (CLASS) != ADDR_REGS) \ ? DATA_REGS \ : (GET_CODE (X) == CONST_DOUBLE \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \ ? ((TARGET_68881|TARGET_CFV4E) && (CLASS == FP_REGS || CLASS == DATA_OR_FP_REGS) \ ? FP_REGS : NO_REGS) \ : (TARGET_PCREL \ && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \ || GET_CODE (X) == LABEL_REF)) \ ? ADDR_REGS \ : (CLASS)) Which looks like it allows QImode into ADDR_REGS instead of insisting on DATA_REGS. Do you think this should be: #define PREFERRED_RELOAD_CLASS(X,CLASS) \ (((GET_CODE (X) == CONST_INT \ && (unsigned) (INTVAL (X) + 0x80) < 0x100) \ || GET_MODE(X) == QImode) \ ? DATA_REGS \ : (GET_CODE (X) == CONST_DOUBLE \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \ ? ((TARGET_68881|TARGET_CFV4E) && (CLASS == FP_REGS || CLASS == DATA_OR_FP_REGS) \ ? FP_REGS : NO_REGS) \ : (TARGET_PCREL \ && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \ || GET_CODE (X) == LABEL_REF)) \ ? ADDR_REGS \ : (CLASS)) -- Peter Barada [EMAIL PROTECTED]