[PATCH] Fix ia64 __sync_fetch_and_{sub,xor,...}

Jakub Jelinek jakub@redhat.com
Tue Nov 29 13:24:00 GMT 2005


Hi!

As spotted on libgomp.c/atomic-10.c, ia64 has been compiling say
__sync_fetch_and_sub (&x2, 1);
or
__sync_fetch_and_xor (&x2, 1);
to exactly same assembly as
__sync_fetch_and_add (&x2, 1);
i.e.
fetchadd4.acq r15 = [r14], 1
But in the first case we want
fetchadd4.acq r15 = [r14], -1
instead and in the second case can't use fetchadd4.acq at all
(need to use cmpxchg).
Ok for trunk/4.1?

2005-11-29  Jakub Jelinek  <jakub@redhat.com>

	* config/ia64/ia64.c (ia64_expand_atomic_op): Only use
	fetchadd{4,8}.acq instruction if CODE is PLUS or MINUS, for MINUS
	negate VAL.

--- gcc/config/ia64/ia64.c.jj	2005-11-29 04:22:52.000000000 -0500
+++ gcc/config/ia64/ia64.c	2005-11-29 08:08:52.163067703 -0500
@@ -2039,8 +2039,13 @@ ia64_expand_atomic_op (enum rtx_code cod
   enum insn_code icode;
 
   /* Special case for using fetchadd.  */
-  if ((mode == SImode || mode == DImode) && fetchadd_operand (val, mode))
+  if ((mode == SImode || mode == DImode)
+      && (code == PLUS || code == MINUS)
+      && fetchadd_operand (val, mode))
     {
+      if (code == MINUS)
+	val = GEN_INT (-INTVAL (val));
+
       if (!old_dst)
         old_dst = gen_reg_rtx (mode);
 

	Jakub



More information about the Gcc-patches mailing list