__atomic_compare_exchange has 6 parameters of which one is a boolean indicating whether its the weak or strong variation.

The external library doesn't bother with the weak condition, so it only has 5 parameters. When generating the external call for the size specific __atomic_compare_exchange_N variations, that parameter wasn't being removed. It also wasn't being caught by the tests, so I modified the existing testcases to expect certain values and to make sure they are right.

Bootstraps on x86_64-unknown-linux-gnu  with no new regressions.

Andrew
        * builtins.c (expand_builtin): Remove 4th parameter representing 
        weak/strong mode when __atomic_compare_exchange becomes a library call.

        testsuite
        * gcc.dg/atomic-generic-aux.c (__atomic_compare_exchange): Fail if 
        memory model parameters don't match expected values.
        * gcc.dg/atomic-generic.c: Pass specific memory model parameters to
        __atomic_compare_exchange.
        * gcc.dg/atomic-noinline.c: Pass specific memory model parameters to
        __atomic_compare_exchange_n.
        * gcc.dg/atomic-noinline-aux.c (__atomic_compare_exchange_2): Remove
        weak/strong parameter and fail if memory models aren't correct.



Index: builtins.c
===================================================================
*** builtins.c  (revision 181350)
--- builtins.c  (working copy)
*************** expand_builtin (tree exp, rtx target, rt
*** 6578,6589 ****
      case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
      case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
      case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
!       mode = 
!         get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1);
!       target = expand_builtin_atomic_compare_exchange (mode, exp, target);
!       if (target)
!       return target;
!       break;
  
      case BUILT_IN_ATOMIC_LOAD_1:
      case BUILT_IN_ATOMIC_LOAD_2:
--- 6578,6605 ----
      case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
      case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
      case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
!       {
!       unsigned int nargs, z;
!       VEC(tree,gc) *vec;
! 
!       mode = 
!           get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1);
!       target = expand_builtin_atomic_compare_exchange (mode, exp, target);
!       if (target)
!         return target;
! 
!       /* If this is turned into an external library call, the weak parameter
!          must be dropped to match the expected parameter list.  */
!       nargs = call_expr_nargs (exp);
!       vec = VEC_alloc (tree, gc, nargs - 1);
!       for (z = 0; z < 3; z++)
!         VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
!       /* Skip the boolean weak parameter.  */
!       for (z = 4; z < 6; z++)
!         VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
!       exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), vec);
!       break;
!       }
  
      case BUILT_IN_ATOMIC_LOAD_1:
      case BUILT_IN_ATOMIC_LOAD_2:
Index: testsuite/gcc.dg/atomic-generic-aux.c
===================================================================
*** testsuite/gcc.dg/atomic-generic-aux.c       (revision 181350)
--- testsuite/gcc.dg/atomic-generic-aux.c       (working copy)
*************** __atomic_exchange (size_t size, void *ob
*** 19,35 ****
  }
  
  
  bool
! __atomic_compare_exchange (size_t size, void *obj, void *expected, 
                           void *desired, int model1, int model2)
  {
    if (!memcmp (obj, expected, size))
      {
        memcpy (obj, desired, size);
!       return true;
      }
!   memcpy (expected, obj, size);
!   return false;
  }
  
  
--- 19,48 ----
  }
  
  
+ /* Note that the external version of this routine has the boolean weak/strong
+    parameter removed.  This is required by teh external library.  */
  bool
! __atomic_compare_exchange (size_t size, void *obj, void *expected,
                           void *desired, int model1, int model2)
  {
+   bool ret;
    if (!memcmp (obj, expected, size))
      {
        memcpy (obj, desired, size);
!       ret = true;
      }
!   else
!     {
!       memcpy (expected, obj, size);
!       ret = false;
!     }
! 
!   /* Make sure the parameters have been properly adjusted for the external
!      function call (no weak/strong parameter.  */
!   if (model1 != __ATOMIC_SEQ_CST || model2 != __ATOMIC_ACQUIRE)
!     ret = !ret;
! 
!   return ret;
  }
  
  
Index: testsuite/gcc.dg/atomic-generic.c
===================================================================
*** testsuite/gcc.dg/atomic-generic.c   (revision 181350)
--- testsuite/gcc.dg/atomic-generic.c   (working copy)
*************** main ()
*** 41,52 ****
    if (memcmp (&b, &ones, size))
      abort ();
  
!   if (!__atomic_compare_exchange (&a, &b, &zero, false, __ATOMIC_RELAXED, 
__ATOMIC_RELAXED))
      abort();
    if (memcmp (&a, &zero, size))
      abort ();
  
!   if (__atomic_compare_exchange (&a, &b, &ones, false, __ATOMIC_RELAXED, 
__ATOMIC_RELAXED))
      abort();
    if (memcmp (&b, &zero, size))
      abort ();
--- 41,52 ----
    if (memcmp (&b, &ones, size))
      abort ();
  
!   if (!__atomic_compare_exchange (&a, &b, &zero, false, __ATOMIC_SEQ_CST, 
__ATOMIC_ACQUIRE))
      abort();
    if (memcmp (&a, &zero, size))
      abort ();
  
!   if (__atomic_compare_exchange (&a, &b, &ones, false, __ATOMIC_SEQ_CST, 
__ATOMIC_ACQUIRE))
      abort();
    if (memcmp (&b, &zero, size))
      abort ();
Index: testsuite/gcc.dg/atomic-noinline.c
===================================================================
*** testsuite/gcc.dg/atomic-noinline.c  (revision 181350)
--- testsuite/gcc.dg/atomic-noinline.c  (working copy)
*************** main ()
*** 31,37 ****
    if (ac != 1)
      abort ();
  
!   __atomic_compare_exchange_n (&as, &bs, cs, 0, __ATOMIC_SEQ_CST, 
__ATOMIC_SEQ_CST);
    if (as != 1)
      abort ();
  
--- 31,37 ----
    if (ac != 1)
      abort ();
  
!   __atomic_compare_exchange_n (&as, &bs, cs, 0, __ATOMIC_SEQ_CST, 
__ATOMIC_ACQUIRE);
    if (as != 1)
      abort ();
  
Index: testsuite/gcc.dg/atomic-noinline-aux.c
===================================================================
*** testsuite/gcc.dg/atomic-noinline-aux.c      (revision 181350)
--- testsuite/gcc.dg/atomic-noinline-aux.c      (working copy)
*************** __atomic_store_1 (char *p, char v, int i
*** 30,38 ****
    *p = 1;
  }
  
! int __atomic_compare_exchange_2 (short *p, short *a, short b, int x, int y, 
int z)
  {
!   *p = 1;
  }
  
  char __atomic_fetch_add_1 (char *p, char v, int i)
--- 30,44 ----
    *p = 1;
  }
  
! int __atomic_compare_exchange_2 (short *p, short *a, short b, int y, int z)
  {
!   /* Fail if the memory models aren't correct as that will indicate the 
external
!      call has failed to remove the weak/strong parameter as required by the
!      library.  */
!   if (y != __ATOMIC_SEQ_CST || z != __ATOMIC_ACQUIRE)
!     *p = 0;
!   else
!     *p = 1;
  }
  
  char __atomic_fetch_add_1 (char *p, char v, int i)

Reply via email to