public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug rtl-optimization/109930] New: transform atomic exchange to unconditional store when old value is unused?
@ 2023-05-22 10:49 Simon.Richter at hogyros dot de
  2023-05-22 12:38 ` [Bug rtl-optimization/109930] " rguenth at gcc dot gnu.org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Simon.Richter at hogyros dot de @ 2023-05-22 10:49 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 109930
           Summary: transform atomic exchange to unconditional store when
                    old value is unused?
           Product: gcc
           Version: 13.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Simon.Richter at hogyros dot de
  Target Milestone: ---

I'm not sure if that is a valid substitution, but...

I have a state machine that has a few transitions where I already know the old
state, so I can simply do an unconditional store, but I'd also like to have an
assertion on the old state in my debug version:

    std::atomic<uint32_t> x;

    /* ... */

    auto old_value = x.exchange(5);
    assert(old_value == 3);

with NDEBUG set, the assert is omitted, and no one is interested in the old
value, so the load-with-reserve can be omitted and the store-conditional
replaced with a regular store, and this should still be semantically
equivalent.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug rtl-optimization/109930] transform atomic exchange to unconditional store when old value is unused?
  2023-05-22 10:49 [Bug rtl-optimization/109930] New: transform atomic exchange to unconditional store when old value is unused? Simon.Richter at hogyros dot de
@ 2023-05-22 12:38 ` rguenth at gcc dot gnu.org
  2023-05-22 15:31 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-05-22 12:38 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Can you proivde a testcase that can be compiled?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug rtl-optimization/109930] transform atomic exchange to unconditional store when old value is unused?
  2023-05-22 10:49 [Bug rtl-optimization/109930] New: transform atomic exchange to unconditional store when old value is unused? Simon.Richter at hogyros dot de
  2023-05-22 12:38 ` [Bug rtl-optimization/109930] " rguenth at gcc dot gnu.org
@ 2023-05-22 15:31 ` pinskia at gcc dot gnu.org
  2023-05-22 17:55 ` Simon.Richter at hogyros dot de
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-05-22 15:31 UTC (permalink / raw)
  To: gcc-bugs

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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Target|                            |!i*86-* & !x86_64-*
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2023-05-22
           Keywords|                            |missed-optimization
             Status|UNCONFIRMED                 |NEW
           Severity|normal                      |enhancement

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Testcase:
```
#include <atomic>

std::atomic<uint32_t> x;
void f()
{
  auto old_value = x.exchange(5);
  (void)old_value;
}

void f0()
{
   x = 5;
}
```

Note on x86_64, these produce the same code generation anyways.
Though on aarch64, it does produce different code. 

I have a suspicion this was reported against x86_64 originally thinking these
two might produce different code generation ...

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug rtl-optimization/109930] transform atomic exchange to unconditional store when old value is unused?
  2023-05-22 10:49 [Bug rtl-optimization/109930] New: transform atomic exchange to unconditional store when old value is unused? Simon.Richter at hogyros dot de
  2023-05-22 12:38 ` [Bug rtl-optimization/109930] " rguenth at gcc dot gnu.org
  2023-05-22 15:31 ` pinskia at gcc dot gnu.org
@ 2023-05-22 17:55 ` Simon.Richter at hogyros dot de
  2023-05-31 17:29 ` wilco at gcc dot gnu.org
  2023-06-01  1:40 ` Simon.Richter at hogyros dot de
  4 siblings, 0 replies; 6+ messages in thread
From: Simon.Richter at hogyros dot de @ 2023-05-22 17:55 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Simon Richter <Simon.Richter at hogyros dot de> ---
I was looking at ARMv7 initially.

If I understood the implementation correctly, this can be a generic
optimization.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug rtl-optimization/109930] transform atomic exchange to unconditional store when old value is unused?
  2023-05-22 10:49 [Bug rtl-optimization/109930] New: transform atomic exchange to unconditional store when old value is unused? Simon.Richter at hogyros dot de
                   ` (2 preceding siblings ...)
  2023-05-22 17:55 ` Simon.Richter at hogyros dot de
@ 2023-05-31 17:29 ` wilco at gcc dot gnu.org
  2023-06-01  1:40 ` Simon.Richter at hogyros dot de
  4 siblings, 0 replies; 6+ messages in thread
From: wilco at gcc dot gnu.org @ 2023-05-31 17:29 UTC (permalink / raw)
  To: gcc-bugs

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

Wilco <wilco at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |wilco at gcc dot gnu.org

--- Comment #4 from Wilco <wilco at gcc dot gnu.org> ---
(In reply to Simon Richter from comment #3)
> I was looking at ARMv7 initially.
> 
> If I understood the implementation correctly, this can be a generic
> optimization.

This optimization is only valid for release or relaxed semantics, otherwise you
remove the acquire semantics of the exchange (without proof this is 100% safe,
this will likely allow an illegal reordering).

Btw if you know the old state then there is presumably no concurrent access
here and so you don't need atomic, let alone sequential consistency.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug rtl-optimization/109930] transform atomic exchange to unconditional store when old value is unused?
  2023-05-22 10:49 [Bug rtl-optimization/109930] New: transform atomic exchange to unconditional store when old value is unused? Simon.Richter at hogyros dot de
                   ` (3 preceding siblings ...)
  2023-05-31 17:29 ` wilco at gcc dot gnu.org
@ 2023-06-01  1:40 ` Simon.Richter at hogyros dot de
  4 siblings, 0 replies; 6+ messages in thread
From: Simon.Richter at hogyros dot de @ 2023-06-01  1:40 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Simon Richter <Simon.Richter at hogyros dot de> ---
> Btw if you know the old state then there is presumably no concurrent access here and so you don't need atomic, let alone sequential consistency.

I know it in some, but not all cases.

Basically, what I do is

        auto old_x = x.load();

    retry:
        switch(old_x) {
        case 1:
            if(!x.compare_exchange_weak(old_x, 2))
                 goto retry;
            stop_timer();
            old_x = x.exchange(4);
            assert(old_x == 2);
            break;
        case 2:
            // we must have preempted another instance of this function
            // do nothing
            break;
        case 3:
            // handle timeout
            ...
            break;
        case 4:
            // handle operation complete
            ...
        }

This is in code for timeout handling in a realtime system, the timer interrupt
can preempt this. State 1 is "operation in progress", state 2 is "operation
finished", state 3 is "operation timed out", and state 4 is "operation finished
and timer stopped", and the timer interrupt will try to switch from 1 to 3.

The transient state 2 then solves the race between the timer expiring and
stopping the timer (which is asynchronous because the interrupt controller has
a few cycles delay).

So the switch from state 2 to state 4 has release semantics.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-06-01  1:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-22 10:49 [Bug rtl-optimization/109930] New: transform atomic exchange to unconditional store when old value is unused? Simon.Richter at hogyros dot de
2023-05-22 12:38 ` [Bug rtl-optimization/109930] " rguenth at gcc dot gnu.org
2023-05-22 15:31 ` pinskia at gcc dot gnu.org
2023-05-22 17:55 ` Simon.Richter at hogyros dot de
2023-05-31 17:29 ` wilco at gcc dot gnu.org
2023-06-01  1:40 ` Simon.Richter at hogyros dot de

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).