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

Reply via email to