public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "torvald at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug middle-end/59448] Code generation doesn't respect C11 address-dependency
Date: Thu, 23 Jan 2014 22:28:00 -0000	[thread overview]
Message-ID: <bug-59448-4-r5EvUtpHdy@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-59448-4@http.gcc.gnu.org/bugzilla/>

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59448

torvald at gcc dot gnu.org changed:

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

--- Comment #10 from torvald at gcc dot gnu.org ---
(In reply to algrant from comment #6)
> Here is a complete C++11 test case.  The code generated for the two loads
> in thread B doesn't maintain the required ordering:

The C++ test has a race condition because the nonatomic load from data is not
ordered wrt. the nonatomic store to data in the other thread.  Please fix that
and report back whether this changes anything.  (I believe the use of
relaxed-MO atomic accesses should be sufficient.)

Nonetheless, if there is a fixed (data-race-free) similar test, then I believe
this fixed test case to be valid in the sense that AFAIU the standards'
requirements (both C++11's and C11's; they are equal in this aspect), code as
in this test case is supposed to be carrying the dependencies forward.

However, I cannot see a *practical* implementation of this requirement.  AFAIU,
dependencies are carried forward through loads/stores too (5.1.2.4#14):
"An evaluation A carries a dependency to an evaluation B if: [...]A writes a
scalar object or bit-field M, B reads from M the value written by A, and A is
sequenced before B".
Because a compiler cannot, in general, analyze which piece of code stored last
to M, it would have to conservatively assume that a dependency is carried
through M.  In turn, it could never optimize expressions such as "(x-x)", at
least if those affect atomic operations on M in some way, irrespective of how
remotely that might have happened.  (I'm restricting my statement to atomic
accesses because I'm not quite sure whether there's some other reason why
nonatomic accesses couldn't be affected by this.)  OTOH, maybe there are
factors that I'm not aware of and that effectively constrain
carries-a-dependency to something that doesn't widely prohibit optimizations.

I don't have significant background information on the design of this part of
the memory model (nor the implementability of this part), but I'll ask around
at the C++ meeting in two weeks.

> According to the architecture specification, to achieve the ordering it's
> sufficient to use the result of the first load in the calculation of the
> address of the second, even if it's done in such a way as to have no
> dependence on the value.

And that's certainly a feasible *architecture* specification.  ISTM that the
language standard tried to model this, but then didn't give the compiler enough
leeway to still be able to optimize code.  The carries-a-depency rules seem
like an unusual shortcut from the language level to requirements on the
generated code, without the usual indirection using the observable behavior of
the abstract machine and as-if.  For example -- and this isn't a precise
definition of course -- if the standard would require that "f" (in your test
case) is needed to process the evaluation, then things like "f-f" could be
optimized out, and the compiler might just do the right thing with standard
optimizations.

As a short-term fix, I believe we can promote all memory_order_consume atomics
to memory_order_acquire, when generating code with consume-MO atomics.  GCC is
at fault here, not the code in the builtins or in libatomic.  Thus, this would
prevent errors when GCC compiled the code and a correct atomics implementation
is used (e.g., third-party libatomic).

This won't help when another (potentially correct) compiler generated the code
with the consume-MO atomics, and GCC-compiled code fails to carry the
dependencies forward.  We could try to change libatomic's consume-MO
implementation to prevent that, but this would any catch cases in which
libatomic is actually used and not the other compiler's builtins or similar. 
Thus, changing libatomic does not seem to be necessary.

Richard, Andrew: Thoughts?


  parent reply	other threads:[~2014-01-23 22:28 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-10 12:07 [Bug target/59448] New: ARM code " algrant at acm dot org
2013-12-10 14:19 ` [Bug c/59448] Code " rearnsha at gcc dot gnu.org
2013-12-10 16:43 ` algrant at acm dot org
2013-12-10 17:47 ` joseph at codesourcery dot com
2013-12-12 18:07 ` [Bug middle-end/59448] " algrant at acm dot org
2013-12-16 14:38 ` joseph at codesourcery dot com
2014-01-20  8:52 ` algrant at acm dot org
2014-01-20  9:02 ` pinskia at gcc dot gnu.org
2014-01-20 10:13 ` algrant at acm dot org
2014-01-20 14:21 ` joseph at codesourcery dot com
2014-01-23 22:28 ` torvald at gcc dot gnu.org [this message]
2014-02-17 10:26 ` algrant at acm dot org
2014-02-17 21:03 ` torvald at gcc dot gnu.org
2014-02-17 22:22 ` algrant at acm dot org
2014-10-28 10:56 ` ramana at gcc dot gnu.org
2014-10-28 12:48 ` amacleod at redhat dot com
2014-10-28 13:43 ` joseph at codesourcery dot com
2014-10-28 17:37 ` t.p.northover at gmail dot com
2014-10-29  1:48 ` joseph at codesourcery dot com
2014-10-29  9:23 ` torvald at gcc dot gnu.org
2014-10-30 21:08 ` torvald at gcc dot gnu.org
2014-10-30 22:16 ` filter-gcc at preshing dot com
2014-11-24 12:13 ` filter-gcc at preshing dot com
2015-01-14 13:59 ` amacleod at redhat dot com
2022-01-15  1:47 ` pinskia at gcc dot gnu.org
2022-01-15  1:53 ` pinskia at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-59448-4-r5EvUtpHdy@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).