On 01/13/2015 05:37 PM, Joseph Myers wrote:
On Tue, 13 Jan 2015, Andrew MacLeod wrote:
It seems that it should be safe to move back to the original patch, and remove
that error test for using consume on an exchange...
I don't think there should be any such errors, for any of the atomic
built-in functions, only warnings (with the model converted to
MEMMODEL_SEQ_CST if not valid, just like a non-constant model). This is
just like any other invalid function argument of a suitable type:
undefined behavior only if the call is executed.
http://www.open-std.org/jtc1/sc22/wg14/12553
Can't see what is in the link, but we've discussed this before.
- There is a warning for invalid memory models already, so I just
continued using that.
- I remove the check for CONSUME in exchange since the current standard
makes no mention of that being illegal.
- I also reversed the current check in compare_exchange to check for
failure > success first, allowing us to still catch both errors if present.
I think this brings us to where we ought to be... at least almost :-)
The latest version I have is n3337, which still specifies that
atomic_clear can't be memory_order_acquire or memory_order_acq_rel. Has
that been updated to specify that memory_order_consume is not allowed
either? I think there was a request in at some point... I can add
that if so.
Bootstraps on x86_64-unknown-linux-gnu, and no regressions in the testsuite.
OK for trunk?
Andrew
2015-01-14 Andrew MacLeod <amacl...@redhat.com>
* builtins.c (expand_builtin_atomic_exchange): Remove error when
memory model is CONSUME.
(expand_builtin_atomic_compare_exchange, expand_builtin_atomic_load,
expand_builtin_atomic_store, expand_builtin_atomic_clear): Change
invalid memory model errors to warnings.
* testsuite/gcc.dg/atomic-invalid.c: Check for invalid memory model
warnings instead of errors.
Index: builtins.c
===================================================================
*** builtins.c (revision 219601)
--- builtins.c (working copy)
*************** expand_builtin_atomic_exchange (machine_
*** 5385,5395 ****
enum memmodel model;
model = get_memmodel (CALL_EXPR_ARG (exp, 2));
- if ((model & MEMMODEL_MASK) == MEMMODEL_CONSUME)
- {
- error ("invalid memory model for %<__atomic_exchange%>");
- return NULL_RTX;
- }
if (!flag_inline_atomics)
return NULL_RTX;
--- 5385,5390 ----
*************** expand_builtin_atomic_compare_exchange (
*** 5422,5441 ****
success = get_memmodel (CALL_EXPR_ARG (exp, 4));
failure = get_memmodel (CALL_EXPR_ARG (exp, 5));
if ((failure & MEMMODEL_MASK) == MEMMODEL_RELEASE
|| (failure & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
{
! error ("invalid failure memory model for %<__atomic_compare_exchange%>");
! return NULL_RTX;
}
! if (failure > success)
! {
! error ("failure memory model cannot be stronger than success "
! "memory model for %<__atomic_compare_exchange%>");
! return NULL_RTX;
! }
!
if (!flag_inline_atomics)
return NULL_RTX;
--- 5417,5441 ----
success = get_memmodel (CALL_EXPR_ARG (exp, 4));
failure = get_memmodel (CALL_EXPR_ARG (exp, 5));
+ if (failure > success)
+ {
+ warning (OPT_Winvalid_memory_model,
+ "failure memory model cannot be stronger than success memory "
+ "model for %<__atomic_compare_exchange%>");
+ success = MEMMODEL_SEQ_CST;
+ }
+
if ((failure & MEMMODEL_MASK) == MEMMODEL_RELEASE
|| (failure & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
{
! warning (OPT_Winvalid_memory_model,
! "invalid failure memory model for "
! "%<__atomic_compare_exchange%>");
! failure = MEMMODEL_SEQ_CST;
! success = MEMMODEL_SEQ_CST;
}
!
if (!flag_inline_atomics)
return NULL_RTX;
*************** expand_builtin_atomic_load (machine_mode
*** 5491,5498 ****
if ((model & MEMMODEL_MASK) == MEMMODEL_RELEASE
|| (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
{
! error ("invalid memory model for %<__atomic_load%>");
! return NULL_RTX;
}
if (!flag_inline_atomics)
--- 5491,5499 ----
if ((model & MEMMODEL_MASK) == MEMMODEL_RELEASE
|| (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
{
! warning (OPT_Winvalid_memory_model,
! "invalid memory model for %<__atomic_load%>");
! model = MEMMODEL_SEQ_CST;
}
if (!flag_inline_atomics)
*************** expand_builtin_atomic_store (machine_mod
*** 5521,5528 ****
&& (model & MEMMODEL_MASK) != MEMMODEL_SEQ_CST
&& (model & MEMMODEL_MASK) != MEMMODEL_RELEASE)
{
! error ("invalid memory model for %<__atomic_store%>");
! return NULL_RTX;
}
if (!flag_inline_atomics)
--- 5522,5530 ----
&& (model & MEMMODEL_MASK) != MEMMODEL_SEQ_CST
&& (model & MEMMODEL_MASK) != MEMMODEL_RELEASE)
{
! warning (OPT_Winvalid_memory_model,
! "invalid memory model for %<__atomic_store%>");
! model = MEMMODEL_SEQ_CST;
}
if (!flag_inline_atomics)
*************** expand_builtin_atomic_clear (tree exp)
*** 5628,5635 ****
if ((model & MEMMODEL_MASK) == MEMMODEL_ACQUIRE
|| (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
{
! error ("invalid memory model for %<__atomic_store%>");
! return const0_rtx;
}
if (HAVE_atomic_clear)
--- 5630,5638 ----
if ((model & MEMMODEL_MASK) == MEMMODEL_ACQUIRE
|| (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
{
! warning (OPT_Winvalid_memory_model,
! "invalid memory model for %<__atomic_store%>");
! model = MEMMODEL_SEQ_CST;
}
if (HAVE_atomic_clear)
Index: testsuite/gcc.dg/atomic-invalid.c
===================================================================
*** testsuite/gcc.dg/atomic-invalid.c (revision 219601)
--- testsuite/gcc.dg/atomic-invalid.c (working copy)
*************** bool x;
*** 13,35 ****
int
main ()
{
! __atomic_compare_exchange_n (&i, &e, 1, 0, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST); /* { dg-error "failure memory model cannot be stronger" } */
! __atomic_compare_exchange_n (&i, &e, 1, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELEASE); /* { dg-error "invalid failure memory" } */
! __atomic_compare_exchange_n (&i, &e, 1, 1, __ATOMIC_SEQ_CST, __ATOMIC_ACQ_REL); /* { dg-error "invalid failure memory" } */
!
! __atomic_load_n (&i, __ATOMIC_RELEASE); /* { dg-error "invalid memory model" } */
! __atomic_load_n (&i, __ATOMIC_ACQ_REL); /* { dg-error "invalid memory model" } */
!
! __atomic_store_n (&i, 1, __ATOMIC_ACQUIRE); /* { dg-error "invalid memory model" } */
! __atomic_store_n (&i, 1, __ATOMIC_CONSUME); /* { dg-error "invalid memory model" } */
! __atomic_store_n (&i, 1, __ATOMIC_ACQ_REL); /* { dg-error "invalid memory model" } */
i = __atomic_always_lock_free (s, NULL); /* { dg-error "non-constant argument" } */
__atomic_load_n (&i, 44); /* { dg-warning "invalid memory model" } */
! __atomic_clear (&x, __ATOMIC_ACQUIRE); /* { dg-error "invalid memory model" } */
! __atomic_clear (&x, __ATOMIC_ACQ_REL); /* { dg-error "invalid memory model" } */
}
--- 13,35 ----
int
main ()
{
! __atomic_compare_exchange_n (&i, &e, 1, 0, __ATOMIC_RELAXED, __ATOMIC_SEQ_CST); /* { dg-warning "failure memory model cannot be stronger" } */
! __atomic_compare_exchange_n (&i, &e, 1, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELEASE); /* { dg-warning "invalid failure memory" } */
! __atomic_compare_exchange_n (&i, &e, 1, 1, __ATOMIC_SEQ_CST, __ATOMIC_ACQ_REL); /* { dg-warning "invalid failure memory" } */
!
! __atomic_load_n (&i, __ATOMIC_RELEASE); /* { dg-warning "invalid memory model" } */
! __atomic_load_n (&i, __ATOMIC_ACQ_REL); /* { dg-warning "invalid memory model" } */
!
! __atomic_store_n (&i, 1, __ATOMIC_ACQUIRE); /* { dg-warning "invalid memory model" } */
! __atomic_store_n (&i, 1, __ATOMIC_CONSUME); /* { dg-warning "invalid memory model" } */
! __atomic_store_n (&i, 1, __ATOMIC_ACQ_REL); /* { dg-warning "invalid memory model" } */
i = __atomic_always_lock_free (s, NULL); /* { dg-error "non-constant argument" } */
__atomic_load_n (&i, 44); /* { dg-warning "invalid memory model" } */
! __atomic_clear (&x, __ATOMIC_ACQUIRE); /* { dg-warning "invalid memory model" } */
! __atomic_clear (&x, __ATOMIC_ACQ_REL); /* { dg-warning "invalid memory model" } */
}