https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105682

--- Comment #8 from sagebar at web dot de ---
(In reply to Jan Hubicka from comment #6)
> I think the conlcusion here is correct.  callee has pure attribute and that
> means that it has no side effects except for reading global memory. So
> whatever volatile assembly does has to satisfy this.
> 
> Now since assembly is not declared as reading memory, GCC concludes that the
> function has no side effects and does not read global memory and this can be
> uprgraded to const.

This assumes that reading memory is the only thing inline assembly can do to
access (part of) the global state. But consider the following example where the
ARM FPU control word is read:

```
#include <fpu_control.h> // HINT: this is arm assembly
//#define _FPU_GETCW(cw) __asm__ __volatile__("vmrs %0, fpscr" : "=r" (cw))
//#define _FPU_SETCW(cw) __asm__ __volatile__("vmsr fpscr, %0" : : "r" (cw))

__attribute__((pure))
fpu_control_t getcw() {
        fpu_control_t result;
        _FPU_GETCW(result);
        return result;
}

int main() {
        fpu_control_t before, after;
        before = getcw();
        _FPU_SETCW(0x1234);
        after = getcw()
        printf("oldcw: %d\n", before);
        printf("newcw: %d\n", after);
}
```

If you're saying that a `__asm__ __volatile__` that doesn't access memory
should be considered as `const`, then gcc should be allowed to remove the first
`getcw()` and simply assign the same value to `before` and `after` (since a
`const` function's return value only depends on its arguments, meaning it calls
can be removed and re-ordered however gcc pleases).

I think you can see how that would be a problem in the above.

However: I would understand gcc doing this if `_FPU_GETCW` was implemented
using `__asm__` instead of `__asm__ __volatile__`.

(If I'm misunderstanding how `pure` is meant to work, please correct me. But as
far as I understand it, the above is a correct usage examle)

Reply via email to