------- Comment #3 from uweigand at gcc dot gnu dot org 2006-05-22 13:27 ------- Looking somewhat more into this problem, there are other places where reload decides to reload an CONST_INT as address. Where this happens, it usually uses Pmode as the mode to do the reload in (which makes sense as Pmode should always be valid as the mode of an address).
Look e.g. at the various call sites of find_reloads_address_part. However, at the place where the decision to reload a valid address due to and EXTRA_MEMORY_CONSTRAINT or 'o' constraint is made, this special treatment of VOIDmode constants is missing. However, it looks to me that this was simply an oversight here. Thus, I'd propose something like the following patch (as of right now completely untested) to replace VOIDmode by Pmode at that place too. This should fix the problem. Index: gcc/reload.c =================================================================== *** gcc/reload.c (revision 113828) --- gcc/reload.c (working copy) *************** find_reloads (rtx insn, int replace, int *** 3854,3864 **** && goal_alternative_offmemok[i] && MEM_P (recog_data.operand[i])) { operand_reloadnum[i] = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX, &XEXP (recog_data.operand[i], 0), (rtx*) 0, base_reg_class (VOIDmode, MEM, SCRATCH), ! GET_MODE (XEXP (recog_data.operand[i], 0)), VOIDmode, 0, 0, i, RELOAD_FOR_INPUT); rld[operand_reloadnum[i]].inc = GET_MODE_SIZE (GET_MODE (recog_data.operand[i])); --- 3854,3872 ---- && goal_alternative_offmemok[i] && MEM_P (recog_data.operand[i])) { + /* If the address to be reloaded is a VOIDmode constant, + use Pmode as mode of the reload register, as would have + been done by find_reloads_address. */ + enum machine_mode address_mode; + address_mode = GET_MODE (XEXP (recog_data.operand[i], 0)); + if (address_mode == VOIDmode) + address_mode = Pmode; + operand_reloadnum[i] = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX, &XEXP (recog_data.operand[i], 0), (rtx*) 0, base_reg_class (VOIDmode, MEM, SCRATCH), ! address_mode, VOIDmode, 0, 0, i, RELOAD_FOR_INPUT); rld[operand_reloadnum[i]].inc = GET_MODE_SIZE (GET_MODE (recog_data.operand[i])); I'll test the patch and propose it on gcc-patches if it works out. Could you verify this patch helps with your original testcase? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27661