public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [gimple] assignments to volatile
@ 2010-06-21 12:44 Nathan Sidwell
  2010-06-21 13:26 ` Richard Guenther
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-21 12:44 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1320 bytes --]

I've come across inconsistent and surprising behaviour when assigning to 
volatile lvalues.

Sometimes we re-read the assigned-to object, and sometimes we do not.  For instance,
    return vobj = data;
will cause a reread of vobj, IF data is not a constant.
or
   cond ? vobj = data : 0
will cause a reread of vobj, even when we don't use the result of the 
conditional expression -- unless data is a constant, in which case there is 
no-reread.  (And confusingly, if you put void casts inside the two conditional 
sub-expressions, the re-reading goes away, but it doesn't even when you 
explicitly cast the whole expression to void).

In the attached testcase, test_1, test_6 and test_7 have this surprising 
rereading behaviour.

The fault appears to be in gimplify_modify_expr, where we return the LHS as the 
value, if the caller wants the value.  The attached patch changes that routine 
when the target lvalue is volatile.  In that case it will create a temporary to 
hold the RHS value, assign that temporary to the LHS and then return the temporary.

Although the bug is architecture-neutral, the testcase is x86-specific because 
it's checking for specific accesses occurring.

built and tested on i686-pc-linux-gnu, ok?

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery


[-- Attachment #2: volatile.patch --]
[-- Type: text/x-patch, Size: 4198 bytes --]

2010-06-21  Nathan Sidwell  <nathan@codesourcery.com>

	gcc/
	* gimplify.c (gimplify_modify_expr): When assigning to volatiles,
	copy the src value and return a copy.

	gcc/testsuite/
	* gcc.target/i386/volatile-2.c: New.

Index: gimplify.c
===================================================================
--- gimplify.c	(revision 160876)
+++ gimplify.c	(working copy)
@@ -4467,6 +4467,28 @@
   gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
 	      || TREE_CODE (*expr_p) == INIT_EXPR);
 
+  if (want_value && TREE_THIS_VOLATILE (TREE_TYPE (*to_p)))
+    {
+      /* copy the rhs to a temporary, store the temporary and then
+         return it.  This makes sure we consistently do not re-read a
+         volatile just after storing it.  */
+      tree lhs = *to_p;
+      tree rhs = *from_p;
+      tree nv_type = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
+      tree tmp = create_tmp_var (nv_type, "modtmp");
+      tree tmp_ass = build2 (MODIFY_EXPR, nv_type, tmp, rhs);
+      tree vol_ass = build2 (MODIFY_EXPR, nv_type, lhs, tmp);
+      
+      recalculate_side_effects (tmp_ass);
+      gimplify_and_add (tmp_ass, pre_p);
+
+      recalculate_side_effects (vol_ass);
+      gimplify_and_add (vol_ass, pre_p);
+
+      *expr_p = tmp;
+      return GS_OK;
+    }
+  
   /* Insert pointer conversions required by the middle-end that are not
      required by the frontend.  This fixes middle-end type checking for
      for example gcc.dg/redecl-6.c.  */
Index: testsuite/gcc.target/i386/volatile-2.c
===================================================================
--- testsuite/gcc.target/i386/volatile-2.c	(revision 0)
+++ testsuite/gcc.target/i386/volatile-2.c	(revision 0)
@@ -0,0 +1,92 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* Check volatiles are written, read or not re-read consistently */
+
+
+/* simple assignments */
+
+extern int volatile obj_0;
+void test_0 (int data)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_0" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_0," } } */
+  obj_0 = data;
+}
+
+extern int volatile obj_1;
+int test_1 (int data)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_1" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_1," } } */
+  return obj_1 = data;
+}
+
+extern int volatile obj_2;
+int test_2 (void)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_2" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_2," } } */
+  return obj_2 = 0;
+}
+
+
+/* Assignments in compound exprs */
+
+extern int volatile obj_3;
+int test_3 (int data)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_3" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_3," } } */
+  return (obj_3 = data, 0);
+}
+
+extern int volatile obj_4;
+int test_4 (void)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_4" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_4," } } */
+  return (obj_4 = 0, 0);
+}
+extern int volatile obj_5;
+int test_5 (void)
+{
+  /* should reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_5" } } */
+  /* { dg-final { scan-assembler "movl\[ \t\]obj_5," } } */
+  return (obj_5 = 0, obj_5);
+}
+
+/* Assignments in conditional exprs */
+
+extern int volatile obj_6;
+void test_6 (int data, int cond)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_6" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_6," } } */
+  cond ? obj_6 = data : 0;
+}
+
+extern int volatile obj_7;
+int test_7 (int data, int cond)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_7" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_7," } } */
+  return cond ? obj_7 = data : 0;
+}
+
+extern int volatile obj_8;
+int test_8 (int cond)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_8" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_8," } } */
+  return cond ? obj_8 = 0 : 0;
+}

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

* Re: [gimple] assignments to volatile
  2010-06-21 12:44 [gimple] assignments to volatile Nathan Sidwell
@ 2010-06-21 13:26 ` Richard Guenther
  2010-06-21 13:55   ` Michael Matz
  2010-06-22 12:08   ` Nathan Sidwell
  0 siblings, 2 replies; 81+ messages in thread
From: Richard Guenther @ 2010-06-21 13:26 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On Mon, Jun 21, 2010 at 1:56 PM, Nathan Sidwell <nathan@codesourcery.com> wrote:
> I've come across inconsistent and surprising behaviour when assigning to
> volatile lvalues.
>
> Sometimes we re-read the assigned-to object, and sometimes we do not.  For
> instance,
>   return vobj = data;
> will cause a reread of vobj, IF data is not a constant.
> or
>  cond ? vobj = data : 0
> will cause a reread of vobj, even when we don't use the result of the
> conditional expression -- unless data is a constant, in which case there is
> no-reread.  (And confusingly, if you put void casts inside the two
> conditional sub-expressions, the re-reading goes away, but it doesn't even
> when you explicitly cast the whole expression to void).
>
> In the attached testcase, test_1, test_6 and test_7 have this surprising
> rereading behaviour.
>
> The fault appears to be in gimplify_modify_expr, where we return the LHS as
> the value, if the caller wants the value.  The attached patch changes that
> routine when the target lvalue is volatile.  In that case it will create a
> temporary to hold the RHS value, assign that temporary to the LHS and then
> return the temporary.
>
> Although the bug is architecture-neutral, the testcase is x86-specific
> because it's checking for specific accesses occurring.
>
> built and tested on i686-pc-linux-gnu, ok?

Hm, TREE_THIS_VOLATILE (TREE_TYPE (*to_p)) should
certainly be TREE_THIS_VOLATILE (*to_p), and all this
should be done after gimplifying *to_p.  I think even just
before we build the gimple assign/call do

if (TREE_THIS_VOLATILE (*to_p) && want_value)
  *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);

and change

  if (want_value)
    {
      *expr_p = unshare_expr (*to_p);
      return GS_OK;

to

  if (want_value)
    {
      *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
      return GS_O;

Richard.

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

* Re: [gimple] assignments to volatile
  2010-06-21 13:26 ` Richard Guenther
@ 2010-06-21 13:55   ` Michael Matz
  2010-06-21 14:07     ` Richard Guenther
                       ` (3 more replies)
  2010-06-22 12:08   ` Nathan Sidwell
  1 sibling, 4 replies; 81+ messages in thread
From: Michael Matz @ 2010-06-21 13:55 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Nathan Sidwell, GCC Patches

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1748 bytes --]

Hello,

On Mon, 21 Jun 2010, Richard Guenther wrote:

> > I've come across inconsistent and surprising behaviour when assigning 
> > to volatile lvalues.
> >
> > Sometimes we re-read the assigned-to object, and sometimes we do not.  For
> > instance,
> >   return vobj = data;
> > will cause a reread of vobj, IF data is not a constant.

I'd consider the latter condition a bug.  I.e. the rereading must happen 
in every case.  It must happen because in C the value of "lhs = rhs" is 
that of reading 'lhs' ("An assignment expression has the value of the left 
operand after the assignment, but is not an lvalue." 6.5.16), and if lhs 
happens to be volatile than the abstract machine implies two accesses to 
lhs, one write (of the assignment) and one read (to get to the value of 
lhs).

> > or
> >  cond ? vobj = data : 0
> > will cause a reread of vobj, even when we don't use the result of the
> > conditional expression -- unless data is a constant, in which case there is
> > no-reread.  (And confusingly, if you put void casts inside the two
> > conditional sub-expressions, the re-reading goes away, but it doesn't even
> > when you explicitly cast the whole expression to void).
> >
> > In the attached testcase, test_1, test_6 and test_7 have this surprising
> > rereading behaviour.
> >
> > The fault appears to be in gimplify_modify_expr, where we return the LHS as
> > the value, if the caller wants the value.  The attached patch changes that
> > routine when the target lvalue is volatile.  In that case it will create a
> > temporary to hold the RHS value, assign that temporary to the LHS and then
> > return the temporary.

... which implies that I think that this is exactly the wrong solution.


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-21 13:55   ` Michael Matz
@ 2010-06-21 14:07     ` Richard Guenther
  2010-06-21 14:09     ` Nathan Sidwell
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 81+ messages in thread
From: Richard Guenther @ 2010-06-21 14:07 UTC (permalink / raw)
  To: Michael Matz; +Cc: Nathan Sidwell, GCC Patches

On Mon, Jun 21, 2010 at 3:30 PM, Michael Matz <matz@suse.de> wrote:
> Hello,
>
> On Mon, 21 Jun 2010, Richard Guenther wrote:
>
>> > I've come across inconsistent and surprising behaviour when assigning
>> > to volatile lvalues.
>> >
>> > Sometimes we re-read the assigned-to object, and sometimes we do not.  For
>> > instance,
>> >   return vobj = data;
>> > will cause a reread of vobj, IF data is not a constant.
>
> I'd consider the latter condition a bug.  I.e. the rereading must happen
> in every case.  It must happen because in C the value of "lhs = rhs" is
> that of reading 'lhs' ("An assignment expression has the value of the left
> operand after the assignment, but is not an lvalue." 6.5.16), and if lhs
> happens to be volatile than the abstract machine implies two accesses to
> lhs, one write (of the assignment) and one read (to get to the value of
> lhs).
>
>> > or
>> >  cond ? vobj = data : 0
>> > will cause a reread of vobj, even when we don't use the result of the
>> > conditional expression -- unless data is a constant, in which case there is
>> > no-reread.  (And confusingly, if you put void casts inside the two
>> > conditional sub-expressions, the re-reading goes away, but it doesn't even
>> > when you explicitly cast the whole expression to void).
>> >
>> > In the attached testcase, test_1, test_6 and test_7 have this surprising
>> > rereading behaviour.
>> >
>> > The fault appears to be in gimplify_modify_expr, where we return the LHS as
>> > the value, if the caller wants the value.  The attached patch changes that
>> > routine when the target lvalue is volatile.  In that case it will create a
>> > temporary to hold the RHS value, assign that temporary to the LHS and then
>> > return the temporary.
>
> ... which implies that I think that this is exactly the wrong solution.

And also implies that the frontend should arrange for what
gets used.

Richard.

>
> Ciao,
> Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-21 13:55   ` Michael Matz
  2010-06-21 14:07     ` Richard Guenther
@ 2010-06-21 14:09     ` Nathan Sidwell
  2010-06-21 14:17       ` Michael Matz
  2010-06-21 14:17     ` IainS
  2010-06-22 15:37     ` Mark Mitchell
  3 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-21 14:09 UTC (permalink / raw)
  To: Michael Matz; +Cc: Richard Guenther, GCC Patches

On 06/21/10 14:30, Michael Matz wrote:

> I'd consider the latter condition a bug.  I.e. the rereading must happen
> in every case.  It must happen because in C the value of "lhs = rhs" is
> that of reading 'lhs' ("An assignment expression has the value of the left
> operand after the assignment, but is not an lvalue." 6.5.16), and if lhs
> happens to be volatile than the abstract machine implies two accesses to
> lhs, one write (of the assignment) and one read (to get to the value of
> lhs).

The subexpression 'vobj = expr' has a value.  Shouldn't there therefore be a 
reread of that value in the expression-statement 'vobj = expr;'?

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-21 13:55   ` Michael Matz
  2010-06-21 14:07     ` Richard Guenther
  2010-06-21 14:09     ` Nathan Sidwell
@ 2010-06-21 14:17     ` IainS
  2010-06-21 14:24       ` Michael Matz
  2010-06-22 15:37     ` Mark Mitchell
  3 siblings, 1 reply; 81+ messages in thread
From: IainS @ 2010-06-21 14:17 UTC (permalink / raw)
  To: Michael Matz; +Cc: Richard Guenther, Nathan Sidwell, GCC Patches


On 21 Jun 2010, at 14:30, Michael Matz wrote:
> On Mon, 21 Jun 2010, Richard Guenther wrote:
>
>>> I've come across inconsistent and surprising behaviour when  
>>> assigning
>>> to volatile lvalues.
>>>
>>> Sometimes we re-read the assigned-to object, and sometimes we do  
>>> not.  For
>>> instance,
>>>   return vobj = data;
>>> will cause a reread of vobj, IF data is not a constant.
>
> I'd consider the latter condition a bug.  I.e. the rereading must  
> happen
> in every case.  It must happen because in C the value of "lhs = rhs"  
> is
> that of reading 'lhs' ("An assignment expression has the value of  
> the left
> operand after the assignment, but is not an lvalue." 6.5.16), and if  
> lhs
> happens to be volatile than the abstract machine implies two  
> accesses to
> lhs, one write (of the assignment) and one read (to get to the value  
> of
> lhs).

that answers the "what" but not the "when".

Suppose that vobj was a hardware register ...

... I would expect that the assignment would write the value of expr  
to the register...

... but I would _not_ expect the register to be re-read (and, indeed,  
in many cases in hardware interaction - that could cause an issue).

or did I miss sth?
Iain

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

* Re: [gimple] assignments to volatile
  2010-06-21 14:09     ` Nathan Sidwell
@ 2010-06-21 14:17       ` Michael Matz
  2010-06-21 14:19         ` Richard Guenther
  0 siblings, 1 reply; 81+ messages in thread
From: Michael Matz @ 2010-06-21 14:17 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Richard Guenther, GCC Patches

Hi,

On Mon, 21 Jun 2010, Nathan Sidwell wrote:

> On 06/21/10 14:30, Michael Matz wrote:
> 
> > I'd consider the latter condition a bug.  I.e. the rereading must happen
> > in every case.  It must happen because in C the value of "lhs = rhs" is
> > that of reading 'lhs' ("An assignment expression has the value of the left
> > operand after the assignment, but is not an lvalue." 6.5.16), and if lhs
> > happens to be volatile than the abstract machine implies two accesses to
> > lhs, one write (of the assignment) and one read (to get to the value of
> > lhs).
> 
> The subexpression 'vobj = expr' has a value.  Shouldn't there therefore be a
> reread of that value in the expression-statement 'vobj = expr;'?

A good question.  I'm very certain that we need a reread for
 "x = (vobj = y);" .
(I even thought we had testcases for this actually happening)
I would find the consequence of also having to reread for "vobj = y;" 
surprising.

There's some leeway in the standard as to what actually constitutes an 
access to a volatile object (implementation-defined), and perhaps we can 
define it to be no (read) access in the second case: The subexpression has 
a value, but the source code doesn't retrieve it, and I think we're free 
to define this non-retrieval to imply no access to the value (and hence to 
vobj).


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-21 14:17       ` Michael Matz
@ 2010-06-21 14:19         ` Richard Guenther
  2010-06-21 14:53           ` Michael Matz
  0 siblings, 1 reply; 81+ messages in thread
From: Richard Guenther @ 2010-06-21 14:19 UTC (permalink / raw)
  To: Michael Matz; +Cc: Nathan Sidwell, GCC Patches

On Mon, Jun 21, 2010 at 4:07 PM, Michael Matz <matz@suse.de> wrote:
> Hi,
>
> On Mon, 21 Jun 2010, Nathan Sidwell wrote:
>
>> On 06/21/10 14:30, Michael Matz wrote:
>>
>> > I'd consider the latter condition a bug.  I.e. the rereading must happen
>> > in every case.  It must happen because in C the value of "lhs = rhs" is
>> > that of reading 'lhs' ("An assignment expression has the value of the left
>> > operand after the assignment, but is not an lvalue." 6.5.16), and if lhs
>> > happens to be volatile than the abstract machine implies two accesses to
>> > lhs, one write (of the assignment) and one read (to get to the value of
>> > lhs).
>>
>> The subexpression 'vobj = expr' has a value.  Shouldn't there therefore be a
>> reread of that value in the expression-statement 'vobj = expr;'?
>
> A good question.  I'm very certain that we need a reread for
>  "x = (vobj = y);" .
> (I even thought we had testcases for this actually happening)
> I would find the consequence of also having to reread for "vobj = y;"
> surprising.
>
> There's some leeway in the standard as to what actually constitutes an
> access to a volatile object (implementation-defined), and perhaps we can
> define it to be no (read) access in the second case: The subexpression has
> a value, but the source code doesn't retrieve it, and I think we're free
> to define this non-retrieval to imply no access to the value (and hence to
> vobj).

The standard also specifies that the value has unqualified type
(whether that matters here or not I am not sure).  So x is assigned
from a non-volatile typed value.

Richard.

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

* Re: [gimple] assignments to volatile
  2010-06-21 14:17     ` IainS
@ 2010-06-21 14:24       ` Michael Matz
  2010-06-21 14:50         ` Nathan Sidwell
  2010-06-21 15:24         ` Nathan Sidwell
  0 siblings, 2 replies; 81+ messages in thread
From: Michael Matz @ 2010-06-21 14:24 UTC (permalink / raw)
  To: IainS; +Cc: Richard Guenther, Nathan Sidwell, GCC Patches

Hi,

On Mon, 21 Jun 2010, IainS wrote:

> > > >  return vobj = data;
> > > >will cause a reread of vobj, IF data is not a constant.
> >
> >I'd consider the latter condition a bug.  I.e. the rereading must happen
> >in every case.  It must happen because in C the value of "lhs = rhs" is
> >that of reading 'lhs' ("An assignment expression has the value of the left
> >operand after the assignment, but is not an lvalue." 6.5.16), and if lhs
> >happens to be volatile than the abstract machine implies two accesses to
> >lhs, one write (of the assignment) and one read (to get to the value of
> >lhs).
> 
> that answers the "what" but not the "when".
> 
> Suppose that vobj was a hardware register ...
> 
> ... I would expect that the assignment would write the value of expr to the
> register...
> 
> ... but I would _not_ expect the register to be re-read (and, indeed, in many
> cases in hardware interaction - that could cause an issue).
> 
> or did I miss sth?

Yes, namely that the author explicitely wrote a read access to vobj.
To demonstrate, like
  return vobj;
implies a read from vobj, also
  return vobj = x;
implies a read from vobj.  The latter _also_ implies a store to vobj.  If 
you want the read to not happen the author better writes
  vobj = x;
  return x;


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-21 14:24       ` Michael Matz
@ 2010-06-21 14:50         ` Nathan Sidwell
  2010-06-21 15:24           ` Michael Matz
  2010-06-21 15:24         ` Nathan Sidwell
  1 sibling, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-21 14:50 UTC (permalink / raw)
  To: Michael Matz; +Cc: IainS, Richard Guenther, GCC Patches

On 06/21/10 15:09, Michael Matz wrote:

> Yes, namely that the author explicitely wrote a read access to vobj.
> To demonstrate, like
>    return vobj;
> implies a read from vobj, also
>    return vobj = x;
> implies a read from vobj.  The latter _also_ implies a store to vobj.  If
> you want the read to not happen the author better writes
>    vobj = x;
>    return x;

Then what about plain
	vobj;
?  Is that a read of vobj?

what about hiding the assignment inside a cond expr
      cond ? vobj = expr : 0;
Is that a re-read of vobj?

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-21 14:19         ` Richard Guenther
@ 2010-06-21 14:53           ` Michael Matz
  0 siblings, 0 replies; 81+ messages in thread
From: Michael Matz @ 2010-06-21 14:53 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Nathan Sidwell, GCC Patches

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1228 bytes --]

Hi,

On Mon, 21 Jun 2010, Richard Guenther wrote:

> >> The subexpression 'vobj = expr' has a value.  Shouldn't there 
> >> therefore be a reread of that value in the expression-statement 'vobj 
> >> = expr;'?
> >
> > A good question.  I'm very certain that we need a reread for  "x = 
> > (vobj = y);" . (I even thought we had testcases for this actually 
> > happening) I would find the consequence of also having to reread for 
> > "vobj = y;" surprising.
> >
> > There's some leeway in the standard as to what actually constitutes an
> > access to a volatile object (implementation-defined), and perhaps we can
> > define it to be no (read) access in the second case: The subexpression has
> > a value, but the source code doesn't retrieve it, and I think we're free
> > to define this non-retrieval to imply no access to the value (and hence to
> > vobj).
> 
> The standard also specifies that the value has unqualified type
> (whether that matters here or not I am not sure).  So x is assigned
> from a non-volatile typed value.

Yes, but I don't think this matters.  In 'int x = (int)vobj;' the value of 
the RHS will also be unqualified, but to get to that value you still have 
to access vobj.


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-21 14:50         ` Nathan Sidwell
@ 2010-06-21 15:24           ` Michael Matz
  2010-06-22 11:36             ` Dave Korn
  2010-06-23 20:16             ` Mike Stump
  0 siblings, 2 replies; 81+ messages in thread
From: Michael Matz @ 2010-06-21 15:24 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: IainS, Richard Guenther, GCC Patches

Hi,

On Mon, 21 Jun 2010, Nathan Sidwell wrote:

> > Yes, namely that the author explicitely wrote a read access to vobj.
> > To demonstrate, like
> >    return vobj;
> > implies a read from vobj, also
> >    return vobj = x;
> > implies a read from vobj.  The latter _also_ implies a store to vobj.  If
> > you want the read to not happen the author better writes
> >    vobj = x;
> >    return x;
> 
> Then what about plain
> 	vobj;
> ?  Is that a read of vobj?

As said, implementation-defined I think.  (I think we should define it to 
be no access, unlike 'x = vobj;' even if x is unused later.).

> what about hiding the assignment inside a cond expr
>      cond ? vobj = expr : 0;
> Is that a re-read of vobj?

If that's the full expression I think we should say that this doesn't 
constitute a read access.  If the above was itself only a subexpression it 
should be a read access, like in 
  x = cond ? vobj = expr : 0; or
  f (cond ? vobj = expr : 0);
(Of course both accesses would only happen if cond is true).

Put probably Joseph will correct me on all points I've made :-)


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-21 14:24       ` Michael Matz
  2010-06-21 14:50         ` Nathan Sidwell
@ 2010-06-21 15:24         ` Nathan Sidwell
  2010-06-21 15:46           ` Michael Matz
  1 sibling, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-21 15:24 UTC (permalink / raw)
  To: Michael Matz; +Cc: IainS, Richard Guenther, GCC Patches

On 06/21/10 15:09, Michael Matz wrote:

> implies a read from vobj, also
>    return vobj = x;
> implies a read from vobj.

Also, doesn't that contradict the sequence-point rules?  We'd have a read and 
write of vobj without an intervening sequence point (and the read was not used 
to determine the to-be-written value).

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-21 15:24         ` Nathan Sidwell
@ 2010-06-21 15:46           ` Michael Matz
  0 siblings, 0 replies; 81+ messages in thread
From: Michael Matz @ 2010-06-21 15:46 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: IainS, Richard Guenther, GCC Patches

Hi,

On Mon, 21 Jun 2010, Nathan Sidwell wrote:

> > implies a read from vobj, also
> >    return vobj = x;
> > implies a read from vobj.
> 
> Also, doesn't that contradict the sequence-point rules?  We'd have a 
> read and write of vobj without an intervening sequence point (and the 
> read was not used to determine the to-be-written value).

I think there's no problem.  We have three side-effects for the above 
expression: two accesses to vobj (one read (1), one write (2)), and the 
modification of object vobj (3).  The separation of the volatile write 
access and the actual modification of value may seem academic, but let's 
follow the letter.  All these side-effects must be complete before the 
next sequence point (we have only one here, the end of full expression), 
which will obviously be the case, no matter if there's side-effect (1) or 
not.

Now, onto 6.5 #2:

  Between the previous and next sequence point an object shall have its 
  stored value modified at most once by the evaluation of an expression. 
  Furthermore, the prior value shall be read only to determine the value 
  to be stored.70)

This talks only about the side-effect of changing the stored value (which 
we do only once) and about the prior value, which we don't use at all.

I.e. I think volatility doesn't enter the picture as far as 6.5. #2 is 
concerned, it rules out the usual pattern of "i=i++ + 1", no matter if i 
is volatile or not.


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-21 15:24           ` Michael Matz
@ 2010-06-22 11:36             ` Dave Korn
  2010-06-23 20:16             ` Mike Stump
  1 sibling, 0 replies; 81+ messages in thread
From: Dave Korn @ 2010-06-22 11:36 UTC (permalink / raw)
  To: Michael Matz; +Cc: Nathan Sidwell, IainS, Richard Guenther, GCC Patches

On 21/06/2010 15:25, Michael Matz wrote:
> Hi,
> 
> On Mon, 21 Jun 2010, Nathan Sidwell wrote:
> 
>>> Yes, namely that the author explicitely wrote a read access to vobj.
>>> To demonstrate, like
>>>    return vobj;
>>> implies a read from vobj, also
>>>    return vobj = x;
>>> implies a read from vobj.  The latter _also_ implies a store to vobj.  If
>>> you want the read to not happen the author better writes
>>>    vobj = x;
>>>    return x;
>> Then what about plain
>> 	vobj;
>> ?  Is that a read of vobj?
> 
> As said, implementation-defined I think.  (I think we should define it to 
> be no access, unlike 'x = vobj;' even if x is unused later.).

  I'm not so sure, that's how people write code to read-and-discard
auto-resetting flag registers in memory mapped hardware.

    cheers,
      DaveK

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

* Re: [gimple] assignments to volatile
  2010-06-21 13:26 ` Richard Guenther
  2010-06-21 13:55   ` Michael Matz
@ 2010-06-22 12:08   ` Nathan Sidwell
  2010-06-22 12:25     ` Richard Guenther
  2010-06-22 13:12     ` Michael Matz
  1 sibling, 2 replies; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-22 12:08 UTC (permalink / raw)
  To: Richard Guenther; +Cc: GCC Patches, Michael Matz

[-- Attachment #1: Type: text/plain, Size: 4028 bytes --]

On 06/21/10 13:07, Richard Guenther wrote:

> Hm, TREE_THIS_VOLATILE (TREE_TYPE (*to_p)) should
> certainly be TREE_THIS_VOLATILE (*to_p), and all this
> should be done after gimplifying *to_p.  I think even just
> before we build the gimple assign/call do
...

Thanks!  here's a tested patch that implements it the way you suggest.

Now, as for the semantics we want.  I disagree with Michael's opinion.

Firstly, C and C++ differ in their std's description of the semantics of an 
expression cast to void (implicitly or explicitly).  The C std essentially says 
the value is discarded.  The C++ std specifies that no lvalue to rvalue 
transformation occurs, and it is this transformation that causes an lvalue 
object to be read.  There was a long discussion about this several years ago 
when I patched G++ to have somewhat more useful semantics (and warnings) than it 
did have.  That series of patches started when I noticed that in C++ 
'(void)*vol_ptr' did not cause a read of the pointed-to object, but it did in C. 
  The conclusion at that time were that the implemented C semantics were what 
was wanted.  These were:
* after an assignment to a volatile, no re-read occurred.
* a volatile was always read in a void context.

These rules are
* simple
* composable

It means that:

   '*vol_ptr1 = *vol_ptr2 = 0'
doesn't read *vol_ptr2 and therefore assign an unknown value to *vol_ptr1.  It 
also doesn't force any ordering on the two assignments to *vol_ptr1 and 
*vol_ptr2 -- just as would be true if things were not volatile.

   '*vol_ptr1'
where this is not the lhs of an assignment, will read the volatile object being 
pointed to, regardless of whether we use the value or not.

Notice in those examples that I have statement fragments.  The semantics are the 
same regardless of the context in which those fragments occur.

IIUC, Michael's desired semantics are
*) after an assignment, the value is re-read iff the assignment's value is used.
*) a volatile object is not read in a void context.
*) a volatile sub-expression is read or re-read if the value is used by the 
containing expression [I am unsure if this is Michael's semantics or not, please 
correct me if I'm wrong]

I am unsure whether the behaviour Michael would like is dependent on 
optimization level.  I think that would be a very bad thing, btw.

I think these lead to confusing code sequences, and are not composable. 
Fundamentally the ambiguity comes from specifying when an assignment's value is 
needed.  Without even considering data-flow optimizations that could determine a 
value is unused, we have the following:

   'cond ? (*vol_ptr = v) : other_v;'

The conditional expression has a value, even though it is in a void context. 
Does that mean that the volatile assignment's value is used or not?  Similarly for:
   'something, (*vol_ptr = v);'
or a more complicated variants:
   'something, ((vol_ptr = v), something);'
   '(something, (vol_ptr = v)), something;'

the problem here is that the behaviour of a sub-expression now depends on the 
context in which it is embedded (and that could be quite deeply embedded).  If 
we decide that the above examples do not re-read, because the value is 
ultimately not used, we have the ability for the programmer to really get 
confused during debugging.  For instance, they may rewrite one of these as
    'tmp = cond ? (*vol_ptr = v) : other_v;'
in order to determine the value that was written.  But now we've changed the 
pattern of accesses to the volatile object.  (And by in my recent dive into 
gimplify, we'll have a harder patch to write as we need to track want_result 
through more structures than we do at the moment.)

Should whatever semantics we decide upon be implemented by the gimplifier or by 
the front-end?  I'm not sure, but I do think the gimplifier should specify the 
semantics of volatile accesses, and those semantics should be consistent. 
Currently they are not.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery


[-- Attachment #2: volatile.patch --]
[-- Type: text/x-patch, Size: 3676 bytes --]

2010-06-21  Nathan Sidwell  <nathan@codesourcery.com>
	    Richard Guenther  <richard.guenther@gmail.com>

	gcc/
	* gimplify.c (gimplify_modify_expr): When assigning to volatiles,
	copy the src value and return a copy.

	gcc/testsuite/
	* gcc.target/i386/volatile-2.c: New.

Index: gimplify.c
===================================================================
--- gimplify.c	(revision 160876)
+++ gimplify.c	(working copy)
@@ -4572,6 +4572,9 @@
       SET_DECL_DEBUG_EXPR (*from_p, *to_p);
    }
 
+  if (want_value && TREE_THIS_VOLATILE (*to_p))
+    *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
+
   if (TREE_CODE (*from_p) == CALL_EXPR)
     {
       /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
@@ -4599,7 +4602,7 @@
 
   if (want_value)
     {
-      *expr_p = unshare_expr (*to_p);
+      *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
       return GS_OK;
     }
   else
Index: testsuite/gcc.target/i386/volatile-2.c
===================================================================
--- testsuite/gcc.target/i386/volatile-2.c	(revision 0)
+++ testsuite/gcc.target/i386/volatile-2.c	(revision 0)
@@ -0,0 +1,92 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* Check volatiles are written, read or not re-read consistently */
+
+
+/* simple assignments */
+
+extern int volatile obj_0;
+void test_0 (int data)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_0" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_0," } } */
+  obj_0 = data;
+}
+
+extern int volatile obj_1;
+int test_1 (int data)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_1" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_1," } } */
+  return obj_1 = data;
+}
+
+extern int volatile obj_2;
+int test_2 (void)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_2" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_2," } } */
+  return obj_2 = 0;
+}
+
+
+/* Assignments in compound exprs */
+
+extern int volatile obj_3;
+int test_3 (int data)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_3" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_3," } } */
+  return (obj_3 = data, 0);
+}
+
+extern int volatile obj_4;
+int test_4 (void)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_4" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_4," } } */
+  return (obj_4 = 0, 0);
+}
+extern int volatile obj_5;
+int test_5 (void)
+{
+  /* should reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_5" } } */
+  /* { dg-final { scan-assembler "movl\[ \t\]obj_5," } } */
+  return (obj_5 = 0, obj_5);
+}
+
+/* Assignments in conditional exprs */
+
+extern int volatile obj_6;
+void test_6 (int data, int cond)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_6" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_6," } } */
+  cond ? obj_6 = data : 0;
+}
+
+extern int volatile obj_7;
+int test_7 (int data, int cond)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_7" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_7," } } */
+  return cond ? obj_7 = data : 0;
+}
+
+extern int volatile obj_8;
+int test_8 (int cond)
+{
+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_8" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_8," } } */
+  return cond ? obj_8 = 0 : 0;
+}

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

* Re: [gimple] assignments to volatile
  2010-06-22 12:08   ` Nathan Sidwell
@ 2010-06-22 12:25     ` Richard Guenther
  2010-06-22 13:12     ` Michael Matz
  1 sibling, 0 replies; 81+ messages in thread
From: Richard Guenther @ 2010-06-22 12:25 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches, Michael Matz

On Tue, Jun 22, 2010 at 1:16 PM, Nathan Sidwell <nathan@codesourcery.com> wrote:
> On 06/21/10 13:07, Richard Guenther wrote:
>
>> Hm, TREE_THIS_VOLATILE (TREE_TYPE (*to_p)) should
>> certainly be TREE_THIS_VOLATILE (*to_p), and all this
>> should be done after gimplifying *to_p.  I think even just
>> before we build the gimple assign/call do
>
> ...
>
> Thanks!  here's a tested patch that implements it the way you suggest.
>
> Now, as for the semantics we want.  I disagree with Michael's opinion.
>
> Firstly, C and C++ differ in their std's description of the semantics of an
> expression cast to void (implicitly or explicitly).  The C std essentially
> says the value is discarded.  The C++ std specifies that no lvalue to rvalue
> transformation occurs, and it is this transformation that causes an lvalue
> object to be read.  There was a long discussion about this several years ago
> when I patched G++ to have somewhat more useful semantics (and warnings)
> than it did have.  That series of patches started when I noticed that in C++
> '(void)*vol_ptr' did not cause a read of the pointed-to object, but it did
> in C.  The conclusion at that time were that the implemented C semantics
> were what was wanted.  These were:
> * after an assignment to a volatile, no re-read occurred.
> * a volatile was always read in a void context.
>
> These rules are
> * simple
> * composable
>
> It means that:
>
>  '*vol_ptr1 = *vol_ptr2 = 0'
> doesn't read *vol_ptr2 and therefore assign an unknown value to *vol_ptr1.
>  It also doesn't force any ordering on the two assignments to *vol_ptr1 and
> *vol_ptr2 -- just as would be true if things were not volatile.
>
>  '*vol_ptr1'
> where this is not the lhs of an assignment, will read the volatile object
> being pointed to, regardless of whether we use the value or not.
>
> Notice in those examples that I have statement fragments.  The semantics are
> the same regardless of the context in which those fragments occur.
>
> IIUC, Michael's desired semantics are
> *) after an assignment, the value is re-read iff the assignment's value is
> used.
> *) a volatile object is not read in a void context.
> *) a volatile sub-expression is read or re-read if the value is used by the
> containing expression [I am unsure if this is Michael's semantics or not,
> please correct me if I'm wrong]
>
> I am unsure whether the behaviour Michael would like is dependent on
> optimization level.  I think that would be a very bad thing, btw.
>
> I think these lead to confusing code sequences, and are not composable.
> Fundamentally the ambiguity comes from specifying when an assignment's value
> is needed.  Without even considering data-flow optimizations that could
> determine a value is unused, we have the following:
>
>  'cond ? (*vol_ptr = v) : other_v;'
>
> The conditional expression has a value, even though it is in a void context.
> Does that mean that the volatile assignment's value is used or not?
>  Similarly for:
>  'something, (*vol_ptr = v);'
> or a more complicated variants:
>  'something, ((vol_ptr = v), something);'
>  '(something, (vol_ptr = v)), something;'
>
> the problem here is that the behaviour of a sub-expression now depends on
> the context in which it is embedded (and that could be quite deeply
> embedded).  If we decide that the above examples do not re-read, because the
> value is ultimately not used, we have the ability for the programmer to
> really get confused during debugging.  For instance, they may rewrite one of
> these as
>   'tmp = cond ? (*vol_ptr = v) : other_v;'
> in order to determine the value that was written.  But now we've changed the
> pattern of accesses to the volatile object.  (And by in my recent dive into
> gimplify, we'll have a harder patch to write as we need to track want_result
> through more structures than we do at the moment.)
>
> Should whatever semantics we decide upon be implemented by the gimplifier or
> by the front-end?  I'm not sure, but I do think the gimplifier should
> specify the semantics of volatile accesses, and those semantics should be
> consistent. Currently they are not.

Thanks for the updated patch.  I will review it once we settled
on the desired semantics.

And yes - the front-ends should make the semantic explicit.
I'd like to get rid of MODIFY_EXPR having a value to avoid these
problems and have the frontends lower MODIFY_EXPRs with
a value by using COMPOUND_EXPRs.

Richard.

> nathan
>
> --
> Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
>
>

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

* Re: [gimple] assignments to volatile
  2010-06-22 12:08   ` Nathan Sidwell
  2010-06-22 12:25     ` Richard Guenther
@ 2010-06-22 13:12     ` Michael Matz
  2010-06-22 13:54       ` Nathan Sidwell
  1 sibling, 1 reply; 81+ messages in thread
From: Michael Matz @ 2010-06-22 13:12 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Richard Guenther, GCC Patches

Hi,

On Tue, 22 Jun 2010, Nathan Sidwell wrote:

> IIUC, Michael's desired semantics are
> *) after an assignment, the value is re-read iff the assignment's value is
> used.
> *) a volatile object is not read in a void context.
> *) a volatile sub-expression is read or re-read if the value is used by the
> containing expression [I am unsure if this is Michael's semantics or not,
> please correct me if I'm wrong]

I think you're correct.

> I am unsure whether the behaviour Michael would like is dependent on
> optimization level.  I think that would be a very bad thing, btw.

It wouldn't be dependend on the optimization level, that would be 
terrible.  I.e. the "used-by" property would be purely syntactical.

> I think these lead to confusing code sequences, and are not composable.
> Fundamentally the ambiguity comes from specifying when an assignment's value
> is needed.

Indeed.  Both semantics (re-read or no re-read) will generate some 
surprises, mine has the problem of context dependency, yours for instance 
breaks this identity:
  x = vol = y;
<==>
  vol = y;
  x = vol;

I read the standard as requiring this identity to hold (in particular the 
language about values of assignments not being lvalues is only to disallow 
constructs like "(a = b) = c;").  That is my fundamental problem with your 
approach, that it effectively creates this identity:
  x = y    // as fragment
<==>
  (t = y, x = t, t)  // t a new temporary of the unqualified type of x

Note that I don't think this would be bad semantics, to the contrary (I'm 
not particularly glad about the context dependency that my reading 
implies).  I just don't see it justified in the standard.

> pattern of accesses to the volatile object.  (And by in my recent dive into
> gimplify, we'll have a harder patch to write as we need to track want_result
> through more structures than we do at the moment.)

I'd rather think that it's not gimplify's job at all to implement volatile 
semantics.  It's rather the frontend which should make sure all reads and 
writes to volatile objects are emitted as specified in the language 
standard.  gimplify then merely shouldn't change the number and kind of 
accesses to volatile objects (neither should any further transformation).

> Should whatever semantics we decide upon be implemented by the 
> gimplifier or by the front-end?  I'm not sure, but I do think the 
> gimplifier should specify the semantics of volatile accesses, and those 
> semantics should be consistent. Currently they are not.

I have no problem if we specify that we gimplify assignments as per the 
above second identity.  (I just also think that the C frontend needs 
fixing to emit explicit re-reads).


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-22 13:12     ` Michael Matz
@ 2010-06-22 13:54       ` Nathan Sidwell
  2010-06-22 15:21         ` Michael Matz
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-22 13:54 UTC (permalink / raw)
  To: Michael Matz; +Cc: Richard Guenther, GCC Patches

On 06/22/10 13:37, Michael Matz wrote:

>> I think these lead to confusing code sequences, and are not composable.
>> Fundamentally the ambiguity comes from specifying when an assignment's value
>> is needed.
>
> Indeed.  Both semantics (re-read or no re-read) will generate some
> surprises, mine has the problem of context dependency,

As this is the case then I think we're looking for the solution with the least 
surprise, and whatever solution we have will be outside the bounds of the std to 
some greater or lesser extent.

> yours for instance
> breaks this identity:
>    x = vol = y;
> <==>
>    vol = y;
>    x = vol;
>
> I read the standard as requiring this identity to hold (in particular the
> language about values of assignments not being lvalues is only to disallow
> constructs like "(a = b) = c;").

Thanks for identifying the crux of the difference.  I don't think that 
transformation is an identity when volatiles are in play.  Volatile objects 
break all sorts of transformations that would otherwise be fine.  For instance 
your semantics make the following transform not an identity:
    tmp = vol;
    // no further use of tmp
<==>
    vol;

I don't see what's special about the transformation you're highlighting as not 
being an identity under one set of semantics.

I'm still having a problem with sequence points.  Your email of yesterday:

 > Now, onto 6.5 #2:
 >
 >    Between the previous and next sequence point an object shall have its
 >    stored value modified at most once by the evaluation of an expression.
 >    Furthermore, the prior value shall be read only to determine the value
 >    to be stored.70)
 >
 > This talks only about the side-effect of changing the stored value (which
 > we do only once) and about the prior value, which we don't use at all.

I had misremembered that piece of the std as saying 'the object's value shall be 
read only ...'.  I.e. no 'prior' in there.  Indeed, the explanation given in the 
C-faq http://linuxdude.com/Steve_Sumit/C-faq/q3.8.html is 'any and all accesses 
to it within the same expression must be for the purposes of computing the value 
to be written'.  I did think the mental model I have of assignments came from 
the C-faq, but I can't find it there.  Here it is, perhaps someone will 
recognize the author?

1) for each assignment, the new value is written on a ball, and thrown at the 
lvalue target.

2) it is guaranteed all balls will arrive at their targets by the next sequence 
point.

3) if more than one ball is aimed at the same target, chaos occurs.

4) if you try and read a target when a ball is in flight for that target, chaos 
occurs.

Your read-after-write interpretation breaks that model (of course the model 
could be wrong)

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-22 13:54       ` Nathan Sidwell
@ 2010-06-22 15:21         ` Michael Matz
  2010-06-22 16:12           ` Joseph S. Myers
  0 siblings, 1 reply; 81+ messages in thread
From: Michael Matz @ 2010-06-22 15:21 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Richard Guenther, GCC Patches

Hi,

On Tue, 22 Jun 2010, Nathan Sidwell wrote:

> > Indeed.  Both semantics (re-read or no re-read) will generate some 
> > surprises, mine has the problem of context dependency,
> 
> As this is the case then I think we're looking for the solution with the 
> least surprise, and whatever solution we have will be outside the bounds 
> of the std to some greater or lesser extent.

Indeed (if we determine that the solutions don't violate the standard of 
course).

> > yours for instance
> > breaks this identity:
> >    x = vol = y;
> > <==>
> >    vol = y;
> >    x = vol;
> 
> Thanks for identifying the crux of the difference.  I don't think that 
> transformation is an identity when volatiles are in play.  Volatile 
> objects break all sorts of transformations that would otherwise be fine.  

Note that I'm not seeing the above identity as transformation (that could 
or could not be allowed).  Rather I read the standard as describing the 
semantics of "x = vol = y" in terms of the second sequence (by defining 
how to get to the value of 'vol = y'); as in the second sequence _being_ 
the semantics of the first one.  That reading could be wrong, but it is 
the reason why I think a re-read needs to occur.

> For instance your semantics make the following transform not an 
> identity:

>    tmp = vol;
>    // no further use of tmp
> <==>
>    vol;
> 
> I don't see what's special about the transformation you're highlighting 
> as not being an identity under one set of semantics.

The difference is that I don't see any language in the standard that would 
require these two sequences to be equivalent (much less to define the 
first one in terms of the latter one).

> I'm still having a problem with sequence points.  Your email of yesterday:
> 
> > Now, onto 6.5 #2:
> >
> >    Between the previous and next sequence point an object shall have its
> >    stored value modified at most once by the evaluation of an expression.
> >    Furthermore, the prior value shall be read only to determine the value
> >    to be stored.70)
> >
> > This talks only about the side-effect of changing the stored value (which
> > we do only once) and about the prior value, which we don't use at all.
> 
> I had misremembered that piece of the std as saying 'the object's value shall
> be read only ...'.  I.e. no 'prior' in there.  Indeed, the explanation given
> in the C-faq http://linuxdude.com/Steve_Sumit/C-faq/q3.8.html is 'any and all
> accesses to it within the same expression must be for the purposes of
> computing the value to be written'.

I think that's just a sloppy reformulation of the standard together with 
the fact that accesses to the 'new value' usually don't make much 
difference, except in the presence of volatile.

> 1) for each assignment, the new value is written on a ball, and thrown 
>    at the lvalue target.
> 
> 2) it is guaranteed all balls will arrive at their targets by the next 
>    sequence point.
> 
> 3) if more than one ball is aimed at the same target, chaos occurs.
> 
> 4) if you try and read a target when a ball is in flight for that 
>    target, chaos occurs.
> 
> Your read-after-write interpretation breaks that model (of course the model
> could be wrong)

(I'm of course saying the model is wrong ;-), though perhaps it actually 
isn't and my read-after-write interpretation doesn't break it, read on)

While reading this mental model a different aspect of this whole topic 
came into my mind, namely that there's a implicit ordering of 
subexpressions when values of assignments are involved.  Not quite 
sequence points, but certainly effects that must occur necessarily before 
other effects.  For instance in "x = y = z" it's clear that the assignment 
to y has to happen before the assignment to x (that is because the value 
of y = z is that of y, so if the assignment to y would happen after the 
assignment to x it would access the old value).

Sequence points are there to be able to say something about allowed orders 
of side-effects.  The implicit ordering above when assignment values are 
used also help that goal (on a smaller scale, it for instance doesn't 
impose an ordering on subexpressions not related to the assignment).  
Maybe this explains why I think there's no problem with sequence points.  
Your model would need amendment in point 2), not just mentioning sequence 
points but also these other ordering constraints, for which I don't have a 
good name :)


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-21 13:55   ` Michael Matz
                       ` (2 preceding siblings ...)
  2010-06-21 14:17     ` IainS
@ 2010-06-22 15:37     ` Mark Mitchell
  2010-06-22 15:37       ` Jakub Jelinek
                         ` (2 more replies)
  3 siblings, 3 replies; 81+ messages in thread
From: Mark Mitchell @ 2010-06-22 15:37 UTC (permalink / raw)
  To: Michael Matz; +Cc: Richard Guenther, Nathan Sidwell, GCC Patches

Michael Matz wrote:

>>> Sometimes we re-read the assigned-to object, and sometimes we do not.  For
>>> instance,
>>>   return vobj = data;
>>> will cause a reread of vobj, IF data is not a constant.
> 
> I'd consider the latter condition a bug.  I.e. the rereading must happen 
> in every case.

I think that it's without question that:

  vobj = data;

should not cause a read from vobj; the value is not used.  I think
real-world embedded programmers would be surprised to see a read from an
I/O register there.  Do you agree?

Similarly, I think that:

  cond ? vobj = data : ...

should not cause a read from vobj.  The conditional in this case is just
a form of if/then; it would surprise programmers if this behaved
differently from:

  if (cond)
    vobj = data;

Do you agree?

The case of:

  x = vobj = data;

is different because the value is being used.  In that case, I have no
strong opinion.

Rather than argue about this last case in theory, though, I'd be
inclined to look at existing practice.  What do RealView, CodeWarrior,
Green Hills or other long-standing compilers for embedded systems do?
If there's a clear consensus, we can follow that.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-22 15:37     ` Mark Mitchell
@ 2010-06-22 15:37       ` Jakub Jelinek
  2010-06-22 15:57         ` Paul Koning
  2010-06-22 15:47       ` Michael Matz
  2010-06-22 15:56       ` Paul Koning
  2 siblings, 1 reply; 81+ messages in thread
From: Jakub Jelinek @ 2010-06-22 15:37 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Michael Matz, Richard Guenther, Nathan Sidwell, GCC Patches

On Tue, Jun 22, 2010 at 11:17:31AM -0400, Mark Mitchell wrote:
>   if (cond)
>     vobj = data;
> 
> Do you agree?
> 
> The case of:
> 
>   x = vobj = data;
> 
> is different because the value is being used.  In that case, I have no
> strong opinion.

What about
(void) vobj;
or
(void) (vobj = data);
?  Should that read vobj?

	Jakub

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

* Re: [gimple] assignments to volatile
  2010-06-22 15:37     ` Mark Mitchell
  2010-06-22 15:37       ` Jakub Jelinek
@ 2010-06-22 15:47       ` Michael Matz
  2010-06-22 15:58         ` Mark Mitchell
  2010-06-22 15:56       ` Paul Koning
  2 siblings, 1 reply; 81+ messages in thread
From: Michael Matz @ 2010-06-22 15:47 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Richard Guenther, Nathan Sidwell, GCC Patches

Hi,

On Tue, 22 Jun 2010, Mark Mitchell wrote:

> I think that it's without question that:
> 
>   vobj = data;
> 
> should not cause a read from vobj; the value is not used.  I think
> real-world embedded programmers would be surprised to see a read from an
> I/O register there.  Do you agree?

Yes.

>   cond ? vobj = data : ...
> 
> should not cause a read from vobj.
> 
> Do you agree?

Yes.

> The case of:
>   x = vobj = data;
> 
> is different because the value is being used.  In that case, I have no
> strong opinion.
> 
> Rather than argue about this last case in theory, though, I'd be
> inclined to look at existing practice.  What do RealView, CodeWarrior,
> Green Hills or other long-standing compilers for embedded systems do?

That would be interesting, yes.

> If there's a clear consensus, we can follow that.


Ciao,
Michael.

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

* RE: [gimple] assignments to volatile
  2010-06-22 15:37     ` Mark Mitchell
  2010-06-22 15:37       ` Jakub Jelinek
  2010-06-22 15:47       ` Michael Matz
@ 2010-06-22 15:56       ` Paul Koning
  2 siblings, 0 replies; 81+ messages in thread
From: Paul Koning @ 2010-06-22 15:56 UTC (permalink / raw)
  To: Mark Mitchell, Michael Matz; +Cc: Richard Guenther, Nathan Sidwell, GCC Patches

> Michael Matz wrote:
> 
> >>> Sometimes we re-read the assigned-to object, and sometimes we do
> not.  For
> >>> instance,
> >>>   return vobj = data;
> >>> will cause a reread of vobj, IF data is not a constant.
> >
> > I'd consider the latter condition a bug.  I.e. the rereading must
> happen
> > in every case.
> 
> I think that it's without question that:
> 
>   vobj = data;
> 
> should not cause a read from vobj; the value is not used.  I think
> real-world embedded programmers would be surprised to see a read from
> an
> I/O register there.  Do you agree?

Yes.  Whatever else you do, this property is mandatory.
 
> Similarly, I think that:
> 
>   cond ? vobj = data : ...
> 
> should not cause a read from vobj.  The conditional in this case is
> just
> a form of if/then; it would surprise programmers if this behaved
> differently from:
> 
>   if (cond)
>     vobj = data;
> 
> Do you agree?

Maybe.  Personally I would view the statement you listed as bad code.
 
> The case of:
> 
>   x = vobj = data;
> 
> is different because the value is being used.  In that case, I have no
> strong opinion.
> 
> Rather than argue about this last case in theory, though, I'd be
> inclined to look at existing practice.  What do RealView, CodeWarrior,
> Green Hills or other long-standing compilers for embedded systems do?
> If there's a clear consensus, we can follow that.

Right.

The question on the statement you quoted is whether people interpret it as "data is assigned to two variables" or "data is assigned to vobj and the vobj is assigned to x".  I take it from earlier discussion that the standard says the latter.  Actually, given that this code is confusing, it might deserve a warning.

Finally, whatever is done must produce the same answer whether the code is compiled as C or C++.

	paul


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

* RE: [gimple] assignments to volatile
  2010-06-22 15:37       ` Jakub Jelinek
@ 2010-06-22 15:57         ` Paul Koning
  0 siblings, 0 replies; 81+ messages in thread
From: Paul Koning @ 2010-06-22 15:57 UTC (permalink / raw)
  To: Jakub Jelinek, Mark Mitchell
  Cc: Michael Matz, Richard Guenther, Nathan Sidwell, GCC Patches

> What about
> (void) vobj;
> or
> (void) (vobj = data);
> ?  Should that read vobj?

Yes on the first.  Don't know on the second.  The problem is that some
programmers have a bad habit of throwing in (void) when it isn't needed,
for example when ignoring the return value of a function used as a
statement.  Code like (void) printf (...) is quite common.  Given that
people do this, it's hard to guess what (void) (a=b); was intended to
convey.  Maybe the best thing to do with that one is (a) pick an answer,
(b) generate a warning.

	paul 

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

* Re: [gimple] assignments to volatile
  2010-06-22 15:47       ` Michael Matz
@ 2010-06-22 15:58         ` Mark Mitchell
  2010-06-23 11:38           ` Nathan Sidwell
  0 siblings, 1 reply; 81+ messages in thread
From: Mark Mitchell @ 2010-06-22 15:58 UTC (permalink / raw)
  To: Michael Matz; +Cc: Richard Guenther, Nathan Sidwell, GCC Patches

Michael Matz wrote:

>>   x = vobj = data;

>> Rather than argue about this last case in theory, though, I'd be
>> inclined to look at existing practice.  What do RealView, CodeWarrior,
>> Green Hills or other long-standing compilers for embedded systems do?

> That would be interesting, yes.

Nathan, I know that we have RealView available for testing, and I
believe we also have CodeWarrior installed.  Would you like to give
those two a try?

If so, you could also look at:

  vobj;

and:

  (void) vobj;

I think those should do reads, but, again, I'd be persuaded by existing
practice.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-22 15:21         ` Michael Matz
@ 2010-06-22 16:12           ` Joseph S. Myers
  0 siblings, 0 replies; 81+ messages in thread
From: Joseph S. Myers @ 2010-06-22 16:12 UTC (permalink / raw)
  To: Michael Matz; +Cc: Nathan Sidwell, Richard Guenther, GCC Patches

On Tue, 22 Jun 2010, Michael Matz wrote:

> While reading this mental model a different aspect of this whole topic 
> came into my mind, namely that there's a implicit ordering of 
> subexpressions when values of assignments are involved.  Not quite 

If you look in C1X drafts you will see more of an *explicit* ordering.  
"The side effect of updating the stored value of the left operand is 
sequenced after the value computations of the left and right operands. The 
evaluations of the operands are unsequenced." (N1425 6.5.16#3).

Note that there is nothing about sequencing for any reading of the left 
operand after the store.  There is also nothing about sequencing for the 
conversion of the right operand to the type of the left operand (which 
could cause floating-point exceptions, for example), though I'd interpret 
that as being part of the value computation of the right operand.

As I read it, in "*p = *q = *r = *s;", there is no sequencing among the 
assignments to *p, *q and *r, although they must all occur by the sequence 
point at the end of the statement.  Note what N1252, the paper introducing 
this sequencing model, says: "It is extremely important to note here that 
the assignment is not sequenced after any side effects of the operands, 
but only after their value computations.".

My view is that the value computation of an assignment consists of the 
value computation of both operands including the conversion of the right 
operand to the type of the left operand, and the value should be 
considered to be the result of that conversion, without volatile lvalues 
being reread.  In "A = B = C = D;", the side effects of assignment to A, B 
and C are unsequenced with respect to each other and with respect to any 
other side effects of A, B, C and D except where other sequence points are 
involved (if C involves a call to a function, for example, then all side 
effects in that function are sequenced before the assignments to any of A, 
B and C).

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [gimple] assignments to volatile
  2010-06-22 15:58         ` Mark Mitchell
@ 2010-06-23 11:38           ` Nathan Sidwell
  2010-06-23 14:05             ` Mark Mitchell
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-23 11:38 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Michael Matz, Richard Guenther, GCC Patches

On 06/22/10 16:36, Mark Mitchell wrote:

> Nathan, I know that we have RealView available for testing, and I
> believe we also have CodeWarrior installed.  Would you like to give
> those two a try?

I couldn't get CodeWarrior to play.

RVCT generated code consistent with my proposal.  Specifically in:
  some_use_of = volatile_object = value;
the volatile object is only written to and not read, regardless of the context 
of that volatile assignment (be it return expression, conditional expression or 
serial assignment).

>    vobj;
>    (void) vobj;

Both of these cause a read of vobj in RVCT (and GCC).

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-23 11:38           ` Nathan Sidwell
@ 2010-06-23 14:05             ` Mark Mitchell
  2010-06-23 14:06               ` Michael Matz
                                 ` (2 more replies)
  0 siblings, 3 replies; 81+ messages in thread
From: Mark Mitchell @ 2010-06-23 14:05 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Michael Matz, Richard Guenther, GCC Patches

Nathan Sidwell wrote:

> RVCT generated code consistent with my proposal.  Specifically in:
>  some_use_of = volatile_object = value;
> the volatile object is only written to and not read, regardless of the
> context of that volatile assignment (be it return expression,
> conditional expression or serial assignment).

Good.

>>    vobj;
>>    (void) vobj;
> 
> Both of these cause a read of vobj in RVCT (and GCC).

Good.

If there are no objections within the next 48 hours, then I think we
should consider the semantics settled.  I'm not trying to squash
discussion; if people don't like those semantics, let's discuss.  But, I
think existing practice should weigh heavily.

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-23 14:05             ` Mark Mitchell
@ 2010-06-23 14:06               ` Michael Matz
  2010-06-23 16:00                 ` Richard Guenther
  2010-06-23 16:25               ` Paul Koning
  2010-06-23 19:16               ` Mike Stump
  2 siblings, 1 reply; 81+ messages in thread
From: Michael Matz @ 2010-06-23 14:06 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Nathan Sidwell, Richard Guenther, GCC Patches

Hi,

On Wed, 23 Jun 2010, Mark Mitchell wrote:

> >>    vobj;
> >>    (void) vobj;
> > 
> > Both of these cause a read of vobj in RVCT (and GCC).
> 
> Good.
> 
> If there are no objections within the next 48 hours, then I think we 
> should consider the semantics settled.  I'm not trying to squash 
> discussion; if people don't like those semantics, let's discuss.  But, I 
> think existing practice should weigh heavily.

FWIW I agree.


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-23 14:06               ` Michael Matz
@ 2010-06-23 16:00                 ` Richard Guenther
  0 siblings, 0 replies; 81+ messages in thread
From: Richard Guenther @ 2010-06-23 16:00 UTC (permalink / raw)
  To: Michael Matz; +Cc: Mark Mitchell, Nathan Sidwell, GCC Patches

On Wed, Jun 23, 2010 at 3:10 PM, Michael Matz <matz@suse.de> wrote:
> Hi,
>
> On Wed, 23 Jun 2010, Mark Mitchell wrote:
>
>> >>    vobj;
>> >>    (void) vobj;
>> >
>> > Both of these cause a read of vobj in RVCT (and GCC).
>>
>> Good.
>>
>> If there are no objections within the next 48 hours, then I think we
>> should consider the semantics settled.  I'm not trying to squash
>> discussion; if people don't like those semantics, let's discuss.  But, I
>> think existing practice should weigh heavily.
>
> FWIW I agree.

And thus the revised patch is ok if it indeed implements the above
and passes bootstrap & regtest.

Thanks,
Richard.

>
> Ciao,
> Michael.
>

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

* RE: [gimple] assignments to volatile
  2010-06-23 14:05             ` Mark Mitchell
  2010-06-23 14:06               ` Michael Matz
@ 2010-06-23 16:25               ` Paul Koning
  2010-06-23 17:13                 ` Mark Mitchell
  2010-06-23 19:16               ` Mike Stump
  2 siblings, 1 reply; 81+ messages in thread
From: Paul Koning @ 2010-06-23 16:25 UTC (permalink / raw)
  To: Mark Mitchell, Nathan Sidwell; +Cc: Michael Matz, Richard Guenther, GCC Patches

> Nathan Sidwell wrote:
> 
> > RVCT generated code consistent with my proposal.  Specifically in:
> >  some_use_of = volatile_object = value;
> > the volatile object is only written to and not read, regardless of
> the
> > context of that volatile assignment (be it return expression,
> > conditional expression or serial assignment).
> 
> Good.
> 
> >>    vobj;
> >>    (void) vobj;
> >
> > Both of these cause a read of vobj in RVCT (and GCC).
> 
> Good.
> 
> If there are no objections within the next 48 hours, then I think we
> should consider the semantics settled.  I'm not trying to squash
> discussion; if people don't like those semantics, let's discuss.  But,
> I
> think existing practice should weigh heavily.

Agreed.

The semantics will be the same for C and C++, correct?

	paul

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

* Re: [gimple] assignments to volatile
  2010-06-23 16:25               ` Paul Koning
@ 2010-06-23 17:13                 ` Mark Mitchell
  0 siblings, 0 replies; 81+ messages in thread
From: Mark Mitchell @ 2010-06-23 17:13 UTC (permalink / raw)
  To: Paul Koning; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

Paul Koning wrote:

> The semantics will be the same for C and C++, correct?

I should certainly hope so.  I see no reason for them to be different,
and we certainly want to minimize such differences.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-23 14:05             ` Mark Mitchell
  2010-06-23 14:06               ` Michael Matz
  2010-06-23 16:25               ` Paul Koning
@ 2010-06-23 19:16               ` Mike Stump
  2010-06-24 10:22                 ` Mark Mitchell
  2010-06-24 10:23                 ` Nathan Sidwell
  2 siblings, 2 replies; 81+ messages in thread
From: Mike Stump @ 2010-06-23 19:16 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

On Jun 23, 2010, at 6:08 AM, Mark Mitchell wrote:
> Nathan Sidwell wrote:
> 
>> RVCT generated code consistent with my proposal.  Specifically in:
>> some_use_of = volatile_object = value;
>> the volatile object is only written to and not read, regardless of the
>> context of that volatile assignment (be it return expression,
>> conditional expression or serial assignment).
> 
> Good.
> 
>>>   vobj;
>>>   (void) vobj;
>> 
>> Both of these cause a read of vobj in RVCT (and GCC).
> 
> Good.
> 
> If there are no objections within the next 48 hours,

I object.

gcc semantics are carefully designed.  gcc is the standard compiler for much embedded work, C and C++ differ due to the standards organizations, some of those differences are truly unfortunate, but there you go.  If someone wanted to fix gcc, the proper way would be to get the C and C++ committees on the same page, nail it down, or make it a hard error, and remove any latitude and confusion and make them agree.

C++ says:

  All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand.

You can't just willy nilly change this:

int i, j, k;
void foo(int &j) {
  foo(i = k);
}

can sense if you get it right or not.  Add a volatile on i, and you discover, you can't just change this as you see fit, in particular, not in the way you all seem to want, which is just plain wrong.

Further, C says:

  An assignment expression has the value of the left operand after the assignment

Now, this is pretty plain, the value is the left operand.  They choose this wording as they didn't want the return value to be a modifiable lvalue.  I concede there is enough wiggle room here to confuse users and give implementors enough latitude to try and claim they are following the standard, but really, the return value is the valuer of the left operand, if it weren't, the standard would not say it was.  It could have said, the value is the value that was stored in the left operand, or the value is the right operand after conversion to the type of the left operand, or a host of other possibilities.

> then I think we should consider the semantics settled.  I'm not trying to squash
> discussion; if people don't like those semantics, let's discuss.  But, I
> think existing practice should weigh heavily.

This semantic in gcc has been the industry standard for at least 15 years.  If there have been any code written that depend upon this, you break them all.  This breakage is silent, and in the type of code that you really don't want to break in this way.

I object to the change.

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

* Re: [gimple] assignments to volatile
  2010-06-21 15:24           ` Michael Matz
  2010-06-22 11:36             ` Dave Korn
@ 2010-06-23 20:16             ` Mike Stump
  2010-06-24 11:51               ` Michael Matz
  1 sibling, 1 reply; 81+ messages in thread
From: Mike Stump @ 2010-06-23 20:16 UTC (permalink / raw)
  To: Michael Matz; +Cc: Nathan Sidwell, IainS, Richard Guenther, GCC Patches

On Jun 21, 2010, at 7:25 AM, Michael Matz wrote:
> On Mon, 21 Jun 2010, Nathan Sidwell wrote:
>>> Yes, namely that the author explicitely wrote a read access to vobj.
>>> To demonstrate, like
>>>   return vobj;
>>> implies a read from vobj, also
>>>   return vobj = x;
>>> implies a read from vobj.  The latter _also_ implies a store to vobj.  If
>>> you want the read to not happen the author better writes
>>>   vobj = x;
>>>   return x;
>> 
>> Then what about plain
>> 	vobj;
>> ?  Is that a read of vobj?
> 
> As said, implementation-defined I think.

:-(  The standard waffles around with the implementation defined terminology because they don't define wires and voltages and the CPU bus.  If they did, it would be plain as day what they mean.  They do this only because those accesses are beyond the capability of the standard to describe well and because the standards writers are lazy and/or not skilled enough to get the language correct,

The basics are pretty simple, consider a byte wide bus, single processor, no cache, with a char access.  A read access of the abstract machine is mapped to read bus cycle, and a write is mapped to a write cycle.  This isn't meant to be opaque or surprising.

The use terminology like:

  What constitutes an access to  an object  that  has volatile-qualified type is implementation-defined.

because exactly what happens when you access a character on a machine that doesn't have an 8-bit wide bus is slightly trickier to define.  This isn't meant to be used to arbitrarily change the mapping of the abstract machine onto the physical machine.  It is wrong to think one can use the latitude in the standard due to implementation defined bits to add or erase entire loads and stores.

For example, we could define all stores to volatile objects on x86_64 machines of width 64-bit to not happen, but that would be crazy, but the precise wording of the standard actually allows it.  If there were a mapping standard for C on x86_64 hardware that refined and defined the abstract semantics to the actual bus, you'd discover in that standard, there would be no wiggle room for this sort of declaration.

>  (I think we should define it to be no access, unlike 'x = vobj;' even if x is unused later.).

Again, it is wrong to abuse the latitude in the standard like this.  If the standard says there is a read access on the abstract machine, then there is a read access on the physical machine (at least when the sizes match).  We define an access, iff there is a access on the abstract machine.

>> what about hiding the assignment inside a cond expr
>>     cond ? vobj = expr : 0;
>> Is that a re-read of vobj?
> 
> If that's the full expression I think we should say that this doesn't 
> constitute a read access.

The standard describes all accesses on the abstract machine, the model we use for gcc is that every single access is mapped to a single hardware bus cycle, as long as the size of the access and the bus are the same.  For a size mismatch, I'd need more room, but the rules are equally as predicable.  A 64-bit store for example, on a 32-bit bus happens as two 32-bit cycles.  Give that mapping, we can judge the above as wrong.

I'm against the idea of using any other mapping.  So, I'd rather you argue the behavior of what gcc should do, but stating what the requite semantics of the abstract machine of the language standard mandates.  Then, what gcc should do is exactly match that.  I object to anything else.

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

* Re: [gimple] assignments to volatile
  2010-06-23 19:16               ` Mike Stump
@ 2010-06-24 10:22                 ` Mark Mitchell
  2010-06-24 15:53                   ` Mike Stump
  2010-06-24 10:23                 ` Nathan Sidwell
  1 sibling, 1 reply; 81+ messages in thread
From: Mark Mitchell @ 2010-06-24 10:22 UTC (permalink / raw)
  To: Mike Stump; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

Mike Stump wrote:

> If someone wanted to fix gcc, the proper way would be to get the C
> and C++ committees on the same page, nail it down, or make it a hard
> error, and remove any latitude and confusion and make them agree.

Are you saying that C and C++ require different behavior for:

  x = y = z;

where "y" is volatile?  Or are you saying that C++ requires that "y" be
read while C does not specify it one way or the other?

Please state your position more clearly.

> An assignment expression has the value of the left operand after the 
> assignment

I don't think this is nearly as clear as you do.  Furthermore, I think
existing practice from other embedded compilers is pretty important;
your statement that "the semantics in GCC has been the industry standard
for at least 15 years" is overly strong.  But, changing GCC's historic
behavior is clearly not desirable, and that's an argument against
eliminating the read.

However, I cannot see any good justification for:

  int x;
  volatile int y;
  int z;
  x ? y = z : 0

generating a read from "y" while:

  x ? y = 0 : 0

does not.

Which behavior are you claiming is correct here?

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-23 19:16               ` Mike Stump
  2010-06-24 10:22                 ` Mark Mitchell
@ 2010-06-24 10:23                 ` Nathan Sidwell
  2010-06-24 17:05                   ` Mike Stump
  1 sibling, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-24 10:23 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On 06/23/10 19:36, Mike Stump wrote:


> C++ says:

C and C++ differ in their cast-to-void behaviour.  In particular, in C++
   (void)obj;
does not cause a read of obj, because no lvalue->rvalue decay occurs.  This is 
very confusing for volatiles and incompatible with established C semantics.  As 
such G++ will cause a read of a volatile scalar obj in these cases.  For a 
volatile aggregate obj, it will emit a warning.

In C++ the result of an assignment is an lvalue.  It is not in C.

> You can't just willy nilly change this:
>
> int i, j, k;
> void foo(int&j) {
>    foo(i = k);
> }
>
> can sense if you get it right or not.  Add a volatile on i, and you discover, you can't just change this as you see fit, in particular, not in the way you all seem to want, which is just plain wrong.

I do not know what you are saying here.  Making (just) i volatile will render 
your code example ill-formed.

> Further, C says:
>
>    An assignment expression has the value of the left operand after the assignment
>
> Now, this is pretty plain, the value is the left operand.  They choose this wording as they didn't want the return value to be a modifiable lvalue.  I concede there is enough wiggle room here to confuse users and give implementors enough latitude to try and claim they are following the standard, but really, the return value is the valuer of the left operand, if it weren't, the standard would not say it was.  It could have said, the value is the value that was stored in the left operand, or the value is the right operand after conversion to the type of the left operand, or a host of other possibilities.

Are you saying that in C, both

   (void)obj;
and
   (void)(obj = value);

should behave the same wrt the behaviour of reads from a volatile obj?  I 
thought there was consensus that they should not.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-23 20:16             ` Mike Stump
@ 2010-06-24 11:51               ` Michael Matz
  0 siblings, 0 replies; 81+ messages in thread
From: Michael Matz @ 2010-06-24 11:51 UTC (permalink / raw)
  To: Mike Stump; +Cc: Nathan Sidwell, IainS, Richard Guenther, GCC Patches

Hi,

On Wed, 23 Jun 2010, Mike Stump wrote:

> >  (I think we should define it to be no access, unlike 'x = vobj;' even if x is unused later.).
> 
> Again, it is wrong to abuse the latitude in the standard like this.  If 
> the standard says there is a read access on the abstract machine,

The point of this whole thread is that the standard doesn't say there's a 
read access for "vobj;" (full expression).  I tried to argue in this 
thread that there should be a read and a write access of vobj in
 "x = vobj = y;" .  From that position some surprising consequences would 
follow, which I tried to either argue irrelevant or wrongly implied.

I'm not sure what exactly your position on this whole matter is, except 
for "let's do exactly what the standard says".  I'm not at all disagreeing 
with the position, but this very thread shows quite clearly that there's 
disagreement about _what_ exactly the standard says.  So you should rather 
try to explain what you think the standard implies (I myself don't know if 
you're for or against a re-read).


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-24 10:22                 ` Mark Mitchell
@ 2010-06-24 15:53                   ` Mike Stump
  2010-06-24 16:00                     ` Mark Mitchell
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Stump @ 2010-06-24 15:53 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

On Jun 23, 2010, at 10:54 PM, Mark Mitchell wrote:
> Mike Stump wrote:
>> If someone wanted to fix gcc, the proper way would be to get the C
>> and C++ committees on the same page, nail it down, or make it a hard
>> error, and remove any latitude and confusion and make them agree.
> 
> Are you saying that C and C++ require different behavior for:
> 
>  x = y = z;
> 
> where "y" is volatile?

In my book no, they do not.  I think a reasonable person can also say that they do, because the C standard can be read in a way that is difference from the C standard.  C++ requires a re-read of y.  For consistency, the C standard should be read in a way that requires the re-read of y.

> Or are you saying that C++ requires that "y" be read while C does not specify it one way or the other?

This is the essence of the second point above.

> Please state your position more clearly.

C++ requires a re-read of y, the patch was going to remove the re-read, I objected because the patch then makes the compiler not conform to the C++ standard.  The patch was going to make C differ from C++, should the semantic for C++ be put back to match the standard. I really don't like to see the behavior of C++ and C differ when they don't need to.

>> An assignment expression has the value of the left operand after the 
>> assignment
> 
> I don't think this is nearly as clear as you do.

Ok.  Let's talk about it.  I objected because people seems to be going in the wrong direction.  Maybe I just misunderstood the effect of the patch.  The patch removes the re-read of y, right?

> Furthermore, I think existing practice from other embedded compilers is pretty important;

But to the exclusion of all of gcc users and the c++ standard?

> However, I cannot see any good justification for:
> 
>  int x;
>  volatile int y;
>  int z;
>  x ? y = z : 0
> 
> generating a read from "y" while:
> 
>  x ? y = 0 : 0
> 
> does not.

I wasn't arguing this case.  I believe both standards have them behaving the same.

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

* Re: [gimple] assignments to volatile
  2010-06-24 15:53                   ` Mike Stump
@ 2010-06-24 16:00                     ` Mark Mitchell
  2010-06-24 19:37                       ` Mike Stump
  2010-06-25  9:20                       ` Nathan Sidwell
  0 siblings, 2 replies; 81+ messages in thread
From: Mark Mitchell @ 2010-06-24 16:00 UTC (permalink / raw)
  To: Mike Stump; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

Mike Stump wrote:

>> x = y = z;
>> 
>> where "y" is volatile?

> C++ requires a re-read of y, the patch was going to remove the
> re-read, I objected because the patch then makes the compiler not
> conform to the C++ standard.

I think that you have to read rather a lot into the C++ standard to
arrive at that conclusion.  But, I suggest that you raise the issue on
the C++ reflector and report back.  I think that it would be very
helpful to hear what other implementors think.

But, this point may be moot; I don't know if the proposed patch changes
the behavior here or not.  Nathan, can you clarify that?

>> int x; volatile int y; int z; x ? y = z : 0
>> 
>> generating a read from "y" while:
>> 
>> x ? y = 0 : 0
>> 
>> does not.
> 
> I wasn't arguing this case.  I believe both standards have them
> behaving the same.

And which way is that?  Do you think that y needs to be read, or not?

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-24 10:23                 ` Nathan Sidwell
@ 2010-06-24 17:05                   ` Mike Stump
  2010-06-24 17:29                     ` Paul Koning
  2010-06-25  9:26                     ` Nathan Sidwell
  0 siblings, 2 replies; 81+ messages in thread
From: Mike Stump @ 2010-06-24 17:05 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On Jun 24, 2010, at 1:04 AM, Nathan Sidwell wrote:
> On 06/23/10 19:36, Mike Stump wrote:
>> C++ says:
> 
> C and C++ differ in their cast-to-void behaviour.  In particular, in C++
>  (void)obj;
> does not cause a read of obj, because no lvalue->rvalue decay occurs.  This is very confusing for volatiles and incompatible with established C semantics.  As such G++ will cause a read of a volatile scalar obj in these cases.

Yeah, this was one of the later changes that I groaned over when it went in, I wish the C and C++ standards people were on the same page.  If they are to differ, I would not be against just making the construct an error, to prohibit people from making any use of a semantic that isn't the same in both languages.  I know the status quo is to just conform to the C semantic, and I didn't argue or object to that; it's just an unfortunate position to be in.  However, since we went in that direction, I wish people would formulate a change for the C++ language consistent with that and get that in, say, in the name of C compatibility.

> In C++ the result of an assignment is an lvalue.  It is not in C.
> 
>> You can't just willy nilly change this:
>> 
>> int i, j, k;
>> void foo(int&j) {
>>   foo(i = k);
>> }
>> 
>> can sense if you get it right or not.  Add a volatile on i, and you discover, you can't just change this as you see fit, in particular, not in the way you all seem to want, which is just plain wrong.
> 
> I do not know what you are saying here.  Making (just) i volatile will render your code example ill-formed.

Sorry for not expounding.  I thought it would be obvious I was talking about well formed code...  First case would be something like:

volatile int i, j, k;
volatile int vi;
void foo(volatile int& j) {
  foo(i = k);
}

here, we need to bind j to the address of i.  The second case is something like:

volatile int i, j, k;
volatile int vi;
void foo(int j) {
  foo(i = k);
}

where the value passed to foo is the value read from i, and i being volatile, would mean a read of i.

>> Further, C says:
>> 
>>   An assignment expression has the value of the left operand after the assignment
>> 
>> Now, this is pretty plain, the value is the left operand.  They choose this wording as they didn't want the return value to be a modifiable lvalue.  I concede there is enough wiggle room here to confuse users and give implementors enough latitude to try and claim they are following the standard, but really, the return value is the valuer of the left operand, if it weren't, the standard would not say it was.  It could have said, the value is the value that was stored in the left operand, or the value is the right operand after conversion to the type of the left operand, or a host of other possibilities.
> 
> Are you saying that in C, both
> 
>  (void)obj;
> and
>  (void)(obj = value);
> 
> should behave the same wrt the behaviour of reads from a volatile obj?  I thought there was consensus that they should not.

Technically, I was arguing against the dropping of the re-read of vobj in the  a = vobj = c; case.  I believe doing so would cause g++ to violate the C++ language standard.

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

* RE: [gimple] assignments to volatile
  2010-06-24 17:05                   ` Mike Stump
@ 2010-06-24 17:29                     ` Paul Koning
  2010-06-25  9:26                     ` Nathan Sidwell
  1 sibling, 0 replies; 81+ messages in thread
From: Paul Koning @ 2010-06-24 17:29 UTC (permalink / raw)
  To: Mike Stump, Nathan Sidwell
  Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

> > On 06/23/10 19:36, Mike Stump wrote:
> >> C++ says:
> >
> > C and C++ differ in their cast-to-void behaviour.  In particular, in
> C++
> >  (void)obj;
> > does not cause a read of obj, because no lvalue->rvalue decay
occurs.
> This is very confusing for volatiles and incompatible with established
> C semantics.  As such G++ will cause a read of a volatile scalar obj
in
> these cases.
> 
> Yeah, this was one of the later changes that I groaned over when it
> went in, I wish the C and C++ standards people were on the same page.
> If they are to differ, I would not be against just making the
construct
> an error, to prohibit people from making any use of a semantic that
> isn't the same in both languages.  I know the status quo is to just
> conform to the C semantic, and I didn't argue or object to that; it's
> just an unfortunate position to be in.  However, since we went in that
> direction, I wish people would formulate a change for the C++ language
> consistent with that and get that in, say, in the name of C
> compatibility.

As I see it, for C++ to deviate from C in this respect is a C++ bug.  

Making such a construct an error in C++ programs is probably a bit
strong, but I would want to see it be a warning (on by default).

	paul

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

* Re: [gimple] assignments to volatile
  2010-06-24 16:00                     ` Mark Mitchell
@ 2010-06-24 19:37                       ` Mike Stump
  2010-06-25  9:37                         ` Nathan Sidwell
  2010-06-25  9:20                       ` Nathan Sidwell
  1 sibling, 1 reply; 81+ messages in thread
From: Mike Stump @ 2010-06-24 19:37 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

On Jun 24, 2010, at 7:32 AM, Mark Mitchell wrote:
> Mike Stump wrote:
> 
>>> x = y = z;
>>> 
>>> where "y" is volatile?
> 
>> C++ requires a re-read of y, the patch was going to remove the
>> re-read, I objected because the patch then makes the compiler not
>> conform to the C++ standard.
> 
> I think that you have to read rather a lot into the C++ standard to
> arrive at that conclusion.

I disagree.  It we meant to create a temporary for a = b = c, when a b and c are all class types, we would have listed 5.17 in 12.2.  Do you know of any C++ compilers that so create a temporary?  g++ certainly doesn't.  Now, compare 6.6.3.  It can create a temporary, and it does list 12.2, and is listed by 12.2.

Do you think:

	(0, a)

can create a temporary for a as well?  The standard uses similar wording there as well:

  The  type  and value of the result are the type and value of the right
  operand; the result is an lvalue if its right operand is.

I think what your missing is kinda basic, from 1.7:

  An object is created by  a  definition  (_basic.def_), by a new-expression (_expr.new_) or by the imple-
  mentation (_class.temporary_)  when  needed.

This is meant to describe when objects are created.  We don't have a definition, so basic.def doesn't apply.  We don't have a new, so expr.new doesn't apply, and class.temporary doesn't apply, so, there is in fact no object created.  If one had been created the standard would has said it.  I think your confusing the as-if rule, which says, you can create temporaries all you want, as long as you can't observe it.  This is different, we can observe it, so it can't be created.

If you want to claim an object is create, start from 1.7, and tell me which of basic.def, expr.new or class.temporary is used, and we'll work forward from there.  Now, how do I know we're dealing with an object, because of 3.10:

   An  lvalue refers to an object or function.

Now, how do I know we're dealing with an lvalue:

  the result is an lvalue

QED.  So, the standard is perfectly clear on this point, but I do admit, the wording could be improved in 5.17.

> But, I suggest that you raise the issue on the C++ reflector and report back.  I think that it would be very helpful to hear what other implementors think.

I'd rather just survey what their compilers do.  If they all agree with you, maybe indeed g++ is the odd man out.  I have a sneaky suspicion that none of them do.  When all compilers match, I don't usually waste the reflector's time on such trivial matters, though, would be good to reword the standard to say the result is the left hand side, so that people are less able to be confused by the wording.

> But, this point may be moot; I don't know if the proposed patch changes
> the behavior here or not.  Nathan, can you clarify that?

I thought his patch was clear:

+  /* should not reread obj */
+  /* { dg-final { scan-assembler "movl\[ \t\]\[^,\]+, obj_8" } } */
+  /* { dg-final { scan-assembler-not "movl\[ \t\]obj_8," } } */
+  return cond ? obj_8 = 0 : 0;

>>> int x; volatile int y; int z; x ? y = z : 0
>>> 
>>> generating a read from "y" while:
>>> 
>>> x ? y = 0 : 0
>>> 
>>> does not.
>> 
>> I wasn't arguing this case.  I believe both standards have them
>> behaving the same.
> 
> And which way is that?  Do you think that y needs to be read, or not?

In:

volatile int i, j, k;
volatile int vi;
void foo(int p) {
  k = (i ? j=0 : k);
}

j is re-read.  It is re-read regardless if j=0, or j=k is used in the source.  Now, for the simpler:

volatile int i, j, k;
volatile int vi;
void foo(int p) {
  i ? j=0 : 0;
}

neither gcc nor g++ re-reads, and I'm not arguing changing that.  Nor is anyone suggesting changing that, so I don't see the point of asking.  I'm dodging what the standard says, well, unless someone wants to propose we change how they behave currently.

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

* Re: [gimple] assignments to volatile
  2010-06-24 16:00                     ` Mark Mitchell
  2010-06-24 19:37                       ` Mike Stump
@ 2010-06-25  9:20                       ` Nathan Sidwell
  1 sibling, 0 replies; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-25  9:20 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Mike Stump, Michael Matz, Richard Guenther, GCC Patches

On 06/24/10 15:32, Mark Mitchell wrote:
> Mike Stump wrote:
>
>>> x = y = z;
>>>
>>> where "y" is volatile?
>
>> C++ requires a re-read of y, the patch was going to remove the
>> re-read, I objected because the patch then makes the compiler not
>> conform to the C++ standard.
>
> I think that you have to read rather a lot into the C++ standard to
> arrive at that conclusion.  But, I suggest that you raise the issue on
> the C++ reflector and report back.  I think that it would be very
> helpful to hear what other implementors think.
>
> But, this point may be moot; I don't know if the proposed patch changes
> the behavior here or not.  Nathan, can you clarify that?

Yes, it changes the behaviour for C++ in the same way it changes it for C. 
Specifically the assigned-to object is not reread.

For C and C++ to have different behaviour wrt volatile accesses is a mistake 
(hence, as I mentioned, previous changes to G++ to make it have the same 
behaviour as gcc).

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-24 17:05                   ` Mike Stump
  2010-06-24 17:29                     ` Paul Koning
@ 2010-06-25  9:26                     ` Nathan Sidwell
  2010-06-25 18:20                       ` Mike Stump
  1 sibling, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-25  9:26 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On 06/24/10 16:42, Mike Stump wrote:

> Sorry for not expounding.  I thought it would be obvious I was talking about well formed code...  First case would be something like:
>
> volatile int i, j, k;
> volatile int vi;
> void foo(volatile int&  j) {
>    foo(i = k);
> }
>
> here, we need to bind j to the address of i.  The second case is something like:

Correct.  The patch does not change this behaviour -- the C++ front end already 
has to explicitly break out the lvalue from the assignment to conform to the 
semantics of TREEs.  The current G++ behaviour is not to re-read the assigned-to 
value.

> volatile int i, j, k;
> volatile int vi;
> void foo(int j) {
>    foo(i = k);
> }
>
> where the value passed to foo is the value read from i, and i being volatile, would mean a read of i.

This is just the use-of-assignment value embedded in a different context.  Or do 
you consider it somewhat different from the
   non_vol = vol = expr;
case?

>>> Further, C says:
>>>
>>>    An assignment expression has the value of the left operand after the assignment
>>>
>>> Now, this is pretty plain, the value is the left operand.  They choose this wording as they didn't want the return value to be a modifiable lvalue.  I concede there is enough wiggle room here to confuse users and give implementors enough latitude to try and claim they are following the standard, but really, the return value is the valuer of the left operand, if it weren't, the standard would not say it was.  It could have said, the value is the value that was stored in the left operand, or the value is the right operand after conversion to the type of the left operand, or a host of other possibilities.
>>
>> Are you saying that in C, both
>>
>>   (void)obj;
>> and
>>   (void)(obj = value);
>>
>> should behave the same wrt the behaviour of reads from a volatile obj?  I thought there was consensus that they should not.
>
> Technically, I was arguing against the dropping of the re-read of vobj in the  a = vobj = c; case.  I believe doing so would cause g++ to violate the C++ 
language standard

You stated something about the C standard, my question was about the behaviour 
in C to clarify what you meant.  Do you have an opinion about that?

I am having a hard time following your reasoning, as it appears to switch 
between C and C++ standards.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-24 19:37                       ` Mike Stump
@ 2010-06-25  9:37                         ` Nathan Sidwell
  2010-06-25 19:06                           ` Mike Stump
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-25  9:37 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On 06/24/10 19:38, Mike Stump wrote:
> On Jun 24, 2010, at 7:32 AM, Mark Mitchell wrote:
>> Mike Stump wrote:
>>
>>>> x = y = z;
>>>>
>>>> where "y" is volatile?
>>
>>> C++ requires a re-read of y, the patch was going to remove the
>>> re-read, I objected because the patch then makes the compiler not
>>> conform to the C++ standard.
>>
>> I think that you have to read rather a lot into the C++ standard to
>> arrive at that conclusion.
>
> I disagree.  It we meant to create a temporary for a = b = c, when a b and c are all class types, we would have listed 5.17 in 12.2.  Do you know of any C++ compilers that so create a temporary?  g++ certainly doesn't.  Now, compare 6.6.3.  It can create a temporary, and it does list 12.2, and is listed by 12.2.

We were talking about scalars.  volatile structs are treated differently.  As I 
already mentioned, in G++, '(void)volatile_class_object' does not cause 
lvalue->rvalue  decay and does not cause a read of all the members of the 
object.  I think the behaviour of volatile structs in C++ is too ill-specified 
to meaningfully talk about when accesses to the members occur.

I think the goal should be to make accesses to volatile scalars, as used when 
poking at hardware, follow simple, composable, consistent rules.  IMHO the 
current implemented behaviour is none of those.

> j is re-read.  It is re-read regardless if j=0, or j=k is used in the source.  Now, for the simpler:
>
> volatile int i, j, k;
> volatile int vi;
> void foo(int p) {
>    i ? j=0 : 0;
> }
>
> neither gcc nor g++ re-reads, and I'm not arguing changing that.  Nor is anyone suggesting changing that, so I don't see the point of asking.  I'm dodging what the standard says, well, unless someone wants to propose we change how they behave currently.

But gcc does reread when assigning a non-constant value.  As I pointed out, 
GCC's behaviour is inconsistent.

nathan.

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-25  9:26                     ` Nathan Sidwell
@ 2010-06-25 18:20                       ` Mike Stump
  2010-06-28  8:49                         ` Nathan Sidwell
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Stump @ 2010-06-25 18:20 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On Jun 24, 2010, at 11:35 PM, Nathan Sidwell wrote:
> On 06/24/10 16:42, Mike Stump wrote:
> 
>> Sorry for not expounding.  I thought it would be obvious I was talking about well formed code...  First case would be something like:
>> 
>> volatile int i, j, k;
>> volatile int vi;
>> void foo(volatile int&  j) {
>>   foo(i = k);
>> }
>> 
>> here, we need to bind j to the address of i.  The second case is something like:
> 
> Correct.  The patch does not change this behaviour -- the C++ front end already has to explicitly break out the lvalue from the assignment to conform to the semantics of TREEs.  The current G++ behaviour is not to re-read the assigned-to value.

g++ seems not to share your position:

	movl	_i, %eax
	movl	%eax, (%esp)

volatile int i, j, k;
volatile int vi;
void foo(int j) {
  foo(i = k);
}

GNU C++ (GCC) version 4.6.0 20100620 (experimental) [trunk revision 161045] (x86_64-apple-darwin10)
	compiled by GNU C version 4.2.1 (Apple Inc. build 5659), GMP version 5.0.1

?  Certainly I must misunderstand something, can you spot it?


> This is just the use-of-assignment value embedded in a different context.  Or do you consider it somewhat different from the
>  non_vol = vol = expr;
> case?

I don't believe that standard distinguishes.

> 
>>>> Further, C says:
>>>> 
>>>>   An assignment expression has the value of the left operand after the assignment
>>>> 
>>>> Now, this is pretty plain, the value is the left operand.  They choose this wording as they didn't want the return value to be a modifiable lvalue.  I concede there is enough wiggle room here to confuse users and give implementors enough latitude to try and claim they are following the standard, but really, the return value is the valuer of the left operand, if it weren't, the standard would not say it was.  It could have said, the value is the value that was stored in the left operand, or the value is the right operand after conversion to the type of the left operand, or a host of other possibilities.
>>> 
>>> Are you saying that in C, both
>>> 
>>>  (void)obj;
>>> and
>>>  (void)(obj = value);
>>> 
>>> should behave the same wrt the behaviour of reads from a volatile obj?  I thought there was consensus that they should not.
>> 
>> Technically, I was arguing against the dropping of the re-read of vobj in the  a = vobj = c; case.  I believe doing so would cause g++ to violate the C++ 
> language standard
> 
> You stated something about the C standard, my question was about the behaviour in C to clarify what you meant.  Do you have an opinion about that?

The standard has an opinion I respect:

  An assignment expression has the value of the left operand

value in this context means:

       3.15
       [#1] object
       region of data storage in  the  execution  environment,  the
       contents of which can represent values                       |

and the left operand means vobj (in your snippet).

C is the same.  C++ interpreted what the C standard meant at time and tried to clarify.  There is a slight mod in this area due to C++, which is why the language is slightly different, but the intent of the C++ committee was to make them match C.

The standards have many tricky areas, many hard to read things, but when the chain of reasoning spans just 2 sections, and uses 1 or two verbs each, using simple, well defined terms, I just don't see the room to be confused.

> I am having a hard time following your reasoning, as it appears to switch between C and C++ standards.

I don't switch between them, I've expounded on both, because others brought both up.  In this case, one can be used to understand the meaning of the other, as both are intended to match (save for the very obvious lvalue result), that was the one addition the C++ people did to better match the requirements for C++.  C has no need to adopt that, but since the pulled in modifiable lvalue, they could pull in this change safely, if they wanted.  Previously, they didn't have the terminology to do it, now they do.

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

* Re: [gimple] assignments to volatile
  2010-06-25  9:37                         ` Nathan Sidwell
@ 2010-06-25 19:06                           ` Mike Stump
  2010-06-25 21:33                             ` Mark Mitchell
  2010-06-28  9:52                             ` Nathan Sidwell
  0 siblings, 2 replies; 81+ messages in thread
From: Mike Stump @ 2010-06-25 19:06 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On Jun 24, 2010, at 11:50 PM, Nathan Sidwell wrote:
> On 06/24/10 19:38, Mike Stump wrote:
>> On Jun 24, 2010, at 7:32 AM, Mark Mitchell wrote:
>>> Mike Stump wrote:
>>> 
>>>>> x = y = z;
>>>>> 
>>>>> where "y" is volatile?
>>> 
>>>> C++ requires a re-read of y, the patch was going to remove the
>>>> re-read, I objected because the patch then makes the compiler not
>>>> conform to the C++ standard.
>>> 
>>> I think that you have to read rather a lot into the C++ standard to
>>> arrive at that conclusion.
>> 
>> I disagree.  It we meant to create a temporary for a = b = c, when a b and c are all class types, we would have listed 5.17 in 12.2.  Do you know of any C++ compilers that so create a temporary?  g++ certainly doesn't.  Now, compare 6.6.3.  It can create a temporary, and it does list 12.2, and is listed by 12.2.
> 
> We were talking about scalars.

I don't find any limitation in 5.17 to scalars or to objects of class type.  If you examine the wording in 8.5.3 for example, a place that we all know does create temporaries:

    --Otherwise, a temporary of type "cv1 T1" is created and initialized
      from  the  initializer expression using the rules for a non-refer-
      ence copy initialization  (_dcl.init_).   The  reference  is  then
      bound  to  the  temporary.

we can see the usual language the standard uses to create temporaries.  It _must_ do this, so that the results of == on &lval can be defined.  We use 12.2 as a proxy to find places in the standard that create temporaries.  One can also just search the standard for the word temporary, if one wanted to.  Since 5.17 doesn't distinguish between class nor scalars, we are free to use the semantics of class types to better understand the semantics for scalars.  These semantics _must_ be the same, because there is no stated difference.  The standard is not meant to be misread.  It isn't formal enough to withstand people intentionally or otherwise, misreading it.

So, what we are talking about are the semantics of 5.17, and those are not limited to scalars.

> volatile structs are treated differently.

In a = vob = c; stucts are treated the same.  This is the case we were discussing.  We can know that, because it appears on the 6th lines of this email.

>  I think the behaviour of volatile structs in C++ is too ill-specified to meaningfully talk about when accesses to the members occur.

Again, I disagree.  We could embark upon what the standard says, but, let's just agree to not, unless someone wants to learn what it says, or someone wants to change the status quo behavior in a way that deviates from the standard.

> I think the goal should be to make accesses to volatile scalars, as used when poking at hardware, follow simple, composable, consistent rules.

Yeah, the problem with that is implicit in that, is, I want to make the compiler agree to the ruleset I just invented because I like it, and if we do that, the semantics then change day by day, by the whim of the person doing the patch today, and the each implementor gets to choose a different rule, and the users don't benefit.  The other possibility is to make it conform to the language standard, when reasonable.  I think the later is the best option.  No one has argued that they understand what the standard says and want to intentionally deviate from it, nor have they stated a good reason for doing that.

So, could you please restate what you want to do.  Do you want gcc to follow the language standard, or, would you rather ignore the standard and just invent some rules on the fly for gcc to follow?

>  IMHO the current implemented behaviour is none of those.

Concerning:

Sometimes we re-read the assigned-to object, and sometimes we do not.  For instance,
  return vobj = data;
will cause a reread of vobj, IF data is not a constant.

the proper solution is to make it always reread vobj.  Simple and consistent, while matching the standard, no?

This sort of bug happens because people forget the, this optimization isn't valid when TREE_THIS_VOLATILE is set.  The solution is to add the missing check.  We know it is the optimizer, as if you replace the constant with anything but a constant, we get the proper semantics.  That's proof positive that the bug lies no in the semantics of all other cases, but rather the semantics of the constant case.

>> j is re-read.  It is re-read regardless if j=0, or j=k is used in the source.  Now, for the simpler:
>> 
>> volatile int i, j, k;
>> volatile int vi;
>> void foo(int p) {
>>   i ? j=0 : 0;
>> }
>> 
>> neither gcc nor g++ re-reads, and I'm not arguing changing that.  Nor is anyone suggesting changing that, so I don't see the point of asking.  I'm dodging what the standard says, well, unless someone wants to propose we change how they behave currently.
> 
> But gcc does reread when assigning a non-constant value.  As I pointed out, GCC's behaviour is inconsistent.

Ah, I want hoping to avoid that case...  Oh well...  [ pause ]

g++ doesn't reread in that case.  :-)  I think that matches the language standard 5.16:

4 If  the  second and third operands are lvalues and have the same type,
  the result is of that type and is an lvalue.

and no decay, no access.  I don't see that as problematic.  gcc does access, and I think that follows the C standard.  When exploring it, we find only constants screw it up, so the bug again, is in the optimizer, and the code missing is the one that says, don't do this optimization when volatile.  When that bug is fixed, gcc (c language) is then consistent with itself.

As for the inconsistency between C and C++.  I don't feel as strongly on how to resolve this.  I might vote to leave the g++ hack out here, but if people wanted the hack to be all lvalues cast to void are converted to rvalues, I don't feel strongly enough to oppose, though, I wish people would rather hit up the C and C++ people, lock them in a room, and say you can't come out until one of you relents.  I'd also be ok with it being a hard error, as this can be refined later when the standards people agree on a consistent semantic.  Hard error (off with pedantic) or a note might  be my preferred solution.

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

* Re: [gimple] assignments to volatile
  2010-06-25 19:06                           ` Mike Stump
@ 2010-06-25 21:33                             ` Mark Mitchell
  2010-06-26  9:35                               ` Mike Stump
  2010-06-28  9:52                             ` Nathan Sidwell
  1 sibling, 1 reply; 81+ messages in thread
From: Mark Mitchell @ 2010-06-25 21:33 UTC (permalink / raw)
  To: Mike Stump; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

Mike Stump wrote:

> So, could you please restate what you want to do.  Do you want gcc to
> follow the language standard, or, would you rather ignore the
> standard and just invent some rules on the fly for gcc to follow?

There's no need to take that tone.  Nathan and I have both participated
in standards committees and in making G++ much more conformant to the
standard.  Of course we don't want to make things up on the fly.

But, you are asserting that the standard unambiguously mandates a
particular behavior.  I, at least, don't think that's clear.  I also
don't think that in this area the standard is more important than
existing practice, both in GCC and in other compilers.

Rather than all this discussion of the standard, I'd like to see a list
of the cases that are controversial, together with a table showing what
compilers do reads and which do not.

Nathan, perhaps you can put together the table?  And then we can ask
volunteers to start filling it in?

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-25 21:33                             ` Mark Mitchell
@ 2010-06-26  9:35                               ` Mike Stump
  2010-06-26 10:18                                 ` Mark Mitchell
  2010-06-26 10:20                                 ` Richard Kenner
  0 siblings, 2 replies; 81+ messages in thread
From: Mike Stump @ 2010-06-26  9:35 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

On Jun 25, 2010, at 11:44 AM, Mark Mitchell wrote:
> There's no need to take that tone.

Sorry for the tone.  I honestly don't know if people want to deviate from the standard, and if so, why, or if they just have a different idea of what it says, or why they think it says what they think.

> Of course we don't want to make things up on the fly.

Very little of the preceding has any backing from the language of the standard for the proposed behavior change, hence my confusion.

> But, you are asserting that the standard unambiguously mandates a particular behavior.

Yes,

> I, at least, don't think that's clear.

I'd like to understand how you interpret the standard.  If you could point out the support in the standard for a copy to be made, that would help me understand better.

Other compilers might differ on the re-read.  Even if they did, I'd still object to changing gcc to match them.  I'd rather talk with their implementors and figure out if they think they conform to the standard or not, and if not, why?  Could be just a simple bug in their compiler that they would fix.

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

* Re: [gimple] assignments to volatile
  2010-06-26  9:35                               ` Mike Stump
@ 2010-06-26 10:18                                 ` Mark Mitchell
  2010-06-26 12:18                                   ` Richard Guenther
  2010-06-26 10:20                                 ` Richard Kenner
  1 sibling, 1 reply; 81+ messages in thread
From: Mark Mitchell @ 2010-06-26 10:18 UTC (permalink / raw)
  To: Mike Stump; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

Mike Stump wrote:

> I'd like to understand how you interpret the standard.

I simply think it does not say.  I don't think it says make a copy.  I
don't think it says don't make a copy.  I understand how you are reading
it, but I think you're finding meaning where none is necessarily
present.  I'll be persuaded if you show me a consensus of people on the
standards reflector, but you didn't want to ask on the reflector.

If it is unspecified, I'd rather not do the read.  I don't argue the
standard mandates not doing the read, but I feel that it's better
behavior.  I think it's odd to do a read from "y" in "x = y = z", but I
think it's *very* odd to do a read from "y" in the case of "x ? y = z :
...", which is what Nathan says we presently do.

> Other compilers might differ on the re-read.  Even if they did, I'd
> still object to changing gcc to match them.  I'd rather talk with
> their implementors and figure out if they think they conform to the
> standard or not, and if not, why?  Could be just a simple bug in
> their compiler that they would fix.

I don't find that likely.  Changing this behavior will change the
meaning of existing programs in mysterious ways.  I doubt you'll find
compiler implementors eager to do that.  But, we can't know until we
test the compilers.  Maybe they all agree with you.

Backwards compatibility is also the best reason not to change GCC; even
if the standard unambiguously mandated that we change, it might not make
sense to change, since it might break code that's worked with GCC for a
long time.

But, that doesn't resolve the constant vs. non-constant question.
That's an inconsistency so weird and horrid that I think we have to
change either the constant case or the non-constant case.  If we don't
make those cases consistent, we'll find that optimization levels affect
whether a volatile location is read and that's very bad indeed.  So, I
think that GCC is going to have to change it's behavior in one or the
other of these cases.

Right now you're asserting that the standard mandates a particular
behavior, but you seem unwilling to back that up by getting a consensus
on the reflector, and you're saying that existing practice by other
compilers won't change your opinion.  That seems a pretty rigid
position.  I'd be a lot more persuaded if you helped to establish either
a consensus on the standards reflector or demonstrated a consensus of
other compilers.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-26  9:35                               ` Mike Stump
  2010-06-26 10:18                                 ` Mark Mitchell
@ 2010-06-26 10:20                                 ` Richard Kenner
  1 sibling, 0 replies; 81+ messages in thread
From: Richard Kenner @ 2010-06-26 10:20 UTC (permalink / raw)
  To: mikestump; +Cc: gcc-patches, mark, matz, nathan, richard.guenther

> I honestly don't know if people want to deviate from the standard, and if
> so, why, or if they just have a different idea of what it says, or why
> they think it says what they think.

Implementing a standard precisely is good.  Doing what users expect is
also good.  When those two conflict, we have to choose which to do.
The former is USUALLY the right choice, but not always.  It depends on
the level of ambiguity in the standard and the historical legimacy of
the expectation.

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

* Re: [gimple] assignments to volatile
  2010-06-26 10:18                                 ` Mark Mitchell
@ 2010-06-26 12:18                                   ` Richard Guenther
  2010-06-26 19:52                                     ` Michael Matz
  0 siblings, 1 reply; 81+ messages in thread
From: Richard Guenther @ 2010-06-26 12:18 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Mike Stump, Nathan Sidwell, Michael Matz, GCC Patches

On Sat, Jun 26, 2010 at 5:46 AM, Mark Mitchell <mark@codesourcery.com> wrote:
> Mike Stump wrote:
>
>> I'd like to understand how you interpret the standard.
>
> I simply think it does not say.  I don't think it says make a copy.  I
> don't think it says don't make a copy.  I understand how you are reading
> it, but I think you're finding meaning where none is necessarily
> present.  I'll be persuaded if you show me a consensus of people on the
> standards reflector, but you didn't want to ask on the reflector.
>
> If it is unspecified, I'd rather not do the read.  I don't argue the
> standard mandates not doing the read, but I feel that it's better
> behavior.  I think it's odd to do a read from "y" in "x = y = z", but I
> think it's *very* odd to do a read from "y" in the case of "x ? y = z :
> ...", which is what Nathan says we presently do.
>
>> Other compilers might differ on the re-read.  Even if they did, I'd
>> still object to changing gcc to match them.  I'd rather talk with
>> their implementors and figure out if they think they conform to the
>> standard or not, and if not, why?  Could be just a simple bug in
>> their compiler that they would fix.
>
> I don't find that likely.  Changing this behavior will change the
> meaning of existing programs in mysterious ways.  I doubt you'll find
> compiler implementors eager to do that.  But, we can't know until we
> test the compilers.  Maybe they all agree with you.
>
> Backwards compatibility is also the best reason not to change GCC; even
> if the standard unambiguously mandated that we change, it might not make
> sense to change, since it might break code that's worked with GCC for a
> long time.

What did GCC do for all these cases pre-tree-ssa?

Richard.

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

* Re: [gimple] assignments to volatile
  2010-06-26 12:18                                   ` Richard Guenther
@ 2010-06-26 19:52                                     ` Michael Matz
  2010-06-26 19:57                                       ` Mark Mitchell
  0 siblings, 1 reply; 81+ messages in thread
From: Michael Matz @ 2010-06-26 19:52 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Mark Mitchell, Mike Stump, Nathan Sidwell, GCC Patches

Hi,

On Sat, 26 Jun 2010, Richard Guenther wrote:

> > Backwards compatibility is also the best reason not to change GCC; 
> > even if the standard unambiguously mandated that we change, it might 
> > not make sense to change, since it might break code that's worked with 
> > GCC for a long time.
> 
> What did GCC do for all these cases pre-tree-ssa?

Trying 3.3, and this testcase:

-----------------------
volatile int vobj1, vobj2, vobj3, vobj4, vobj5, vobj6, vobj7, vobj8, vobj9;
int x, y, z;
void f1 (int i)
{
  vobj1 = y;
  x = vobj2 = y;
  x ? vobj3 = y : z;
  x = y ? vobj4 = z : i;
  vobj5;
  vobj6 = 42;
  x = vobj7 = 43;
  x ? vobj8 = 44 : z;
  x = y ? vobj9 = 45 : i;
}
-----------------------

I.e. testing all cases we were discussing in this thread, constant and 
non-constant RHS.  cc1 and cc1plus generate the same accesses, in addition 
optimization levels make no difference (as expected).  The relevant 
instructions are this in all cases:

% grep 'mov.*vobj' volatile-check.s
        movl    %edx, vobj1
        movl    %edx, vobj2
        movl    vobj2, %eax
        movl    %edx, vobj3
        movl    %eax, vobj4
        movl    vobj4, %eax
        movl    vobj5, %eax
        movl    %eax, vobj6
        movl    %eax, vobj7
        movl    vobj7, %eax
        movl    %ecx, vobj8
        movl    %eax, vobj9

I.e. a (re-)read occurs for vobj2, vobj4, vobj5 and vobj7, that is these 
cases:

  x = vobj2 = y;
  x = y ? vobj4 = z : i;
  vobj5;
  x = vobj7 = 43;

Interestingly a re-read doesn't occur for vobj9:
  x = y ? vobj9 = 45 : i;
that is the same case as vobj4, just with a constant RHS.  I'd consider 
this a bug.  (For completeness, the reread of vobj4 of course only happens 
conditionally)

FWIW, our current trunk in addition generates re-reads for vobj3, vobj8 
and vobj9.  If one were to follow my (and Mikes?) reading of the standard 
rereading vobj3 and vobj8 would be wrong.

All of these compilers agree that a read is to be emitted for a bare vobj 
access in void context: "vobj5;" but not for the simple assignment
"vobj1 = x;".

ICC 11.0 and 11.1 only generate a read of vobj5 (i.e. no re-reading occurs 
at all) for the C language, and no read at all for the C++ language.


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-26 19:52                                     ` Michael Matz
@ 2010-06-26 19:57                                       ` Mark Mitchell
  2010-06-26 20:08                                         ` Michael Matz
  0 siblings, 1 reply; 81+ messages in thread
From: Mark Mitchell @ 2010-06-26 19:57 UTC (permalink / raw)
  To: Michael Matz; +Cc: Richard Guenther, Mike Stump, Nathan Sidwell, GCC Patches

Michael Matz wrote:

> Trying 3.3, and this testcase:

Thanks for doing this research!

Would you be willing to make a Wiki page with this information on it?

I think if we can fill in a table showing which compilers do what, that
would be extremely helpful.  If we had each of the examples you
collected in rows, and columns showing whether each compiler reads the
volatile variable, we could see just how much consensus there is.

> ICC 11.0 and 11.1 only generate a read of vobj5 (i.e. no re-reading occurs 
> at all) for the C language, and no read at all for the C++ language.

That's interesting.  Of course, ICC is not terribly heavily used as an
embedded compiler, which is where there is the most use of volatile.
(Of course, volatile is used in multi-threaded non-embedded programs as
well, though there the exact number of reads/writes is probably less
important to many users.)

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-26 19:57                                       ` Mark Mitchell
@ 2010-06-26 20:08                                         ` Michael Matz
  2010-06-26 22:13                                           ` Mark Mitchell
  0 siblings, 1 reply; 81+ messages in thread
From: Michael Matz @ 2010-06-26 20:08 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Richard Guenther, Mike Stump, Nathan Sidwell, GCC Patches

Hi,

On Sat, 26 Jun 2010, Mark Mitchell wrote:

> Would you be willing to make a Wiki page with this information on it?

http://gcc.gnu.org/wiki/VolatileAccessComparison


Ciao,
Michael.

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

* Re: [gimple] assignments to volatile
  2010-06-26 20:08                                         ` Michael Matz
@ 2010-06-26 22:13                                           ` Mark Mitchell
  2010-06-28  9:20                                             ` Nathan Sidwell
  0 siblings, 1 reply; 81+ messages in thread
From: Mark Mitchell @ 2010-06-26 22:13 UTC (permalink / raw)
  To: Michael Matz; +Cc: Richard Guenther, Mike Stump, Nathan Sidwell, GCC Patches

Michael Matz wrote:

>> Would you be willing to make a Wiki page with this information on it?
> 
> http://gcc.gnu.org/wiki/VolatileAccessComparison

Thanks!  This is a big help.

I filled in rows for RealView 3.1 and RealView 4.0 and for Visual C++
2010.  It looks like RealView behaves like ICC, which isn't too
surprising given that they are both EDG-based compilers.  On the other
Visual C++ behaves like the current 4.6 trunk.  So, we certainly do not
have agreement across implementors as to what behavior is right.

I'd like to see what some of the other embedded compilers like Green
Hills, CodeWarrior, IAR, and Keil do.

One thing that I'm confused about is that Nathan reported inconsistency
between the constant and non-constant cases.  But, while your table
shows that for GCC 3.3, it doesn't show it for the current 4.6 trunk.
Nathan, are we missing something in the test cases relative to the
inconsistency you reported?

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-06-25 18:20                       ` Mike Stump
@ 2010-06-28  8:49                         ` Nathan Sidwell
  2010-07-01  1:02                           ` Mike Stump
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-28  8:49 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On 06/25/10 17:41, Mike Stump wrote:
> On Jun 24, 2010, at 11:35 PM, Nathan Sidwell wrote:
>> On 06/24/10 16:42, Mike Stump wrote:
>>
>>> Sorry for not expounding.  I thought it would be obvious I was talking about well formed code...  First case would be something like:
>>>
>>> volatile int i, j, k;
>>> volatile int vi;
>>> void foo(volatile int&   j) {
>>>    foo(i = k);
>>> }
>>>
>>> here, we need to bind j to the address of i.  The second case is something like:
>>
>> Correct.  The patch does not change this behaviour -- the C++ front end already has to explicitly break out the lvalue from the assignment to conform to the semantics of TREEs.  The current G++ behaviour is not to re-read the assigned-to value.
>
> g++ seems not to share your position:
>
> 	movl	_i, %eax
> 	movl	%eax, (%esp)
>
> volatile int i, j, k;
> volatile int vi;
> void foo(int j) {
>    foo(i = k);
> }
>
> GNU C++ (GCC) version 4.6.0 20100620 (experimental) [trunk revision 161045] (x86_64-apple-darwin10)
> 	compiled by GNU C version 4.2.1 (Apple Inc. build 5659), GMP version 5.0.1
>
> ?  Certainly I must misunderstand something, can you spot it?

You have changed the testcase to be passing by value from passing by reference. 
  Why do you think those would be equivalent?

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-26 22:13                                           ` Mark Mitchell
@ 2010-06-28  9:20                                             ` Nathan Sidwell
  2010-06-28  9:27                                               ` Nathan Sidwell
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-28  9:20 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Michael Matz, Richard Guenther, Mike Stump, GCC Patches

On 06/26/10 20:57, Mark Mitchell wrote:

> One thing that I'm confused about is that Nathan reported inconsistency
> between the constant and non-constant cases.  But, while your table
> shows that for GCC 3.3, it doesn't show it for the current 4.6 trunk.
> Nathan, are we missing something in the test cases relative to the
> inconsistency you reported?

hm, I have just tested mainling, and I see the same as Michael -- namely a 
reread for constant assignments.   GCC 4.4.3 is different though -- it does not 
do the reread.

I'll add another row to the wiki, with 4.4.3's behaviour.

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-28  9:20                                             ` Nathan Sidwell
@ 2010-06-28  9:27                                               ` Nathan Sidwell
  0 siblings, 0 replies; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-28  9:27 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Michael Matz, Richard Guenther, Mike Stump, GCC Patches

On 06/28/10 08:06, Nathan Sidwell wrote:
> On 06/26/10 20:57, Mark Mitchell wrote:
>
>> One thing that I'm confused about is that Nathan reported inconsistency
>> between the constant and non-constant cases. But, while your table
>> shows that for GCC 3.3, it doesn't show it for the current 4.6 trunk.
>> Nathan, are we missing something in the test cases relative to the
>> inconsistency you reported?
>
> hm, I have just tested mainling, and I see the same as Michael -- namely
> a reread for constant assignments. GCC 4.4.3 is different though -- it
> does not do the reread.

sigh, I'd got .i and .ii suffixes mixed up.  it appears GCC 4.4.3 has different 
behaviour for C and C++.  I'll be really careful filling in the table.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-25 19:06                           ` Mike Stump
  2010-06-25 21:33                             ` Mark Mitchell
@ 2010-06-28  9:52                             ` Nathan Sidwell
  2010-06-30 22:52                               ` Mike Stump
  1 sibling, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-06-28  9:52 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On 06/25/10 19:14, Mike Stump wrote:

> I don't find any limitation in 5.17 to scalars or to objects of class type.  If you examine the wording in 8.5.3 for example, a place that we all know does create temporaries:

I did not make the claim that the standard distinguished.  I am make the claim 
that we want simple, consistent and composable rules for accessing scalar device 
registers.

As you brought it up, I stated what I thought of volatile structure semantics.

> In a = vob = c; stucts are treated the same.  This is the case we were discussing.  We can know that, because it appears on the 6th lines of this email.

The case of structs is what you have brought to the mix.  The original 
discussion was about scalars.

>>   I think the behaviour of volatile structs in C++ is too ill-specified to meaningfully talk about when accesses to the members occur.
>
> Again, I disagree.  We could embark upon what the standard says, but, let's just agree to not, unless someone wants to learn what it says, or someone wants to change the status quo behavior in a way that deviates from the standard.

If you do not want to discuss what the standard says, why did you bring it up? 
This whole discussion is about discrepancies within the standards and between 
them and desired semantics.

>> I think the goal should be to make accesses to volatile scalars, as used when poking at hardware, follow simple, composable, consistent rules.
>
> Yeah, the problem with that is implicit in that, is, I want to make the compiler agree to the ruleset I just invented because I like it, and if we do that, the semantics then change day by day, by the whim of the person doing the patch today, and the each implementor gets to choose a different rule, and the users don't benefit.  The other possibility is to make it conform to the language standard, when reasonable.  I think the later is the best option.  No one has argued that they understand what the standard says and want to intentionally deviate from it, nor have they stated a good reason for doing that.

Could you rephrase that please, I cannot understand what you are claiming.

> So, could you please restate what you want to do.  Do you want gcc to follow the language standard, or, would you rather ignore the standard and just invent some rules on the fly for gcc to follow?

I claim the C and C++ standards are both not clear and at odds semantics that 
are necessary for hardware programming.

>>   IMHO the current implemented behaviour is none of those.
>
> Concerning:
>
> Sometimes we re-read the assigned-to object, and sometimes we do not.  For instance,
>    return vobj = data;
> will cause a reread of vobj, IF data is not a constant.
>
> the proper solution is to make it always reread vobj.  Simple and consistent, while matching the standard, no?

did you not read my original problem statement?  You seem to be ignoring 
associated issues that come with that interpretation, which I mentioned.  Could 
you clarify what you also claim the following expression-statements should reread?

vobj;
vobj = data;
expr, vobj = data;

They all have values.

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-06-28  9:52                             ` Nathan Sidwell
@ 2010-06-30 22:52                               ` Mike Stump
  2010-07-05  8:59                                 ` Nathan Sidwell
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Stump @ 2010-06-30 22:52 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On Jun 28, 2010, at 12:44 AM, Nathan Sidwell wrote:
> did you not read my original problem statement?

I did read it.

> You seem to be ignoring associated issues that come with that interpretation, which I mentioned.

I'm aware of them.  We'd all benefit if the C and C++ committees refined the language to make things more clear and to match each other.

> Could you clarify what you also claim the following expression-statements should reread?

Below is my take on what we should do.

> vobj;

read.

> vobj = data;

no re-read

> expr, vobj = data;

no re-read.

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

* Re: [gimple] assignments to volatile
  2010-06-28  8:49                         ` Nathan Sidwell
@ 2010-07-01  1:02                           ` Mike Stump
  2010-07-05  9:02                             ` Nathan Sidwell
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Stump @ 2010-07-01  1:02 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On Jun 27, 2010, at 11:28 PM, Nathan Sidwell wrote:
> On 06/25/10 17:41, Mike Stump wrote:
>> On Jun 24, 2010, at 11:35 PM, Nathan Sidwell wrote:
>>> On 06/24/10 16:42, Mike Stump wrote:
>>> 
>>>> Sorry for not expounding.  I thought it would be obvious I was talking about well formed code...  First case would be something like:
>>>> 
>>>> volatile int i, j, k;
>>>> volatile int vi;
>>>> void foo(volatile int&   j) {
>>>>   foo(i = k);
>>>> }
>>>> 
>>>> here, we need to bind j to the address of i.  The second case is something like:
>>> 
>>> Correct.  The patch does not change this behaviour -- the C++ front end already has to explicitly break out the lvalue from the assignment to conform to the semantics of TREEs.  The current G++ behaviour is not to re-read the assigned-to value.
>> 
>> g++ seems not to share your position:
>> 
>> 	movl	_i, %eax
>> 	movl	%eax, (%esp)
>> 
>> volatile int i, j, k;
>> volatile int vi;
>> void foo(int j) {
>>   foo(i = k);
>> }
>> 
>> GNU C++ (GCC) version 4.6.0 20100620 (experimental) [trunk revision 161045] (x86_64-apple-darwin10)
>> 	compiled by GNU C version 4.2.1 (Apple Inc. build 5659), GMP version 5.0.1
>> 
>> ?  Certainly I must misunderstand something, can you spot it?
> 
> You have changed the testcase to be passing by value from passing by reference.  Why do you think those would be equivalent?

The read happens when the the object referred to by the reference is accessed:

volatile int i, j;
int x, data, expr, k;

static inline void foo(volatile int &r) {
  int fetch = r;
}

int main() {
  foo(i=k);
}

	movl	_k, %eax
	movl	%eax, _i
	movl	_i, %eax

here, i is re-read.  Here, g++ in fact does re-read the assigned to value.

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

* Re: [gimple] assignments to volatile
  2010-06-30 22:52                               ` Mike Stump
@ 2010-07-05  8:59                                 ` Nathan Sidwell
  2010-07-09  5:27                                   ` Mike Stump
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-07-05  8:59 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On 06/30/10 21:56, Mike Stump wrote:

> Below is my take on what we should do.
>
>> vobj;
>
> read.
>
>> vobj = data;
>
> no re-read
>
>> expr, vobj = data;
>
> no re-read.

Ok, I think everyone's agreed about that.

Do you have a reference to the C standard that clarifies the difference?  Wrt 
the std, all those expression-statements have values - the first is an lvalue, 
the other 2 are rvalues.

Another example I missed is:
   expr, vobj;

I think that should read vobj.  But AFAICT 'expr, vobj = data;' and 'expr, 
vobj;' are identically rvalued according to the C std.  Is there anything in the 
std that justifies them behaving differently?

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-07-01  1:02                           ` Mike Stump
@ 2010-07-05  9:02                             ` Nathan Sidwell
  2010-07-09  5:14                               ` Mike Stump
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-07-05  9:02 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On 07/01/10 02:02, Mike Stump wrote:
> On Jun 27, 2010, at 11:28 PM, Nathan Sidwell wrote:
>> On 06/25/10 17:41, Mike Stump wrote:
>>> On Jun 24, 2010, at 11:35 PM, Nathan Sidwell wrote:
>>>> On 06/24/10 16:42, Mike Stump wrote:
>>>>
>>>>> Sorry for not expounding.  I thought it would be obvious I was talking about well formed code...  First case would be something like:
>>>>>
>>>>> volatile int i, j, k;
>>>>> volatile int vi;
>>>>> void foo(volatile int&    j) {
>>>>>    foo(i = k);
>>>>> }
>>>>>
>>>>> here, we need to bind j to the address of i.  The second case is something like:
>>>>
>>>> Correct.  The patch does not change this behaviour -- the C++ front end already has to explicitly break out the lvalue from the assignment to conform to the semantics of TREEs.  The current G++ behaviour is not to re-read the assigned-to value.
>>>
>>> g++ seems not to share your position:
>>>
>>> 	movl	_i, %eax
>>> 	movl	%eax, (%esp)
>>>
>>> volatile int i, j, k;
>>> volatile int vi;
>>> void foo(int j) {
>>>    foo(i = k);
>>> }
>>>
>>> GNU C++ (GCC) version 4.6.0 20100620 (experimental) [trunk revision 161045] (x86_64-apple-darwin10)
>>> 	compiled by GNU C version 4.2.1 (Apple Inc. build 5659), GMP version 5.0.1
>>>
>>> ?  Certainly I must misunderstand something, can you spot it?
>>
>> You have changed the testcase to be passing by value from passing by reference.  Why do you think those would be equivalent?
>
> The read happens when the the object referred to by the reference is accessed:

You're now changing the example again.  This time with a reference to volatile 
object.

>
> volatile int i, j;
> int x, data, expr, k;
>
> static inline void foo(volatile int&r) {
>    int fetch = r;
> }
>
> int main() {
>    foo(i=k);
> }
>
> 	movl	_k, %eax
> 	movl	%eax, _i
> 	movl	_i, %eax
>
> here, i is re-read.  Here, g++ in fact does re-read the assigned to value.

Yes I would expect this -- there is a sequence point between the assignment to i 
in the argument list, and the read of r in the inlined function.  I do not 
understand the point you are trying to make.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-07-05  9:02                             ` Nathan Sidwell
@ 2010-07-09  5:14                               ` Mike Stump
  2010-07-09  7:20                                 ` Nathan Sidwell
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Stump @ 2010-07-09  5:14 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On Jul 5, 2010, at 2:02 AM, Nathan Sidwell wrote:
> On 07/01/10 02:02, Mike Stump wrote:
>> On Jun 27, 2010, at 11:28 PM, Nathan Sidwell wrote:
>>> On 06/25/10 17:41, Mike Stump wrote:
>>>> On Jun 24, 2010, at 11:35 PM, Nathan Sidwell wrote:
>>>>> The current G++ behaviour is not to re-read the assigned-to value.
> 
>> Here, g++ in fact does re-read the assigned to value.
> 
> Yes I would expect this


Above you say that it doesn't re-read, then you agree with me that it does re-read...  :-)

Anyway, we're on the same page now with respect to this part of the subthread.  I suppose that if we defined re-read to be the process by which the value when used is re-fetched from memory instead of a cached value of the rhs then with that definition gcc always (barring stupid bugs under discussion) re-reads and never doesn't (or at least, if one agreed with me that the result is the value of the lhs).  For those that go with, the value is the converted value of the rhs, then we'd say that gcc never re-reads.

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

* Re: [gimple] assignments to volatile
  2010-07-05  8:59                                 ` Nathan Sidwell
@ 2010-07-09  5:27                                   ` Mike Stump
  2010-07-09  7:22                                     ` Nathan Sidwell
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Stump @ 2010-07-09  5:27 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On Jul 5, 2010, at 1:59 AM, Nathan Sidwell wrote:
> Do you have a reference to the C standard that clarifies the difference?

Sure, it would be the part where the edits are when we ask them to regularize the rules with C++ after C++ fixes what they broke.  :-)  That is why I carefully chose the phrase `what we should do' as opposed to, what the standard says...

> Wrt the std, all those expression-statements have values - the first is an lvalue, the other 2 are rvalues.

Yeah, I know.

> Another example I missed is:
>  expr, vobj;
> 
> I think that should read vobj.

:-)  gcc fetches.  I'd not oppose that.

> But AFAICT 'expr, vobj = data;' and 'expr, vobj;' are identically rvalued according to the C std.  Is there anything in the std that justifies them behaving differently?

Nope, don't think so, at least in the C standard.

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

* Re: [gimple] assignments to volatile
  2010-07-09  5:14                               ` Mike Stump
@ 2010-07-09  7:20                                 ` Nathan Sidwell
  0 siblings, 0 replies; 81+ messages in thread
From: Nathan Sidwell @ 2010-07-09  7:20 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On 07/09/10 06:14, Mike Stump wrote:
> On Jul 5, 2010, at 2:02 AM, Nathan Sidwell wrote:
>> On 07/01/10 02:02, Mike Stump wrote:
>>> On Jun 27, 2010, at 11:28 PM, Nathan Sidwell wrote:
>>>> On 06/25/10 17:41, Mike Stump wrote:
>>>>> On Jun 24, 2010, at 11:35 PM, Nathan Sidwell wrote:
>>>>>> The current G++ behaviour is not to re-read the assigned-to value.
>>
>>> Here, g++ in fact does re-read the assigned to value.
>>
>> Yes I would expect this
>
>
> Above you say that it doesn't re-read, then you agree with me that it does re-read...  :-)

As I said, the two examples are different.  Your modified example inserts a 
sequence point (but you've snipped my sentence explaining that).

> Anyway, we're on the same page now with respect to this part of the subthread.  I suppose that if we defined re-read to be the process by which the value when used is re-fetched from memory instead of a cached value of the rhs then with that definition gcc always (barring stupid bugs under discussion) re-reads and never doesn't (or at least, if one agreed with me that the result is the value of the lhs).  For those that go with, the value is the converted value of the rhs, then we'd say that gcc never re-reads.

No, we are not.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-07-09  5:27                                   ` Mike Stump
@ 2010-07-09  7:22                                     ` Nathan Sidwell
  2010-07-16  8:10                                       ` Nathan Sidwell
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-07-09  7:22 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

On 07/09/10 06:27, Mike Stump wrote:
> On Jul 5, 2010, at 1:59 AM, Nathan Sidwell wrote:
>> Do you have a reference to the C standard that clarifies the difference?
>
> Sure, it would be the part where the edits are when we ask them to regularize the rules with C++ after C++ fixes what they broke.  :-)  That is why I carefully chose the phrase `what we should do' as opposed to, what the standard says...
>
>> Wrt the std, all those expression-statements have values - the first is an lvalue, the other 2 are rvalues.
>
> Yeah, I know.
>
>> Another example I missed is:
>>   expr, vobj;
>>
>> I think that should read vobj.
>
> :-)  gcc fetches.  I'd not oppose that.
>
>> But AFAICT 'expr, vobj = data;' and 'expr, vobj;' are identically rvalued according to the C std.  Is there anything in the std that justifies them behaving differently?
>
> Nope, don't think so, at least in the C standard.

Good, so I think we're all agreed that what the C standard says is not the 
behaviour we want.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-07-09  7:22                                     ` Nathan Sidwell
@ 2010-07-16  8:10                                       ` Nathan Sidwell
  2010-07-16 15:20                                         ` Mark Mitchell
  0 siblings, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-07-16  8:10 UTC (permalink / raw)
  To: Mike Stump; +Cc: Mark Mitchell, Michael Matz, Richard Guenther, GCC Patches

This discussion appears to have gone quiet.  From the table in 
http://gcc.gnu.org/wiki/VolatileAccessComparison I think it clear that:

* GCC's current behaviour is inconsistent

* Historically GCC's behaviour has changed.  GCC 4.3's behaviour is particularly 
unfortunate WRT C and C++ consistency.

* The 2 other compilers tested (I'm lumping all the EDG-based ones together) 
implement different access patterns.  One of which appears to be the same as the 
current GCC development semantics.

* I missed another disambiguating testcase, namely '0, vobj = x;' in C the 
result of the comma operator is not an lvalue -- its result has the same 
properties as the result of the conditional operator.  That argues for them 
behaving the same -- which currently does not happen in GCC.

I think there is also consensus that what the standard literally says are not 
useful semantics.

Is there consensus on what the semantics should be?

Any suggestions as to how to move forward?

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-07-16  8:10                                       ` Nathan Sidwell
@ 2010-07-16 15:20                                         ` Mark Mitchell
  2010-07-19  8:41                                           ` Nathan Sidwell
  2010-08-13  9:56                                           ` Nathan Sidwell
  0 siblings, 2 replies; 81+ messages in thread
From: Mark Mitchell @ 2010-07-16 15:20 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mike Stump, Michael Matz, Richard Guenther, GCC Patches

Nathan Sidwell wrote:

> Is there consensus on what the semantics should be?
> 
> Any suggestions as to how to move forward?

In the abstract, I think the EDG semantics make the most sense.   I
think the VC++ semantics are plausible, but extreme.  I think the
various in-between states that GCC has adopted over the years are just
woefully inconsistent.

So, my first preference would be to adopt the EDG semantics, and my
second preference would be to adopt the VC++/trunk semantics.  My
preference for the EDG semantics is somewhat offset to some extent by
the fact that our current semantics are "more like" GCC's past behavior,
i.e., they are more backward-compatible.

One of the reasons I do not like the VC++/trunk semantics are that using
assert-like macros will change behavior.  For example:

  #define check(X, Y) (X) ? (Y) : abort()
  check (condition, vobj = 3);

I think it's quite surprising that this generates a *read* from vobj,
even though:

  vobj = 3;

does not.

I would prefer not to insert reads except where absolutely required
because (a) they may change the state of hardware in surprising ways,
and (b) they cost cycles.  In short, by requiring rereads, we're setting
GCC up to underperform competing compilers on embedded systems.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-07-16 15:20                                         ` Mark Mitchell
@ 2010-07-19  8:41                                           ` Nathan Sidwell
  2010-08-13  9:56                                           ` Nathan Sidwell
  1 sibling, 0 replies; 81+ messages in thread
From: Nathan Sidwell @ 2010-07-19  8:41 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Mike Stump, Michael Matz, Richard Guenther, GCC Patches

On 07/16/10 16:20, Mark Mitchell wrote:

> One of the reasons I do not like the VC++/trunk semantics are that using
> assert-like macros will change behavior.  For example:
>
>    #define check(X, Y) (X) ? (Y) : abort()
>    check (condition, vobj = 3);
>
> I think it's quite surprising that this generates a *read* from vobj,
> even though:

This is my composability argument.  With the reread semantics, we can't tell whether
    tmp = Frob (&volatile_thing, val);
and
    Frob (&volatile_thing, val);
have the same behaviour, unless we know that Frob is not a macro.

> I would prefer not to insert reads except where absolutely required
> because (a) they may change the state of hardware in surprising ways,
> and (b) they cost cycles.  In short, by requiring rereads, we're setting
> GCC up to underperform competing compilers on embedded systems.

I'd not thought of #b.

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-07-16 15:20                                         ` Mark Mitchell
  2010-07-19  8:41                                           ` Nathan Sidwell
@ 2010-08-13  9:56                                           ` Nathan Sidwell
  2010-08-18 15:32                                             ` Mark Mitchell
  2010-08-20 18:00                                             ` H.J. Lu
  1 sibling, 2 replies; 81+ messages in thread
From: Nathan Sidwell @ 2010-08-13  9:56 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Mike Stump, Michael Matz, Richard Guenther, GCC Patches

On 07/16/10 16:20, Mark Mitchell wrote:
> Nathan Sidwell wrote:
>
>> Is there consensus on what the semantics should be?
>>
>> Any suggestions as to how to move forward?
>
> In the abstract, I think the EDG semantics make the most sense.   I
> think the VC++ semantics are plausible, but extreme.  I think the
> various in-between states that GCC has adopted over the years are just
> woefully inconsistent.
>
> So, my first preference would be to adopt the EDG semantics, and my
> second preference would be to adopt the VC++/trunk semantics.  My
> preference for the EDG semantics is somewhat offset to some extent by
> the fact that our current semantics are "more like" GCC's past behavior,
> i.e., they are more backward-compatible.

There seems to have been no responses to your suggestion.  Can we move forward 
to reviewing the updated patch itself?

The patch is http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02145.html
and Richard indicated he'd review it once semantics were agreed.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

* Re: [gimple] assignments to volatile
  2010-08-13  9:56                                           ` Nathan Sidwell
@ 2010-08-18 15:32                                             ` Mark Mitchell
  2010-08-18 16:18                                               ` Richard Guenther
  2010-08-19 11:11                                               ` Nathan Sidwell
  2010-08-20 18:00                                             ` H.J. Lu
  1 sibling, 2 replies; 81+ messages in thread
From: Mark Mitchell @ 2010-08-18 15:32 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mike Stump, Michael Matz, Richard Guenther, GCC Patches

Nathan Sidwell wrote:

>> So, my first preference would be to adopt the EDG semantics, and my
>> second preference would be to adopt the VC++/trunk semantics.  My
>> preference for the EDG semantics is somewhat offset to some extent by
>> the fact that our current semantics are "more like" GCC's past behavior,
>> i.e., they are more backward-compatible.
> 
> There seems to have been no responses to your suggestion.  Can we move
> forward to reviewing the updated patch itself?

Your patch implements *almost* the EDG semantics.  As I understand it,
you've implemented the EDG semantics, with one exception: that in C++,
vobj5 in this table:

http://gcc.gnu.org/wiki/VolatileAccessComparison

is reread.  In that way, you're consistent between C and C++, whereas
EDG, in C++, avoids the read.

I think it's better to be consistent between C and C++.  Real users
expect to be able to move code back and forth between the languages, and
this is a very subtle difference.

> The patch is http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02145.html
> and Richard indicated he'd review it once semantics were agreed.

I think the patch is ready for review.  If Richard isn't able to review
it soon, I will do so.

I do think that we should have a section in our manual that documents
these semantics.  There are always corner cases, but I think that
something like the following is a reasonable start:

==
GCC never generates a read from a `volatile' object merely because that
object is being modified, unless the object is a bitfield.  (If the
object is a bitfield, the compiler may have to read the current value of
the bitfield, modify it, and store the new value.)

Concretely, none of the following statements result in a read of `vobj':

  int obj;
  volatile int vobj;
  vobj = 0;
  obj = vobj = 0;
  obj ? vobj = 0 : vobj = 1;
==

Would you please find a place to put that (or some modified form
thereof) in the manual?  I can review that in parallel with Richard
reviewing the core patch.

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-08-18 15:32                                             ` Mark Mitchell
@ 2010-08-18 16:18                                               ` Richard Guenther
  2010-08-18 18:04                                                 ` Mike Stump
  2010-08-19 11:11                                               ` Nathan Sidwell
  1 sibling, 1 reply; 81+ messages in thread
From: Richard Guenther @ 2010-08-18 16:18 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Nathan Sidwell, Mike Stump, Michael Matz, GCC Patches

On Wed, Aug 18, 2010 at 5:30 PM, Mark Mitchell <mark@codesourcery.com> wrote:
> Nathan Sidwell wrote:
>
>>> So, my first preference would be to adopt the EDG semantics, and my
>>> second preference would be to adopt the VC++/trunk semantics.  My
>>> preference for the EDG semantics is somewhat offset to some extent by
>>> the fact that our current semantics are "more like" GCC's past behavior,
>>> i.e., they are more backward-compatible.
>>
>> There seems to have been no responses to your suggestion.  Can we move
>> forward to reviewing the updated patch itself?
>
> Your patch implements *almost* the EDG semantics.  As I understand it,
> you've implemented the EDG semantics, with one exception: that in C++,
> vobj5 in this table:
>
> http://gcc.gnu.org/wiki/VolatileAccessComparison
>
> is reread.  In that way, you're consistent between C and C++, whereas
> EDG, in C++, avoids the read.
>
> I think it's better to be consistent between C and C++.  Real users
> expect to be able to move code back and forth between the languages, and
> this is a very subtle difference.
>
>> The patch is http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02145.html
>> and Richard indicated he'd review it once semantics were agreed.
>
> I think the patch is ready for review.  If Richard isn't able to review
> it soon, I will do so.

The patch is ok, and we indeed should document these semantics.

Thanks,
Richard.


> I do think that we should have a section in our manual that documents
> these semantics.  There are always corner cases, but I think that
> something like the following is a reasonable start:
>
> ==
> GCC never generates a read from a `volatile' object merely because that
> object is being modified, unless the object is a bitfield.  (If the
> object is a bitfield, the compiler may have to read the current value of
> the bitfield, modify it, and store the new value.)
>
> Concretely, none of the following statements result in a read of `vobj':
>
>  int obj;
>  volatile int vobj;
>  vobj = 0;
>  obj = vobj = 0;
>  obj ? vobj = 0 : vobj = 1;
> ==
>
> Would you please find a place to put that (or some modified form
> thereof) in the manual?  I can review that in parallel with Richard
> reviewing the core patch.
>
> Thanks,
>
> --
> Mark Mitchell
> CodeSourcery
> mark@codesourcery.com
> (650) 331-3385 x713
>

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

* Re: [gimple] assignments to volatile
  2010-08-18 16:18                                               ` Richard Guenther
@ 2010-08-18 18:04                                                 ` Mike Stump
  0 siblings, 0 replies; 81+ messages in thread
From: Mike Stump @ 2010-08-18 18:04 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Mark Mitchell, Nathan Sidwell, Michael Matz, gcc patches

On Aug 18, 2010, at 9:00 AM, Richard Guenther wrote:
>> I think the patch is ready for review.  If Richard isn't able to review
>> it soon, I will do so.
> 
> The patch is ok, and we indeed should document these semantics.

Yes, please let's document the chosen semantics.  Would be nice to push the semantics into other compilers (clang, Visual C++) and the C and C++ standards groups as well.  Here's to hoping that everyone can agree...

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

* Re: [gimple] assignments to volatile
  2010-08-18 15:32                                             ` Mark Mitchell
  2010-08-18 16:18                                               ` Richard Guenther
@ 2010-08-19 11:11                                               ` Nathan Sidwell
  2010-08-20  4:22                                                 ` Mark Mitchell
  1 sibling, 1 reply; 81+ messages in thread
From: Nathan Sidwell @ 2010-08-19 11:11 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Mike Stump, Michael Matz, Richard Guenther, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 632 bytes --]

Mark,
> Would you please find a place to put that (or some modified form
> thereof) in the manual?  I can review that in parallel with Richard
> reviewing the core patch.

We already had words about volatile accesses in the 'C++ Extensions' section, 
but it also mentioned C semantics there. I moved the common pieces of that to a 
new node under 'C Extensions' and expanded upon it.  I replaced the C++ 
volatiles node with a description of the C++ semantics -- confirming they're the 
same as for C and explaining why.

Is the attached ok?

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery


[-- Attachment #2: vol-sem.patch --]
[-- Type: text/x-patch, Size: 9241 bytes --]

2010-08-19  Nathan Sidwell  <nathan@codesourcery.com>

	* doc/extend.texi (Volatiles): Move from C++ to C and expand.
	(C++ Volatiles): Adjust to describe C++ semantics only.

Index: doc/extend.texi
===================================================================
--- doc/extend.texi	(revision 163365)
+++ doc/extend.texi	(working copy)
@@ -66,6 +66,7 @@
 * Type Attributes::     Specifying attributes of types.
 * Alignment::           Inquiring about the alignment of a type or variable.
 * Inline::              Defining inline functions (as fast as macros).
+* Volatiles::           What constitutes an access to a volatile object.
 * Extended Asm::        Assembler instructions with C expressions as operands.
                         (With them you can define ``built-in'' functions.)
 * Constraints::         Constraints for asm operands
@@ -5052,6 +5053,88 @@
 to be inlined.  If any uses of the function remain, they will refer to
 the single copy in the library.
 
+@node Volatiles
+@section When is a Volatile Object Accessed?
+@cindex accessing volatiles
+@cindex volatile read
+@cindex volatile write
+@cindex volatile access
+
+C has the concept of volatile objects.  These are normally accessed by
+pointers and used for accessing hardware or inter-thread
+communication.  The standard encourage compilers to refrain from
+optimizations concerning accesses to volatile objects, but leaves it
+implementation defined as to what constitutes a volatile access.  The
+minimum requirement is that at a sequence point all previous accesses
+to volatile objects have stabilized and no subsequent accesses have
+occurred.  Thus an implementation is free to reorder and combine
+volatile accesses which occur between sequence points, but cannot do
+so for accesses across a sequence point.  The use of volatiles does
+not allow you to violate the restriction on updating objects multiple
+times between two sequence points.
+
+Accesses to non-volatile objects are not ordered with respect to
+volatile accesses.  You cannot use a volatile object as a memory
+barrier to order a sequence of writes to non-volatile memory.  For
+instance:
+
+@smallexample
+int *ptr = @var{something};
+volatile int vobj;
+*ptr = @var{something};
+vobj = 1;
+@end smallexample
+
+Unless @var{*ptr} and @var{vobj} can be aliased, it is not guaranteed
+that the write to @var{*ptr} will have occurred by the time the update
+of @var{vobj} has happened.  If you need this guarantee, you must use
+a stronger memory barrier such as:
+
+@smallexample
+int *ptr = @var{something};
+volatile int vobj;
+*ptr = @var{something};
+asm volatile ("" : : : "memory");
+vobj = 1;
+@end smallexample
+
+A scalar volatile object is read, when it is accessed in a void context:
+
+@smallexample
+volatile int *src = @var{somevalue};
+*src;
+@end smallexample
+
+Such expressions are rvalues, and GCC implements this as a
+read of the volatile object being pointed to.
+
+Assignments are also expressions and have an rvalue.  However when
+assigning to a scalar volatile, the volatile object is not reread,
+regardless of whether the assignment expression's rvalue is used or
+not.  If the assignment's rvalue is used, the value is that assigned
+to the volatile object.  For instance, there is no read of @var{vobj}
+in all the following cases:
+
+@smallexample
+int obj;
+volatile int vobj;
+vobj = @var{something};
+obj = vobj = @var{something};
+obj ? vobj = @var{onething} : vobj = @var{anotherthing};
+obj = (@var{something}, vobj = @var{anotherthing});
+@end smallexample
+
+If you need to read the volatile object after an assignment has
+occurred, you must use a separate expression with an intervening
+sequence point.
+
+As bitfields are not individually addressable, volatile bitfields may
+be implicitly read when written to, or when adjacent bitfields are
+accessed.  Bitfield operations may be optimized such that adjacent
+bitfields are only partially accessed, if they straddle a storage unit
+boundary.  For these reasons it is unwise to use volatile bitfields to
+access hardware.
+
 @node Extended Asm
 @section Assembler Instructions with C Expression Operands
 @cindex extended @code{asm}
@@ -13152,7 +13235,7 @@
 Predefined Macros,cpp,The GNU C Preprocessor}).
 
 @menu
-* Volatiles::           What constitutes an access to a volatile object.
+* C++ Volatiles::       What constitutes an access to a volatile object.
 * Restricted Pointers:: C99 restricted pointers and references.
 * Vague Linkage::       Where G++ puts inlines, vtables and such.
 * C++ Interface::       You can use a single C++ header file for both
@@ -13169,50 +13252,40 @@
 * Backwards Compatibility:: Compatibilities with earlier definitions of C++.
 @end menu
 
-@node Volatiles
-@section When is a Volatile Object Accessed?
+@node C++ Volatiles
+@section When is a Volatile C++ Object Accessed?
 @cindex accessing volatiles
 @cindex volatile read
 @cindex volatile write
 @cindex volatile access
 
-Both the C and C++ standard have the concept of volatile objects.  These
-are normally accessed by pointers and used for accessing hardware.  The
-standards encourage compilers to refrain from optimizations concerning
-accesses to volatile objects.  The C standard leaves it implementation
-defined  as to what constitutes a volatile access.  The C++ standard omits
-to specify this, except to say that C++ should behave in a similar manner
-to C with respect to volatiles, where possible.  The minimum either
-standard specifies is that at a sequence point all previous accesses to
-volatile objects have stabilized and no subsequent accesses have
-occurred.  Thus an implementation is free to reorder and combine
-volatile accesses which occur between sequence points, but cannot do so
-for accesses across a sequence point.  The use of volatiles does not
-allow you to violate the restriction on updating objects multiple times
-within a sequence point.
+The C++ standard differs from the C standard in its treatment of
+volatile objects.  It fails to specify what constitutes a volatile
+access, except to say that C++ should behave in a similar manner to C
+with respect to volatiles, where possible.  However, the different
+lvalueness of expressions between C and C++ complicate the behaviour.
+G++ behaves the same as GCC for volatile access, @xref{C
+Extensions,,Volatiles}, for a description of GCC's behaviour.
 
-@xref{Qualifiers implementation, , Volatile qualifier and the C compiler}.
+The C and C++ language specifications differ when an object is
+accessed in a void context:
 
-The behavior differs slightly between C and C++ in the non-obvious cases:
-
 @smallexample
 volatile int *src = @var{somevalue};
 *src;
 @end smallexample
 
-With C, such expressions are rvalues, and GCC interprets this either as a
-read of the volatile object being pointed to or only as request to evaluate
-the side-effects.  The C++ standard specifies that such expressions do not
-undergo lvalue to rvalue conversion, and that the type of the dereferenced
-object may be incomplete.  The C++ standard does not specify explicitly
-that it is this lvalue to rvalue conversion which may be responsible for
-causing an access.  However, there is reason to believe that it is,
-because otherwise certain simple expressions become undefined.  However,
-because it would surprise most programmers, G++ treats dereferencing a
-pointer to volatile object of complete type when the value is unused as
-GCC would do for an equivalent type in C@.  When the object has incomplete
-type, G++ issues a warning; if you wish to force an error, you must
-force a conversion to rvalue with, for instance, a static cast.
+The C++ standard specifies that such expressions do not undergo lvalue
+to rvalue conversion, and that the type of the dereferenced object may
+be incomplete.  The C++ standard does not specify explicitly that it
+is lvalue to rvalue conversion which is responsible for causing an
+access.  There is reason to believe that it is, because otherwise
+certain simple expressions become undefined.  However, because it
+would surprise most programmers, G++ treats dereferencing a pointer to
+volatile object of complete type as GCC would do for an equivalent
+type in C@.  When the object has incomplete type, G++ issues a
+warning; if you wish to force an error, you must force a conversion to
+rvalue with, for instance, a static cast.
 
 When using a reference to volatile, G++ does not treat equivalent
 expressions as accesses to volatiles, but instead issues a warning that
@@ -13222,6 +13295,18 @@
 references.  Again, if you wish to force a read, cast the reference to
 an rvalue.
 
+G++ implements the same behaviour as GCC does when assigning to a
+volatile object -- there is no reread of the assigned-to object, the
+assigned rvalue is reused.  Note that in C++ assignment expressions
+are lvalues, and if used as an lvalue, the volatile object will be
+referred to.  For instance, @var{vref} will refer to @var{vobj}, as
+expected, in the following example:
+
+@smallexample
+volatile int vobj;
+volatile int &vref = vobj = @var{something};
+@end smallexample
+
 @node Restricted Pointers
 @section Restricting Pointer Aliasing
 @cindex restricted pointers

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

* Re: [gimple] assignments to volatile
  2010-08-19 11:11                                               ` Nathan Sidwell
@ 2010-08-20  4:22                                                 ` Mark Mitchell
  2010-08-20 16:59                                                   ` Mike Stump
  0 siblings, 1 reply; 81+ messages in thread
From: Mark Mitchell @ 2010-08-20  4:22 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mike Stump, Michael Matz, Richard Guenther, GCC Patches

Nathan Sidwell wrote:

> We already had words about volatile accesses in the 'C++ Extensions'
> section, but it also mentioned C semantics there. I moved the common
> pieces of that to a new node under 'C Extensions' and expanded upon it. 
> I replaced the C++ volatiles node with a description of the C++
> semantics -- confirming they're the same as for C and explaining why.
> 
> Is the attached ok?

OK, thanks.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

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

* Re: [gimple] assignments to volatile
  2010-08-20  4:22                                                 ` Mark Mitchell
@ 2010-08-20 16:59                                                   ` Mike Stump
  0 siblings, 0 replies; 81+ messages in thread
From: Mike Stump @ 2010-08-20 16:59 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Nathan Sidwell, Michael Matz, Richard Guenther, GCC Patches

On Aug 19, 2010, at 8:36 PM, Mark Mitchell wrote:
>> Is the attached ok?
> 
> OK, thanks.

Thanks Nathan...

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

* Re: [gimple] assignments to volatile
  2010-08-13  9:56                                           ` Nathan Sidwell
  2010-08-18 15:32                                             ` Mark Mitchell
@ 2010-08-20 18:00                                             ` H.J. Lu
  2010-08-20 18:33                                               ` Nathan Sidwell
  1 sibling, 1 reply; 81+ messages in thread
From: H.J. Lu @ 2010-08-20 18:00 UTC (permalink / raw)
  To: Nathan Sidwell
  Cc: Mark Mitchell, Mike Stump, Michael Matz, Richard Guenther, GCC Patches

On Fri, Aug 13, 2010 at 2:41 AM, Nathan Sidwell <nathan@codesourcery.com> wrote:
> On 07/16/10 16:20, Mark Mitchell wrote:
>>
>> Nathan Sidwell wrote:
>>
>>> Is there consensus on what the semantics should be?
>>>
>>> Any suggestions as to how to move forward?
>>
>> In the abstract, I think the EDG semantics make the most sense.   I
>> think the VC++ semantics are plausible, but extreme.  I think the
>> various in-between states that GCC has adopted over the years are just
>> woefully inconsistent.
>>
>> So, my first preference would be to adopt the EDG semantics, and my
>> second preference would be to adopt the VC++/trunk semantics.  My
>> preference for the EDG semantics is somewhat offset to some extent by
>> the fact that our current semantics are "more like" GCC's past behavior,
>> i.e., they are more backward-compatible.
>
> There seems to have been no responses to your suggestion.  Can we move
> forward to reviewing the updated patch itself?
>
> The patch is http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02145.html
> and Richard indicated he'd review it once semantics were agreed.
>

Your patch caused:

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



-- 
H.J.

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

* Re: [gimple] assignments to volatile
  2010-08-20 18:00                                             ` H.J. Lu
@ 2010-08-20 18:33                                               ` Nathan Sidwell
  0 siblings, 0 replies; 81+ messages in thread
From: Nathan Sidwell @ 2010-08-20 18:33 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Mark Mitchell, Mike Stump, Michael Matz, Richard Guenther, GCC Patches

On 08/20/10 18:32, H.J. Lu wrote:

>
> Your patch caused:
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45361

Is the behaviour of that test case changed by the gimple change?  what is the 
assembly output you are seeing -- is it merely regex tuning?

I.e. is this a regression, or is it lack of progression?

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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

end of thread, other threads:[~2010-08-20 18:11 UTC | newest]

Thread overview: 81+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-21 12:44 [gimple] assignments to volatile Nathan Sidwell
2010-06-21 13:26 ` Richard Guenther
2010-06-21 13:55   ` Michael Matz
2010-06-21 14:07     ` Richard Guenther
2010-06-21 14:09     ` Nathan Sidwell
2010-06-21 14:17       ` Michael Matz
2010-06-21 14:19         ` Richard Guenther
2010-06-21 14:53           ` Michael Matz
2010-06-21 14:17     ` IainS
2010-06-21 14:24       ` Michael Matz
2010-06-21 14:50         ` Nathan Sidwell
2010-06-21 15:24           ` Michael Matz
2010-06-22 11:36             ` Dave Korn
2010-06-23 20:16             ` Mike Stump
2010-06-24 11:51               ` Michael Matz
2010-06-21 15:24         ` Nathan Sidwell
2010-06-21 15:46           ` Michael Matz
2010-06-22 15:37     ` Mark Mitchell
2010-06-22 15:37       ` Jakub Jelinek
2010-06-22 15:57         ` Paul Koning
2010-06-22 15:47       ` Michael Matz
2010-06-22 15:58         ` Mark Mitchell
2010-06-23 11:38           ` Nathan Sidwell
2010-06-23 14:05             ` Mark Mitchell
2010-06-23 14:06               ` Michael Matz
2010-06-23 16:00                 ` Richard Guenther
2010-06-23 16:25               ` Paul Koning
2010-06-23 17:13                 ` Mark Mitchell
2010-06-23 19:16               ` Mike Stump
2010-06-24 10:22                 ` Mark Mitchell
2010-06-24 15:53                   ` Mike Stump
2010-06-24 16:00                     ` Mark Mitchell
2010-06-24 19:37                       ` Mike Stump
2010-06-25  9:37                         ` Nathan Sidwell
2010-06-25 19:06                           ` Mike Stump
2010-06-25 21:33                             ` Mark Mitchell
2010-06-26  9:35                               ` Mike Stump
2010-06-26 10:18                                 ` Mark Mitchell
2010-06-26 12:18                                   ` Richard Guenther
2010-06-26 19:52                                     ` Michael Matz
2010-06-26 19:57                                       ` Mark Mitchell
2010-06-26 20:08                                         ` Michael Matz
2010-06-26 22:13                                           ` Mark Mitchell
2010-06-28  9:20                                             ` Nathan Sidwell
2010-06-28  9:27                                               ` Nathan Sidwell
2010-06-26 10:20                                 ` Richard Kenner
2010-06-28  9:52                             ` Nathan Sidwell
2010-06-30 22:52                               ` Mike Stump
2010-07-05  8:59                                 ` Nathan Sidwell
2010-07-09  5:27                                   ` Mike Stump
2010-07-09  7:22                                     ` Nathan Sidwell
2010-07-16  8:10                                       ` Nathan Sidwell
2010-07-16 15:20                                         ` Mark Mitchell
2010-07-19  8:41                                           ` Nathan Sidwell
2010-08-13  9:56                                           ` Nathan Sidwell
2010-08-18 15:32                                             ` Mark Mitchell
2010-08-18 16:18                                               ` Richard Guenther
2010-08-18 18:04                                                 ` Mike Stump
2010-08-19 11:11                                               ` Nathan Sidwell
2010-08-20  4:22                                                 ` Mark Mitchell
2010-08-20 16:59                                                   ` Mike Stump
2010-08-20 18:00                                             ` H.J. Lu
2010-08-20 18:33                                               ` Nathan Sidwell
2010-06-25  9:20                       ` Nathan Sidwell
2010-06-24 10:23                 ` Nathan Sidwell
2010-06-24 17:05                   ` Mike Stump
2010-06-24 17:29                     ` Paul Koning
2010-06-25  9:26                     ` Nathan Sidwell
2010-06-25 18:20                       ` Mike Stump
2010-06-28  8:49                         ` Nathan Sidwell
2010-07-01  1:02                           ` Mike Stump
2010-07-05  9:02                             ` Nathan Sidwell
2010-07-09  5:14                               ` Mike Stump
2010-07-09  7:20                                 ` Nathan Sidwell
2010-06-22 15:56       ` Paul Koning
2010-06-22 12:08   ` Nathan Sidwell
2010-06-22 12:25     ` Richard Guenther
2010-06-22 13:12     ` Michael Matz
2010-06-22 13:54       ` Nathan Sidwell
2010-06-22 15:21         ` Michael Matz
2010-06-22 16:12           ` Joseph S. Myers

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).