Richard Guenther wrote: > On Thu, Dec 1, 2011 at 10:40 PM, Georg-Johann Lay wrote: >> Ian Lance Taylor wrote: >> >>> Georg-Johann Lay writes: >>> >>>> If general_operand can be perceived as >>>> >>>> (define_predicate "general_operand" >>>> (ior (match_operand 0 "memory_operand") >>>> (match_operand 0 "register_operand") >>>> (match_operand 0 "immediate_operand"))) >>>> >>>> how can low_io_mem ever match? >>> >>> >>> Oh, I see, I did misunderstand your question. Sorry about that. >>> >>> In general combine is just going to honor what your backend is asking >>> for. If your backend says that it is OK to combine a volatile memory >>> operand, then that is what combine is going to do. >> >> Supplying an insn is the backend's way of telling that it is capable of >> performing a specific operation. >> >> In the present case, the backend tells that it has a "Conditional Jump >> depending on a bit in the I/O area". >> >> It does *not* say "It is ok to infringe volatile correctness" and move one >> volatile memory access across an other one or similar memory annotation like >> memory clobber by means of inline assembly or built-in barrier. >> >> >>> It's certainly OK in >>> general to combine across a volatile memory operand, as is happening >>> here. I guess you are asking whether combine should have another check: >>> if some operand in the insn is a volatile MEM, and it will cross a >>> volatile MEM not mentioned in the combine, should combine reject that >>> combination. >> >> It's never correct to exchange volatile accesses. > > That's not true. volatile accesses to different memory locations > have no special dependence. If it happens that GCC doesn't > do this kind of things then this is only because most passes > don't thouch volatile stmts at all (thus the reports for sub-optimal > code with volatile - we don't even try to do legal transformations). > > Richard.
Disagree. If A and B are two different volatile memory locations, then: Writing or even reading A might change B. A common case where reading A induces changes is reading a latch. A common case where writing A also affects B is if A controls hardware configuration of a module like hardware port, I/O module or internal hardware like hardware timer, PLL, VCO, WDT or whatever. If you change the I/O setup of a port from high-Z to pullup or pulldown or push-pull by writing its configuration register A, you will see port registers B react and change their values. Just as Paul Koning did say: exchange accessing A and B is wrong in general. Or look at software where different tasks synchronize themselves using locks or semaphores to communicate. If A says "data in B is ready for consumption" and you exchange A and B you really have a problem. Johann