http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52483
Oleg Endo <olegendo at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |olegendo at gcc dot gnu.org --- Comment #2 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-09-17 23:05:23 UTC --- (In reply to comment #1) > (In reply to comment #0) > > Maybe a few peepholes would help here? > > Sure. Peephole looks to be reasonable for this. I've investigated a little bit regarding this issue. First I tried to beat it with peepholes, but the actual problem is that in the load/store expanders the predicates use the 'nonimmediate_operand' and/or 'general_operand' functions from recog.c, which reject volatile mems, because its 'volatile_ok' var is '0' during RTL expansion. As a consequence, only simple single-register addressing modes are allowed for volatile mems. Except for displacement address modes, since those have explicit mem patterns, which would match during expansion. In recog.c there is a comment: /* Nonzero means allow operands to be volatile. This should be 0 if you are generating rtl, such as if you are calling the functions in optabs.c and expmed.c (most of the time). This should be 1 if all valid insns need to be recognized, such as in reginfo.c and final.c and reload.c. init_recog and init_recog_no_volatile are responsible for setting this. */ int volatile_ok; And in function.c: void expand_function_start (tree subr) { /* Make sure volatile mem refs aren't considered valid operands of arithmetic insns. */ init_recog_no_volatile (); If that is the only reason for rejecting volatile mems, then I think it would be OK to match volatile mems in the load/store expanders for SH, since there are no arithmetic insns that take mems anyway (except for some GBR byte mem modification insns, which aren't used in the backend). Kaz, does this make sense?