On Fri, Jan 23, 2015 at 03:39:40PM -0600, Segher Boessenkool wrote:
> I understand that argument.  But it is not what GCC actually does, nor
> what I think it should do.  Consider this program:
> 
> --- 8< ---
> int main(void)
> {
>       int x[100], y[100];
> 
>       x[31] = 42;
> 
>       asm("# eww %0" : "=m"(y[4]) : : "memory");
> 
>       return 0;
> }
> --- 8< ---

Here x isn't addressable, so it is certainly fine to DSE it.
x shouldn't be considered memory.
If the address of x escaped, either to the assembly or to some global var
etc., then it probably shouldn't be removed.

> Here is another program:
> 
> --- 8< ---
> int main(void)
> {
>       int x;
> 
>       asm("# eww %0" : "=r"(x) : : "memory");
>       asm("# eww %0" : "=r"(x) : : "memory");
> 
>       return x;
> }
> --- 8< ---
> 
> If "memory" would imply a write and a read, the identical asm here could
> not be CSEd.  But it is.

Certainly not in GCC 4.9 nor trunk.  I've committed the patch because it
makes GCC more aggressive again, just not for the "memory" case.
In case of two idential non-volatile asms with "memory" clobber,
if there are no intervening memory reads or writes, we can talk about
allowing that to be CSEd despite "memory" being considered unspecified
read and write.  If there are stores in between, we certainly should not CSE.

        Jakub

Reply via email to