OSDN Git Service

PR rtl-optimization/51040
authoramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Nov 2011 16:39:32 +0000 (16:39 +0000)
committeramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Nov 2011 16:39:32 +0000 (16:39 +0000)
* optabs.c (expand_atomic_fetch_op): Patchup code for NAND should be AND
followed by NOT.
* builtins.c (expand_builtin_atomic_fetch_op): Patchup code for NAND
should be AND followed by NOT.
* testsuite/gcc.dg/atomic-noinline[-aux].c: Test no-inline NAND and
patchup code.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181259 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/optabs.c
gcc/testsuite/gcc.dg/atomic-noinline-aux.c
gcc/testsuite/gcc.dg/atomic-noinline.c

index 8651536..fa7cbeb 100644 (file)
@@ -1,3 +1,13 @@
+2011-11-10  Andrew MacLeod  <amacleod@redhat.com>
+
+       PR rtl-optimization/51040
+       * optabs.c (expand_atomic_fetch_op): Patchup code for NAND should be AND
+       followed by NOT.
+       * builtins.c (expand_builtin_atomic_fetch_op): Patchup code for NAND
+       should be AND followed by NOT.
+       * testsuite/gcc.dg/atomic-noinline[-aux].c: Test no-inline NAND and
+       patchup code.
+
 2011-11-10  Jakub Jelinek  <jakub@redhat.com>
 
        * vec.h (VEC_BASE): If base is at offset 0 in the structure,
index 5162927..d949dbb 100644 (file)
@@ -5460,8 +5460,17 @@ expand_builtin_atomic_fetch_op (enum machine_mode mode, tree exp, rtx target,
 
   /* Then issue the arithmetic correction to return the right result.  */
   if (!ignore)
-    ret = expand_simple_binop (mode, code, ret, val, NULL_RTX, true,
-                              OPTAB_LIB_WIDEN);
+    {
+      if (code == NOT)
+       {
+         ret = expand_simple_binop (mode, AND, ret, val, NULL_RTX, true,
+                                    OPTAB_LIB_WIDEN);
+         ret = expand_simple_unop (mode, NOT, ret, target, true);
+       }
+      else
+       ret = expand_simple_binop (mode, code, ret, val, target, true,
+                                  OPTAB_LIB_WIDEN);
+    }
   return ret;
 }
 
index b2388ec..c87f5cd 100644 (file)
@@ -7875,8 +7875,15 @@ expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
             Fetch_before == after REVERSE_OP val.  */
          if (!after)
            code = optab.reverse_code;
-         result = expand_simple_binop (mode, code, result, val, target, true,
-                                       OPTAB_LIB_WIDEN);
+         if (code == NOT)
+           {
+             result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
+                                           true, OPTAB_LIB_WIDEN);
+             result = expand_simple_unop (mode, NOT, result, target, true);
+           }
+         else
+           result = expand_simple_binop (mode, code, result, val, target,
+                                         true, OPTAB_LIB_WIDEN);
          return result;
        }
     }
index b92fcfc..b05460e 100644 (file)
@@ -40,11 +40,24 @@ char __atomic_fetch_add_1 (char *p, char v, int i)
   *p = 1;
 }
 
-short __atomic_fetch_add_2 (short *p, short v, short i)
+short __atomic_fetch_add_2 (short *p, short v, int i)
 {
   *p = 1;
 }
 
+/* Really perform a NAND.  PR51040 showed incorrect calculation of a 
+   non-inlined fetch_nand.  */
+unsigned char 
+__atomic_fetch_nand_1 (unsigned char *p, unsigned char v, int i)
+{
+  unsigned char ret;
+
+  ret = *p;
+  *p = ~(*p & v);
+
+  return ret;
+}
+
 int __atomic_is_lock_free (int i, void *p)
 {
   return 10;
index 06a93e0..eb0866e 100644 (file)
@@ -49,6 +49,13 @@ main ()
   if (__atomic_is_lock_free (4, 0) != 10)
     abort ();
    
+  /* PR 51040 was caused by arithmetic code not patching up nand_fetch properly
+     when used an an external function.  Look for proper return value here.  */
+  ac = 0x3C;
+  bc = __atomic_nand_fetch (&ac, 0x0f, __ATOMIC_RELAXED);
+  if (bc != ac)
+    abort ();
+
   return 0;
 }