[committed, MIPS] Fix PR 49696

Richard Sandiford rdsandiford@googlemail.com
Sun Oct 2 17:46:00 GMT 2011


PR 49969 showed a mismatch between the short sync expanders and their
associated insns: the former allowed zero operands but the predicates
in the latter didn't.

Tested on mips64-linux-gnu and applied.

Richard


gcc/
	PR target/49696
	* config/mips/sync.md (sync_<optab>_12): Allow zero operands.
	(sync_old_<optab>_12, sync_new_<optab>_12, sync_nand_12): Likewise.
	(sync_old_nand_12, sync_new_nand_12, test_and_set_12): Likewise.

gcc/testsuite/
	* gcc.dg/pr49696.c: New test.

Index: gcc/config/mips/sync.md
===================================================================
--- gcc/config/mips/sync.md	2011-10-02 18:40:01.000000000 +0100
+++ gcc/config/mips/sync.md	2011-10-02 18:42:25.000000000 +0100
@@ -136,7 +136,7 @@ (define_insn "sync_<optab>_12"
           [(match_operand:SI 1 "register_operand" "d")
 	   (match_operand:SI 2 "register_operand" "d")
 	   (atomic_hiqi_op:SI (match_dup 0)
-			      (match_operand:SI 3 "register_operand" "dJ"))]
+			      (match_operand:SI 3 "reg_or_0_operand" "dJ"))]
 	  UNSPEC_SYNC_OLD_OP_12))
    (clobber (match_scratch:SI 4 "=&d"))]
   "GENERATE_LL_SC"
@@ -177,7 +177,7 @@ (define_insn "sync_old_<optab>_12"
           [(match_operand:SI 2 "register_operand" "d")
 	   (match_operand:SI 3 "register_operand" "d")
 	   (atomic_hiqi_op:SI (match_dup 0)
-			      (match_operand:SI 4 "register_operand" "dJ"))]
+			      (match_operand:SI 4 "reg_or_0_operand" "dJ"))]
 	  UNSPEC_SYNC_OLD_OP_12))
    (clobber (match_scratch:SI 5 "=&d"))]
   "GENERATE_LL_SC"
@@ -218,7 +218,7 @@ (define_insn "sync_new_<optab>_12"
 	   (match_operand:SI 2 "register_operand" "d")
 	   (match_operand:SI 3 "register_operand" "d")
 	   (atomic_hiqi_op:SI (match_dup 0)
-			      (match_operand:SI 4 "register_operand" "dJ"))]
+			      (match_operand:SI 4 "reg_or_0_operand" "dJ"))]
 	  UNSPEC_SYNC_NEW_OP_12))
    (set (match_dup 1)
 	(unspec_volatile:SI
@@ -259,7 +259,7 @@ (define_insn "sync_nand_12"
           [(match_operand:SI 1 "register_operand" "d")
 	   (match_operand:SI 2 "register_operand" "d")
 	   (match_dup 0)
-	   (match_operand:SI 3 "register_operand" "dJ")]
+	   (match_operand:SI 3 "reg_or_0_operand" "dJ")]
 	  UNSPEC_SYNC_OLD_OP_12))
    (clobber (match_scratch:SI 4 "=&d"))]
   "GENERATE_LL_SC"
@@ -298,7 +298,7 @@ (define_insn "sync_old_nand_12"
 	(unspec_volatile:SI
           [(match_operand:SI 2 "register_operand" "d")
 	   (match_operand:SI 3 "register_operand" "d")
-	   (match_operand:SI 4 "register_operand" "dJ")]
+	   (match_operand:SI 4 "reg_or_0_operand" "dJ")]
 	  UNSPEC_SYNC_OLD_OP_12))
    (clobber (match_scratch:SI 5 "=&d"))]
   "GENERATE_LL_SC"
@@ -337,7 +337,7 @@ (define_insn "sync_new_nand_12"
           [(match_operand:SI 1 "memory_operand" "+R")
 	   (match_operand:SI 2 "register_operand" "d")
 	   (match_operand:SI 3 "register_operand" "d")
-	   (match_operand:SI 4 "register_operand" "dJ")]
+	   (match_operand:SI 4 "reg_or_0_operand" "dJ")]
 	  UNSPEC_SYNC_NEW_OP_12))
    (set (match_dup 1)
 	(unspec_volatile:SI
@@ -546,7 +546,7 @@ (define_insn "test_and_set_12"
    (set (match_dup 1)
 	(unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d")
 			     (match_operand:SI 3 "register_operand" "d")
-			     (match_operand:SI 4 "arith_operand" "dJ")]
+			     (match_operand:SI 4 "reg_or_0_operand" "dJ")]
 	  UNSPEC_SYNC_EXCHANGE_12))]
   "GENERATE_LL_SC"
   { return mips_output_sync_loop (insn, operands); }
Index: gcc/testsuite/gcc.dg/pr49696.c
===================================================================
--- /dev/null	2011-10-02 10:31:49.966695399 +0100
+++ gcc/testsuite/gcc.dg/pr49696.c	2011-10-02 18:42:25.000000000 +0100
@@ -0,0 +1,29 @@
+/* { dg-require-effective-target sync_char_short } */
+
+/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "" { target *-*-* } 0 } */
+
+void
+foo (short *x)
+{
+  __sync_val_compare_and_swap (x, 1, 0);
+  __sync_bool_compare_and_swap (x, 1, 0);
+  __sync_lock_test_and_set (x, 0);
+
+  __sync_fetch_and_add (x, 0);
+  __sync_fetch_and_add (x, 0);
+  __sync_fetch_and_add (x, 0);
+  __sync_fetch_and_sub (x, 0);
+  __sync_fetch_and_and (x, 0);
+  __sync_fetch_and_or (x, 0);
+  __sync_fetch_and_xor (x, 0);
+  __sync_fetch_and_nand (x, 0);
+
+  __sync_add_and_fetch (x, 0);
+  __sync_add_and_fetch (x, 0);
+  __sync_add_and_fetch (x, 0);
+  __sync_sub_and_fetch (x, 0);
+  __sync_and_and_fetch (x, 0);
+  __sync_or_and_fetch (x, 0);
+  __sync_xor_and_fetch (x, 0);
+  __sync_nand_and_fetch (x, 0);
+}



More information about the Gcc-patches mailing list